using System.Collections.Generic;
public static double Sigmoid(IEnumerable<double> weights, IEnumerable<double> x, double bias)
return 1 / (1 + Math.Exp(-weights.AsParallel().Zip(x.AsParallel(), (a, b) => a * b).Sum() - bias));
public static Vector ToVector(this IEnumerable<double> e)
return (Vector)e.ToList();
public static Matrix ToMatrix(this IEnumerable<Vector> e)
return (Matrix)e.ToList();
public class Vector : List<double> { }
public class Matrix : List<Vector> { }
public class NeuroNetwork
private static Random rand = new Random();
private static IEnumerable<T> RandomGenerator<T>(int size, Func<int, T> generator)
return ParallelEnumerable.Range(0, size).Select(generator);
private static Vector GetRandomVector(int size)
return RandomGenerator(size, _ => rand.NextDouble()).ToVector();
private static Matrix GetRandomMatrix(int lists, int size)
return RandomGenerator(lists, _ => GetRandomVector(size)).ToMatrix();
List<Matrix> LayerWeights;
public int InCount { get; set; }
public int OutCount { get; set; }
public int HiddenLayerSize { get; set; }
public NeuroNetwork(int inCount = 784, int outCount = 10, int hiddenLayerSize = 15)
this.HiddenLayerSize = hiddenLayerSize;
LayerWeights = new List<Matrix>()
GetRandomMatrix(HiddenLayerSize, InCount),
GetRandomMatrix(OutCount, HiddenLayerSize)
LayerBias = new List<Vector>()
GetRandomVector(HiddenLayerSize),
GetRandomVector(OutCount)
public Vector Forward(Vector input)
if (input.Count != InCount)
throw new ArgumentException("Incorrect input size", "input");
Func<Vector, double, double> perceptronFunc = (weights, bias) => F.Sigmoid(weights, input, bias);
var hiddenLayer = LayerWeights[0].AsParallel();
var hiddenBias = LayerBias[0].AsParallel();
var hiddenOut = hiddenLayer.Zip(hiddenBias, perceptronFunc);
var outLayer = LayerWeights[1].AsParallel();
var outBias = LayerBias[1].AsParallel();
return outLayer.Zip(outBias, perceptronFunc).ToVector();
public static void Main()
Console.WriteLine("Hello World");