ｃ＃でxor　その２

#概要
c#でxorやってみた。


#サンプルコード


```
using System;

public class Hello
{
    static int numEpochs = 200;
    static int numInputs = 2;
    static int numPatterns = 4;
    static double LR_IH = 0.7;
    static double LR_HO = 0.07;
    static int patNum;
    static double error;
    static double outPred;
    static double RMSerror;
    static double[][] trainInputs = new double[][] {
	    new double[]{0, 0},
	    new double[]{1, 0}, 
	    new double[]{0, 1}, 
	    new double[]{1, 1} 
    };
    static double[] trainOutputs= new double[] {0, 1, 1, 0};
    static double[] h = new double[8]; 
    static double[,] wih = new double[4, 8]; 
    static double[] who = new double[8];
    static double forward(double[] state)
    {
	    int i, 
	    	j;
	    for (i = 0; i < 8; i++)
    	{
	    	h[i] = 0.0;
    		for (j = 0; j < numInputs; j++) 
	    	{
		        h[i] = h[i] + (state[j] * wih[j,i]);
	    	}
		    h[i] = tanh(h[i]);
    	}
	    double push = 0.0, 
	        sum = 0.0;
	    for (i = 0; i < 8; i++) 
	    {
	        sum += h[i] * who[i];
    	}
	    push = sum;
	    return push;
    }
    static void backprop(double push, double target) 
    {
    	error = push - target;
    	WeightChangesHO(error);
    	WeightChangesIH(error);
    }
    static void WeightChangesHO(double error)
    {
    	int k; 
    	for (k = 0; k < 8; k++)
    	{
    		double weightChange = LR_HO * error * h[k];
    		who[k] = who[k] - weightChange;
    		if (who[k] < -5) who[k] = -5;
    		else if (who[k] > 5) who[k] = 5;
    	}
    }
    static void WeightChangesIH(double error)
    {
    	int i, 
    		k; 
    	for (i = 0; i < 8; i++)
    	{
    		double gradient = (1 - (h[i]) * h[i]) * who[i] * error * LR_IH;
    		for (k = 0; k < numInputs; k++)
    		{
    			double weightChange = gradient * trainInputs[patNum][k];
    			wih[k, i] = wih[k, i] - weightChange;
    		}
    	}
    }
    static double tanh(double x)
    {
    	if (x > 20) return 1;
    	else if (x < -20) return -1;
    	else
    	{
    		double a = Math.Exp(x);
    		double b = Math.Exp(-x);
    		return (a - b) / (a + b);
    	}
    }
    static double test(int patternNumber) 
    {
    	patNum = patternNumber;
    	return forward(trainInputs[patNum]);
    }
    static void calcOverallError()
    {
    	int i;
    	RMSerror = 0.0;
    	for (i = 0; i < numPatterns; i++)
    	{
    		patNum = i;
    		forward(trainInputs[patNum]);
    		RMSerror = RMSerror + (error * error);
    	}
    	RMSerror = RMSerror / numPatterns;
    	RMSerror = Math.Sqrt(RMSerror);
    }
    static void printWeights() 
    {
    	int i, 
    	    j;
    	for (i = 0; i < 2; i ++) 
    	{
    		for (j = 0; j < 4; j ++) 
    		{
    		    System.Console.WriteLine("{0} {1}  {2}", i, j, wih[i, j]);
    		}
    	}
    	for (i = 0; i < 4; i ++) 
    	{
    	    System.Console.WriteLine("{0} {1}", i, who[i]);
    	}
    }
    static void testAll()
    {
	    int i;
    	double push;
    	for (i = 0; i < numPatterns; i++)
    	{
    		push = test(i);
    		System.Console.WriteLine("pat{0} expected = {1} neural model = {2}", patNum + 1, trainOutputs[patNum], push);
    	}
    }
    static void train()
    {
    	int i, 
    		j;
    	double push;
    	var random = new Random();
    	for (j = 0; j <= numEpochs; j++)
    	{
    		for (i = 0; i < numPatterns; i++)
    		{
    		    var randomdef = random.NextDouble();
    			patNum = (int) ((randomdef * numPatterns) - 0.001);
    			push = forward(trainInputs[patNum]);
    			backprop(push, trainOutputs[patNum]);
    		}
    		calcOverallError();
    		if (j % 100 == 0) 
    		{
    			System.Console.WriteLine("epoch = {0} loss = {1}", j, RMSerror);
    			testAll();
    		}
    	}
    }
    static void initWeights()
    {
    	int i, 
    	    j; 
    	var random = new Random();    
    	for (j = 0; j < 8; j++)
    	{
    	    var randomdef = random.NextDouble();
    		who[j] = (randomdef - 0.5) / 2;
    		for (i = 0; i < numInputs; i++) 
    		{
    		    randomdef = random.NextDouble();
    		    wih[i, j] = (randomdef - 0.5) / 5;
    		}
    	}
    }
    static void init() 
    {
    	initWeights();
    }
    public static void Main()
    {
        init();
        train();
        printWeights();
        System.Console.WriteLine("Hello C#");
    }
}

```

#成果物

https://paiza.io/projects/TA9C1wodA0hlnmQkfaWhqQ

以上。