/// <summary> /// Checks data /// </summary> /// <param name="inp">Input - input patterns</param> /// <param name="dout">Output</param> /// <param name="topo">Topology</param> /// <param name="iw">Index</param> /// <returns>NetworkInfo</returns> private NetworkInfo checkInputs(ref Input inp, ref Output dout, ref Topography topo, out Index iw) { if (topo.Length == 0) throw new NeuralNetworkError(Properties.Settings.Default.FE4); if (!topo.IsCorrect) throw new NeuralNetworkError(Properties.Settings.Default.FE3); if (inp.Rows != dout.Rows) throw new NeuralNetworkError(Properties.Settings.Default.FE2); NetworkInfo info = new NetworkInfo(); iw = Index.Find(ref topo); info.np = inp.Rows; info.ni = inp.Cols; info.no = dout.Cols; info.nw = topo.Length; info.nn = iw.Length - 1; return info; }
/// <summary> /// Train neural netowrk /// </summary> /// <param name="setting">NeuralNetworkSettings</param> /// <param name="info">NetworkInfo</param> /// <param name="inp">Input</param> /// <param name="dout">Output</param> /// <param name="topo">Topography</param> /// <param name="initialWeights">Weights</param> /// <param name="act">Activation</param> /// <param name="gain">Gain</param> /// <param name="iw">Index</param> public TrainResult Train(ref NeuralNetworkSettings setting, ref NetworkInfo info, ref Input inp, ref Output dout, ref Topography topo, Weights initialWeights, ref Activation act, ref Gain gain, ref Index iw) { TrainResult result = new TrainResult(); result.weights = new Weights(initialWeights.Length); result.iterations = 0; result.sse = 0; try { if (OnDebug != null) { debug(setting.ToString()); debug(act.ToString()); debug(gain.ToString()); } result.weights = initialWeights.Backup(); error.CalculateError(ref info, ref inp, ref dout, ref topo, result.weights, ref act, ref gain, ref iw); if (OnDebug != null) { debug("\r\nFirst error value: " + error.Error.ToString() + "\r\n"); } SSE.Clear(); RMSE.Clear(); SSE[0] = result.sse = error.Error; hessians.Clear(); var hessian = new Hessian(ref info); Input ii = inp.Copy().ToInput(); Output oo = dout.Copy().ToOutput(); for (result.iterations = 1; result.iterations < setting.MaxIterations; result.iterations++) { hessian.Compute(ref info, ref inp, ref dout, ref topo, result.weights, ref act, ref gain, ref iw); if (OnDebug != null) debug(hessian.ToString()); hessians.Add(hessian.HessianMat); Weights ww_backup = result.weights.Backup(); for (int jw = 0; jw < 30; jw++) { var diff = (hessian.HessianMat + (I * setting.MU)).SolveEquatation(hessian.GradientMat).Transposed; if (OnDebug != null) { debug("\r\nOdejmuję"); debug(diff.MatrixToString()); } result.weights = ww_backup - diff.ToWeights(); result.weights.Name = "Weights nr " + jw.ToString(); if (OnDebug != null) { bool areSame = result.weights.IsEqual(ww_backup); debug("\r\nWeights are same as previously backed up"); debug(result.weights.ToString()); } SSE[result.iterations] = result.sse = error.CalculateError(ref info, ref inp, ref dout, ref topo, result.weights, ref act, ref gain, ref iw); if (OnDebug != null) debug("\r\nSSE[" + result.iterations.ToString() + "] = " + error.Error.ToString()); if (SSE.CurrentSSE() <= SSE.PreviousSSE(result.iterations)) { if (setting.MU > setting.MUL) { setting.MU /= setting.Scale; } break; } if (setting.MU < setting.MUH) { setting.MU *= setting.Scale; } } double rmse = Math.Sqrt((SSE.CurrentSSE()) / inp.Rows); RMSE[result.iterations] = rmse; updateChart(result.iterations, rmse); if ((double)SSE[result.iterations] < setting.MaxError) { break; } if (OnDebug != null) debug("Błąd: " + rmse.ToString()); if ( (SSE.PreviousSSE(result.iterations) - ((double)SSE[result.iterations])) / SSE.PreviousSSE(result.iterations) < NetworkError.DesiredError//0.000000000000001 ) { break; } } } catch (Exception ex) { throw new NeuralNetworkError("Błąd uczenia sieci. " + ex.Message, ex); } return result; }