/// <summary> /// Method called from button. Gets predicted data. /// </summary> public async Task <Tuple <double[][], double[][], double, double, double> > GetPredictedPlot(BaseModel configModel) { UpdateFields(configModel); double[][] correctPoints = FunctionSolver.Solve(_functionX, _functionY, _first, _last, _points); double[][] predictedPoints = await ComputePredictedPoints(correctPoints); return(new Tuple <double[][], double[][], double, double, double>(correctPoints, predictedPoints, _error, _errorX, _errorY)); }
/// <summary> /// Method called from button. Starts learning network. /// </summary> public async void StartLearning(BaseModel configModel) { UpdateFields(configModel); double[][] correctPoints = FunctionSolver.Solve(_functionX, _functionY, _first, _last, _points); await Learn(correctPoints); }
/// <summary> /// Predicts trajectory basing on how well the network was trained. /// </summary> private async Task <double[][]> ComputePredictedPoints(double[][] correctPoints) { return(await Task.Run(() => { lock (_threadLocker) { try { _network = (ActivationNetwork)Network.Load(ConfigurationPath()); } catch (Exception ex) { throw ex; } var teacher = new BackPropagationLearning(_network) { LearningRate = _learningRate, Momentum = _momentum }; Scaler scaler = new Scaler(correctPoints); var correctScaledPoints = correctPoints.Select(a => a.ToArray()).ToArray(); scaler.Scale(ref correctScaledPoints); var resultTrainingData = ComputeTrainingData(correctScaledPoints); var inputTrainingData = resultTrainingData.Item1.Select(a => a.ToArray()).ToArray(); var outputTrainingData = resultTrainingData.Item2.Select(a => a.ToArray()).ToArray(); RandomizeOrder(ref inputTrainingData, ref outputTrainingData); try { _error = teacher.RunEpoch(inputTrainingData, outputTrainingData) / outputTrainingData.GetLength(0); } catch { RandomizeOrder(ref inputTrainingData, ref outputTrainingData); _error = teacher.RunEpoch(inputTrainingData, outputTrainingData) / outputTrainingData.GetLength(0); } var first = _last; var last = _last + _points; var inputResultData = FunctionSolver.Solve(_functionX, _functionY, first, last, _points); var pointFromInputData = correctPoints .Where((x, i) => (i > correctPoints.GetLength(0) - _inputPoints - 2) && i != correctPoints.GetLength(0) - 1) .Select(x => x.ToArray()).ToArray(); var resultData = pointFromInputData.Concat(inputResultData).ToArray(); Scaler resultScaler = new Scaler(resultData); var solution = resultData.Select(a => a.ToArray()).ToArray <double[]>(); resultScaler.Scale(ref solution); _errorX = 0; _errorY = 0; for (int j = _inputPoints; j < solution.GetLength(0); j++) { double[] networkInput = new double[2 * _inputPoints]; for (int k = _inputPoints, l = 0; k > 0; k--, l = l + 2) { networkInput[l] = solution[j - k][0]; networkInput[l + 1] = solution[j - k][1]; } try { var result = _network.Compute(networkInput); solution[j][0] = result[0]; solution[j][1] = result[1]; } catch { solution[j][0] = double.NaN; solution[j][1] = double.NaN; } } for (int i = 0; i < solution.GetLength(0); i++) { if (double.IsNaN(solution[i][0])) { continue; } solution[i][0] = resultScaler.Rescale(solution[i][0], XYEnum.X); solution[i][1] = resultScaler.Rescale(solution[i][1], XYEnum.Y); _errorX += Math.Pow(resultScaler.Rescale(solution[i][0], XYEnum.X) - resultData[i][0], 2); _errorY += Math.Pow(resultScaler.Rescale(solution[i][1], XYEnum.Y) - resultData[i][1], 2); } _errorX = Math.Sqrt(_errorX / (solution.GetLength(0) - _inputPoints)); _errorY = Math.Sqrt(_errorY / (solution.GetLength(0) - _inputPoints)); _network.Save(ConfigurationPath()); _network = null; solution = solution.Where((el, i) => i >= _inputPoints).ToArray(); return solution; } })); }