public override void Learning(double[] args, double[] expectedRes) { if ((args.Length != NeuronsNetwork[0].Length) || expectedRes.Length != NeuronsNetwork[NeuronsNetwork.Length - 1].Length) { throw new ArgumentException("Количество входных данных не соответсвует размеру (выходного слоя + ожидаемых результатов)"); } GetResult(args); if (WriteLog) { Outputter.Log("Обучение..."); } Task.Run(() => { Parallel.ForEach(NeuronsNetwork[NeuronsNetwork.Length - 1], outputNeuron => { outputNeuron.RecieveErrorSigmoid(null, LearningNorm, InertialTerm, expectedRes[(outputNeuron as OutputNeuron).NeuronId]); } ); } ).Wait(); if (WriteLog) { Outputter.Log("Обучение завершено."); } }
public virtual void RecieveErrorSigmoid(Neuron errorNeuron, double learningNorm, double inertialTerm, double?expectedValue = null) { Interlocked.Exchange(ref ErrorSummary, ErrorSummary + errorNeuron.ErrorSummary); Interlocked.Decrement(ref ErrorsLeft); if (ErrorsLeft == 0) { ErrorSummary = Value * (1 - Value) * ErrorSummary * NextNeurons[errorNeuron]; if (WriteLog) { Outputter.Log($"Вес {NeuronName} - {errorNeuron.NeuronName} изменён {NextNeurons[errorNeuron]} - "); } errorNeuron.LastNeurons[this] = NextNeurons[errorNeuron] = NextNeurons[errorNeuron] * inertialTerm + learningNorm * Value * errorNeuron.ErrorSummary; if (WriteLog) { Outputter.Log($"{NextNeurons[errorNeuron]}"); } if (LastNeurons.Count != 0) { for (int i = 0; i < LastNeurons.Keys.Count; i++) { LastNeurons.Keys.ElementAt(i).RecieveErrorSigmoid(this, learningNorm, inertialTerm); } } } }
public override void SendSignal(Network.ActivateFunction activFunc) { Parallel.ForEach(NextNeurons, nextNeuron => { nextNeuron.Key.RecieveSignal(nextNeuron.Value * Value, activFunc); if (WriteLog) { Outputter.Log($"Сигнал {NeuronName} - {nextNeuron.Key.NeuronName} отправлен = {nextNeuron.Value * Value}"); } }); }
public double[] GetResult(params double[] args) { ClearNeurons(); if (args.Length != NeuronsNetwork[0].Length) { throw new ArgumentException("Количество входных данных не соответсвует размеру входного слоя."); } if (WriteLog) { Outputter.Log($"Входные данные: "); } for (int i = 0; i < args.Length; i++) { if (WriteLog) { Outputter.Log($"{NeuronsNetwork[0][i].NeuronName} = {args[i]}"); } } Task.Run(() => { Parallel.ForEach(NeuronsNetwork[0], inputNeuron => { inputNeuron.RecieveSignal(args[(inputNeuron as InputNeuron).NeuronId], NetFunctions.ActivateFunc); } ); } ).Wait(); Task.Run(() => { for (int i = 1; i < NeuronsNetwork.Length - 1; i++) { Parallel.ForEach(NeuronsNetwork[i].Where(t => t.GetRemainingSignals() == 0), hiddenNeuron => { hiddenNeuron.SendSignal(NetFunctions.ActivateFunc); } ); } } ).Wait(); double[] result = new double[NeuronsNetwork[NeuronsNetwork.Length - 1].Length]; for (int i = 0; i < result.Length; i++) { result[i] = NeuronsNetwork[NeuronsNetwork.Length - 1][i].GetValue(); } return(result); }
public virtual void AddLastNeuron(Neuron neuron, double weight) { if (LastNeurons.ContainsKey(neuron)) { if (WriteLog) { Outputter.Warning($"Нейроны {NeuronName} и {neuron.NeuronName} уже обьединены обратной связью."); } } else { LastNeurons.Add(neuron, weight); } }
public virtual void SendSignal(Network.ActivateFunction activFunc) { Parallel.ForEach(NextNeurons, nextNeuron => { double res = activFunc(Value); nextNeuron.Key.RecieveSignal(res * nextNeuron.Value, activFunc); if (WriteLog) { Outputter.Log($"Сигнал {NeuronName} - {nextNeuron.Key.NeuronName} отправлен = {Value} * {nextNeuron.Value} -> {res} * {nextNeuron.Value}"); } Value = res; } ); }
public virtual void AddNextNeuron(Neuron neuron, double?weight = null) { if (NextNeurons.ContainsKey(neuron)) { if (WriteLog) { Outputter.Warning($"Нейроны {NeuronName} и {neuron.NeuronName} уже обьединены прямой связью."); } } else { Random rand = new Random(); weight = weight == null?rand.NextDouble() : weight; NextNeurons.Add(neuron, weight.Value); neuron.AddLastNeuron(this, weight.Value); neuron.AdmissionsLeft = ++neuron.MaxAdmissionsLeft; } }
public override void AsOffset() { IsOffset = true; NeuronName += " (OFFSET)"; MaxAdmissionsLeft = AdmissionsLeft = 0; Value = 1; if (LastNeurons.Keys.Count != 0) { if (WriteLog) { Outputter.Warning($"При изменении свойства IsOffset нейрон {NeuronName} потерял связи с" + $" {LastNeurons.Keys.Count} нейронами!"); } } while (LastNeurons.Keys.Count != 0) { LastNeurons.ElementAt(0).Key.RemoveNextNeuron(this); LastNeurons.Remove(LastNeurons.ElementAt(0).Key); } }