public static double Pass(double learningRate, INetwork network, List <DataSequence> sequences, bool applyTraining, ILoss lossTraining, ILoss lossReporting) { double numerLoss = 0; double denomLoss = 0; RnnConfig rnnConfig = (RnnConfig)Serializer.Deserialize(NetworkBuilder.Config.RnnConfigFile); foreach (DataSequence seq in sequences) { network.ResetState(); Graph g = new Graph(applyTraining); network.GenerateDropout(applyTraining); for (int i = 0; i < seq.Steps.Count; ++i) { DataStep step = seq.Steps[i]; // Generate in dropout bool[] dropped = new bool[step.Input.W.Length]; for (int col = 0; col < dropped.Length; ++col) { dropped[col] = Math.Abs(rnnConfig.GetTransformed(0, i, col, step.Input.W[col])) < 0.0000001; } Matrix output = network.Activate(step.Input, g, dropped); if (step.TargetOutput != null) { double loss = lossReporting.Measure(output, step.TargetOutput); if (Double.IsNaN(loss) || Double.IsInfinity(loss)) { return(loss); } numerLoss += loss; denomLoss++; if (applyTraining) { lossTraining.Backward(output, step.TargetOutput); } } if (i % 10 == 0 && applyTraining) { g.Backward(); //backprop dw values UpdateModelParams(network, learningRate); //update params g = new Graph(applyTraining); network.GenerateDropout(applyTraining); } } } return(numerLoss / denomLoss); }
/// <summary> /// Один проход для минипакетного обучения /// </summary> /// <param name="learningRate">Скорость обучения</param> /// <param name="network">Нейросеть</param> /// <param name="sequences">Датасет</param> /// <param name="isTraining">Производится ли обучение</param> /// <param name="lossFunction">Функция ошибки</param> /// <returns></returns> public double PassBatch(double learningRate, INetwork network, List <DataSequence> sequences, bool isTraining, ILoss lossFunction) { double numerLoss = 0; double denomLoss = 0; int index, passes = (sequences.Count % BatchSize == 0) ? sequences.Count / BatchSize : sequences.Count / BatchSize + 1; for (int j = 0; j < passes; j++) { GraphCPU g = new GraphCPU(isTraining); for (int i = 0; i < BatchSize; i++) { index = random.Next(sequences.Count); var seq = sequences[index]; network.ResetState(); foreach (DataStep step in seq.Steps) { NNValue output = network.Activate(step.Input, g); if (step.TargetOutput != null) { double loss = lossFunction.Measure(output, step.TargetOutput); if (Double.IsNaN(loss) || Double.IsInfinity(loss)) { return(loss); } numerLoss += loss; denomLoss++; if (isTraining) { lossFunction.Backward(output, step.TargetOutput); } } } } if (isTraining) { g.Backward(); //backprop dw values UpdateModelParams(network, learningRate); //update params } } return(numerLoss / denomLoss); }
/// <summary> /// Онлайн обучение /// </summary> /// <param name="learningRate"></param> /// <param name="network"></param> /// <param name="sequences"></param> /// <param name="applyTraining"></param> /// <param name="lossTraining"></param> /// <returns></returns> public double Pass(double learningRate, INetwork network, List <DataSequence> sequences, bool applyTraining, ILoss lossTraining) { double numerLoss = 0; double denomLoss = 0; foreach (DataSequence seq in sequences) { GraphCPU g = new GraphCPU(applyTraining); network.ResetState(); foreach (DataStep step in seq.Steps) { NNValue output = network.Activate(step.Input, g); if (step.TargetOutput != null) { double loss = lossTraining.Measure(output, step.TargetOutput); if (Double.IsNaN(loss) || Double.IsInfinity(loss)) { return(loss); } numerLoss += loss; denomLoss++; if (applyTraining) { lossTraining.Backward(output, step.TargetOutput); } } } if (applyTraining) { g.Backward(); //backprop dw values UpdateModelParams(network, learningRate); //update params } } return(numerLoss / denomLoss); }