public List <double> FeedForward(double[] input) { if (input.Length != InputLayer.Count) { throw new ArgumentException("input length has to be the same as the InputLayer length"); } // calculate input activations for (int i = 0; i < input.Length; i++) { InputLayer[i].ActivationValue = input[i]; } // calculate hidden layer activations // i : LayerIndex in HiddenLayers // j : NeuronIndex in HiddenLayers[i] for (int i = 0; i < HiddenLayers.Count; i++) { var previousLayer = HiddenLayers.ElementAtOrDefault(i - 1) ?? InputLayer; for (int j = 0; j < HiddenLayers[i].Count; j++) { HiddenLayers[i][j].ActivationValue = CalculateWeightedSum(previousLayer, j); } } // calculate output activations // i : NeuronIndex in OutputLayer var lastLayer = HiddenLayers.LastOrDefault() ?? InputLayer; for (int i = 0; i < OutputLayer.Count; i++) { var currentNeuron = OutputLayer[i]; OutputLayer[i].ActivationValue = CalculateWeightedSum(lastLayer, i); } // return only values of output layer return(OutputLayer.Select(x => x.ActivationValue).ToList()); }