Регистрация | Вход
public class RosenblattPerceptron { private double[][] aWeights; private double[] rWeights; private readonly double lr; private readonly Random rnd; int maxEpochs; public RosenblattPerceptron(int inputDim = 2, int aCount = 50, double learningRate = 0.1, int seed = 0, int maxEpochs = 10) { lr = learningRate; this.maxEpochs = maxEpochs; rnd = new Random(seed); aWeights = new double[aCount][]; for (int i = 0; i < aCount; i++) { aWeights[i] = new double[inputDim + 1]; for (int j = 0; j < aWeights[i].Length; j++) aWeights[i][j] = rnd.NextDouble() * 2 - 1; } rWeights = new double[aCount + 1]; this.maxEpochs = maxEpochs; } private int Step(double z) => z > 0 ? 1 : 0; private double[] Project(double[] input) { double[] outA = new double[aWeights.Length]; for (int i = 0; i < aWeights.Length; i++) { double s = aWeights[i].Last(); for (int j = 0; j < input.Length; j++) s += aWeights[i][j] * input[j]; outA[i] = Step(s); } return outA; } public double[] Compute(double[] vector) { var proj = Project(vector); double s = rWeights.Last(); for (int i = 0; i < proj.Length; i++) s += rWeights[i] * proj[i]; return new double[] { Step(s) }; } public void Learn(double[][] inputs, double[][] outputs) { for (int epoch = 0; epoch < maxEpochs; epoch++) { int errors = 0; for (int i = 0; i < inputs.Length; i++) { var proj = Project(inputs[i]); double s = rWeights.Last(); for (int j = 0; j < proj.Length; j++) s += rWeights[j] * proj[j]; int pred = Step(s); int target = (int)outputs[i][0]; int delta = target - pred; if (delta != 0) { for (int j = 0; j < proj.Length; j++) rWeights[j] += lr * delta * proj[j]; rWeights[rWeights.Length - 1] += lr * delta; errors++; } } if (errors == 0) break; } } } public static void Main(string[] args) { double[][] X = { new double[]{0,0}, new double[]{0,1}, new double[]{1,0}, new double[]{1,1} }; double[][] Y = { new double[]{0}, new double[]{1}, new double[]{1}, new double[]{0} }; var clf = new RosenblattPerceptron(inputDim: 2, aCount: 50, learningRate: 0.1, seed: 42, 10); clf.Learn(X, Y); foreach (var xi in X) { var y = clf.Compute(xi); Console.WriteLine($"{xi[0]}, {xi[1]} -> {y[0]}"); } Console.ReadKey(); }