/// <summary> /// Construct the LMA object. /// </summary> /// <param name="network">The network to train. Must have a single output neuron.</param> /// <param name="training">The training data to use. Must be indexable.</param> /// <param name="h">The Hessian calculator to use.</param> public LevenbergMarquardtTraining(BasicNetwork network, IMLDataSet training, IComputeHessian h) : base(TrainingImplementationType.Iterative) { ValidateNetwork.ValidateMethodToData(network, training); Training = training; _indexableTraining = Training; this._network = network; _trainingLength = (int)_indexableTraining.Count; _weightCount = this._network.Structure.CalculateSize(); _lambda = 0.1; _deltas = new double[_weightCount]; _diagonal = new double[_weightCount]; var input = new BasicMLData( _indexableTraining.InputSize); var ideal = new BasicMLData( _indexableTraining.IdealSize); _pair = new BasicMLDataPair(input, ideal); _hessian = h; _hessian.Init(network, training); }
/// <inheritdoc /> public override void Iteration() { if (!_initComplete) { _hessian.Init(_network, Training); _initComplete = true; } PreIteration(); _hessian.Clear(); _weights = NetworkCODEC.NetworkToArray(_network); _hessian.Compute(); double currentError = _hessian.SSE; SaveDiagonal(); double startingError = currentError; bool done = false; bool singular; while (!done) { ApplyLambda(); var decomposition = new LUDecomposition(_hessian.HessianMatrix); singular = decomposition.IsNonsingular; if (singular) { _deltas = decomposition.Solve(_hessian.Gradients); UpdateWeights(); currentError = CalculateError(); } if (!singular || currentError >= startingError) { _lambda *= ScaleLambda; if (_lambda > LambdaMax) { _lambda = LambdaMax; done = true; } } else { _lambda /= ScaleLambda; done = true; } } Error = currentError; PostIteration(); }
/// <summary> /// Construct the LMA object. /// </summary> /// <param name="network">The network to train. Must have a single output neuron.</param> /// <param name="training">The training data to use. Must be indexable.</param> /// <param name="h">The Hessian calculator to use.</param> public LevenbergMarquardtTraining(BasicNetwork network, IMLDataSet training, IComputeHessian h) : base(TrainingImplementationType.Iterative) { ValidateNetwork.ValidateMethodToData(network, training); Training = training; _indexableTraining = Training; this._network = network; _trainingLength = (int) _indexableTraining.Count; _weightCount = this._network.Structure.CalculateSize(); _lambda = 0.1; _deltas = new double[_weightCount]; _diagonal = new double[_weightCount]; var input = new BasicMLData( _indexableTraining.InputSize); var ideal = new BasicMLData( _indexableTraining.IdealSize); _hessian = h; _hessian.Init(network, training); }