Advertisement
aquiem

Untitled

Oct 5th, 2024
143
0
170 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.43 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4.  
  5. public class main{
  6.     public static void Main(string[] args){
  7.         int[] networkArchitecture = new int[] {3,4,3};
  8.         NeuralNetwork brain = new NeuralNetwork(networkArchitecture);
  9.  
  10.         double[, ,] trainData = new double[4, 2, 3] {
  11.             {
  12.                 {0.1,0.2,0.5},
  13.                 {0.1,0.2,0.5}
  14.             },
  15.             {
  16.                 {0.2,1,0.1},
  17.                 {0.2,1,0.1}
  18.             },
  19.             {
  20.                 {1.6,1.4,0.2},
  21.                 {1.6,1.4,0.2}
  22.             },
  23.             {
  24.                 {0.4,1.2,1.4},
  25.                 {0.4,1.2,1.4}
  26.             },
  27.         };
  28.  
  29.         double[, ,] testData = new double[1, 2, 3] {
  30.             {
  31.                 {1.2,0.2,0.7},
  32.                 {1.2,0.2,0.7},
  33.             }
  34.         };
  35.  
  36.  
  37.         int epoch = 10000000;
  38.         double avgLoss = 0;
  39.         for (int i=0 ; i<epoch ; i++){
  40.  
  41.             double[] currTrainInput = new double[3];
  42.             currTrainInput[0] = trainData[i%4, 0, 0];
  43.             currTrainInput[1] = trainData[i%4, 0, 1];
  44.             currTrainInput[2] = trainData[i%4, 0, 2];
  45.  
  46.             double[] currTrainOutput = new double[3];
  47.             currTrainOutput[0] = trainData[i%4, 1, 0];
  48.             currTrainOutput[1] = trainData[i%4, 1, 1];
  49.             currTrainOutput[2] = trainData[i%4, 1, 2];
  50.  
  51.  
  52.  
  53.             double[] output = NeuralNetwork.FeedForward(brain , currTrainInput);
  54.  
  55.             double loss = calLoss(output, currTrainOutput);
  56.             avgLoss += loss;
  57.  
  58.             NeuralNetwork.Backward(brain, output, currTrainOutput);  
  59.  
  60.             if (i != 0 && i%500000 == 0){
  61.                 Console.WriteLine("avg loss for " + (i) + " iteration is " + (avgLoss/500000));
  62.                 avgLoss = 0;
  63.             }
  64.         }
  65.  
  66.         double[] testInput = new double[3];
  67.         testInput[0] = testData[0, 0, 0];
  68.         testInput[1] = testData[0, 0, 1];
  69.         testInput[2] = testData[0, 0, 2];
  70.  
  71.         double[] testOutput = new double[3];
  72.         testOutput[0] = testData[0, 1, 0];
  73.         testOutput[1] = testData[0, 1, 1];
  74.         testOutput[2] = testData[0, 1, 2];
  75.  
  76.  
  77.  
  78.         double[] NNOutput = NeuralNetwork.FeedForward(brain , testInput);
  79.  
  80.         double testLoss = calLoss(NNOutput, testOutput);
  81.         Console.WriteLine("\n\nfinal test loss is " + testLoss);
  82.  
  83.         // debug.printArray(brain.levels[0].weights[0]);
  84.         // debug.printArray(brain.levels[0].weights[1]);
  85.         // debug.printArray(brain.levels[0].weights[2]);
  86.  
  87.         // Console.WriteLine("\n\n----------------------\n\n");
  88.  
  89.  
  90.         // debug.printArray(brain.levels[1].weights[0]);
  91.         // debug.printArray(brain.levels[1].weights[1]);
  92.         // debug.printArray(brain.levels[1].weights[2]);
  93.         // debug.printArray(brain.levels[1].weights[3]);
  94.  
  95.         // NeuralNetwork.DebugBackward(brain, NNOutput, testOutput);  
  96.     }
  97.  
  98.     public static double calLoss(double[] calculatedOutputs, double[] estimatedOutputs){
  99.         double calculatedNum = 0;
  100.         double estimatedNum = 0;
  101.         for (int i=0 ; i<3 ; i++){
  102.             calculatedNum += calculatedOutputs[i] * Math.Pow(2, 2-i);
  103.             estimatedNum += estimatedOutputs[i] * Math.Pow(2, 2-i);
  104.         }
  105.  
  106.         return Math.Abs(calculatedNum - estimatedNum);
  107.     }
  108. }
  109.  
  110. public class NeuralNetwork
  111. {
  112.     public Level[] levels;
  113.  
  114.     public NeuralNetwork(int[] neuronCounts)
  115.     {
  116.         levels = new Level[neuronCounts.Length-1];
  117.         for (int i = 0; i < neuronCounts.Length - 1; i++)
  118.         {
  119.             levels[i] = new Level(neuronCounts[i], neuronCounts[i + 1]);
  120.         }
  121.     }
  122.  
  123.     // public NeuralNetwork(int[] neuronCounts, levelData[] levelInfo)
  124.     // {
  125.     //     levels = new Level[levelInfo.Length];
  126.  
  127.     //     for (int i = 0; i < levelInfo.Length; i++)
  128.     //     {
  129.     //         levels[i] = new Level(levelInfo[i]);
  130.     //     }
  131.     // }
  132.  
  133.     public static double[] FeedForward(NeuralNetwork network, double[] givenInputs)
  134.     {  
  135.  
  136.         double[] outputs = Level.FeedForward(givenInputs, network.levels[0]);
  137.         for (int i = 1; i < network.levels.Length; i++)
  138.         {
  139.             outputs = Level.FeedForward(outputs, network.levels[i]);
  140.         }
  141.  
  142.         return outputs;
  143.     }
  144.  
  145.     public static void Backward(NeuralNetwork network, double[] calculatedOutputs, double[] estimatedOutputs)
  146.     {
  147.         double[] delta = new double[calculatedOutputs.Length];
  148.         for (int i = 0; i < calculatedOutputs.Length; i++)
  149.         {
  150.             //define loss function
  151.             // Console.WriteLine(calculatedOutputs[i] + " " + estimatedOutputs[i]);
  152.             delta[i] = calculatedOutputs[i] - estimatedOutputs[i];
  153.         }
  154.  
  155.         for (int i = network.levels.Length - 1; i >= 0; i--)
  156.         {
  157.             delta = Level.Backward(network.levels[i], delta);
  158.         }
  159.     }
  160.  
  161.         public static void DebugBackward(NeuralNetwork network, double[] calculatedOutputs, double[] estimatedOutputs)
  162.     {
  163.         double[] delta = new double[calculatedOutputs.Length];
  164.         debug.printArray(calculatedOutputs);
  165.         debug.printArray(estimatedOutputs);
  166.  
  167.         for (int i = 0; i < calculatedOutputs.Length; i++)
  168.         {
  169.             //define loss function
  170.             delta[i] = calculatedOutputs[i] - estimatedOutputs[i];
  171.         }
  172.  
  173.         Console.WriteLine("\nvalue of delta 1 is : ");
  174.         debug.printArray(delta);
  175.  
  176.         for (int i = network.levels.Length - 1; i >= 0; i--)
  177.         {
  178.             delta = Level.DebugBackward(network.levels[i], delta);
  179.             Console.WriteLine("\nvalue of delta 2 is : ");
  180.             debug.printArray(delta);
  181.         }
  182.  
  183.         Console.WriteLine("\n\n----------------------------------------\n\n");
  184.  
  185.     }
  186. }
  187.  
  188. public class Level
  189. {
  190.     public double[] inputs;
  191.     public double[] outputs;
  192.     public double[] biases;
  193.     public double[][] weights;
  194.  
  195.     public Level(int inputCount, int outputCount)
  196.     {
  197.         inputs = new double[inputCount];
  198.         outputs = new double[outputCount];
  199.         biases = new double[outputCount];
  200.         weights = new double[inputCount][];
  201.  
  202.         for (int i = 0; i < inputCount; i++)
  203.         {
  204.             weights[i] = new double[outputCount];
  205.         }
  206.  
  207.         Randomize();
  208.     }
  209.  
  210.     // public Level(levelData data)
  211.     // {
  212.     //     inputs = new double[data.inputs];
  213.     //     outputs = new double[data.outputs];
  214.     //     biases = new double[data.outputs];
  215.     //     weights = new double[data.inputs][];
  216.  
  217.     //     for (int i = 0; i < inputs.Length; i++)
  218.     //     {
  219.     //         weights[i] = new double[data.outputs];
  220.     //     }
  221.  
  222.     //     int temp = 0;
  223.     //     for (int i = 0; i < inputs.Length; i++)
  224.     //     {
  225.     //         for (int j = 0; j < outputs.Length; j++)
  226.     //         {
  227.     //             weights[i][j] = data.weights[temp];
  228.     //             temp++;
  229.     //         }
  230.     //     }
  231.  
  232.     //     for (int i = 0; i < biases.Length; i++)
  233.     //     {
  234.     //         biases[i] = data.biases[i];
  235.     //     }
  236.     // }
  237.  
  238.     private void Randomize()
  239.     {
  240.         System.Random random = new System.Random();
  241.         for (int i = 0; i < inputs.Length; i++)
  242.         {
  243.             for (int j = 0; j < outputs.Length; j++)
  244.             {
  245.                 weights[i][j] = random.NextDouble();
  246.             }
  247.         }
  248.  
  249.         for (int i = 0; i < biases.Length; i++)
  250.         {
  251.             biases[i] = random.NextDouble();
  252.         }
  253.     }
  254.  
  255.     public static double[] FeedForward(double[] givenInputs, Level level)
  256.     {
  257.         for (int i = 0; i < level.inputs.Length; i++)
  258.         {
  259.             level.inputs[i] = givenInputs[i];
  260.         }
  261.        
  262.        
  263.         for (int i = 0; i < level.outputs.Length; i++)
  264.         {
  265.             double sum = 0;
  266.             for (int j = 0; j < level.inputs.Length; j++)
  267.             {
  268.                 sum += level.inputs[j] * level.weights[j][i];
  269.             }
  270.            
  271.             level.outputs[i] = sum;
  272.         }
  273.        
  274.         return level.outputs;
  275.     }
  276.  
  277.     public static double[] Backward(Level level, double[] errorsFromAboveLayer)
  278.     {
  279.         double[][] differentiationWrtWeight = new double[level.inputs.Length][];
  280.         for (int i = 0; i < level.inputs.Length; i++)
  281.         {
  282.             differentiationWrtWeight[i] = new double[level.outputs.Length];
  283.         }
  284.  
  285.         for (int i = 0; i < level.inputs.Length; i++)
  286.         {
  287.             for (int j = 0; j < level.outputs.Length; j++)
  288.             {
  289.                 differentiationWrtWeight[i][j] = level.inputs[i] * errorsFromAboveLayer[j];
  290.             }
  291.         }
  292.  
  293.         UpdateWeights(level, differentiationWrtWeight);
  294.  
  295.         List<double> errorInCurrentLayer = new List<double>();
  296.         for (int i = 0; i < level.inputs.Length; i++)
  297.         {
  298.             double sum = 0;
  299.             for (int j = 0; j < level.outputs.Length; j++)
  300.             {
  301.                 sum += level.weights[i][j] * errorsFromAboveLayer[j];
  302.             }
  303.             errorInCurrentLayer.Add(sum);
  304.         }
  305.  
  306.         double[] temp = errorInCurrentLayer.ToArray();
  307.  
  308.         return errorInCurrentLayer.ToArray();
  309.     }
  310.  
  311.     public static double[] DebugBackward(Level level, double[] errorsFromAboveLayer)
  312.     {
  313.         double[][] differentiationWrtWeight = new double[level.inputs.Length][];
  314.         for (int i = 0; i < level.inputs.Length; i++)
  315.         {
  316.             differentiationWrtWeight[i] = new double[level.outputs.Length];
  317.         }
  318.  
  319.         for (int i = 0; i < level.inputs.Length; i++)
  320.         {
  321.             for (int j = 0; j < level.outputs.Length; j++)
  322.             {
  323.                 differentiationWrtWeight[i][j] = level.inputs[i] * errorsFromAboveLayer[j];
  324.             }
  325.         }
  326.  
  327.         Console.WriteLine("\n\nInputs :");
  328.         string s = "";
  329.         for(int i = 0; i < level.inputs.Length;i++){
  330.             s = s + level.inputs[i].ToString() + " ";
  331.         }
  332.         Console.WriteLine(s);
  333.    
  334.         Console.WriteLine("\n\nOld Wieghts : ");
  335.         for (int i=0 ; i<level.inputs.Length ; i++){
  336.             debug.printArray(level.weights[i]);
  337.         }
  338.  
  339.         UpdateWeights(level, differentiationWrtWeight);
  340.  
  341.         Console.WriteLine("\n\nNew Wieghts : ");
  342.         for (int i=0 ; i<level.inputs.Length ; i++){
  343.             debug.printArray(level.weights[i]);
  344.         }
  345.  
  346.  
  347.         List<double> errorInCurrentLayer = new List<double>();
  348.         for (int i = 0; i < level.inputs.Length; i++)
  349.         {
  350.             double sum = 0;
  351.             for (int j = 0; j < level.outputs.Length; j++)
  352.             {
  353.                 sum += level.weights[i][j] * errorsFromAboveLayer[j];
  354.             }
  355.             errorInCurrentLayer.Add(sum);
  356.         }
  357.  
  358.         double[] temp = errorInCurrentLayer.ToArray();
  359.  
  360.         return errorInCurrentLayer.ToArray();
  361.     }
  362.  
  363.  
  364.     private static void UpdateWeights(Level level, double[][] differentiationWrtWeight)
  365.     {
  366.         for (int i = 0; i < level.inputs.Length; i++)
  367.         {
  368.             for (int j = 0; j < level.outputs.Length; j++)
  369.             {
  370.                 //use alpha
  371.                 level.weights[i][j] = level.weights[i][j] - (differentiationWrtWeight[i][j] * 0.000005);
  372.             }
  373.         }
  374.     }
  375. }
  376.  
  377. public class debug{
  378.     public static void printArray(double[] x){
  379.         string s = "";
  380.         for(int i = 0; i < x.Length;i++){
  381.             s = s + x[i].ToString() + " ";
  382.         }
  383.         Console.WriteLine(s);
  384.     }
  385. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement