2016-08-13 120 views
1

我正在嘗試使用這個https://www.youtube.com/watch?v=KkwX7FkLfug教程來使用反向傳播編寫NeuralNet。用於將一個層中的所有節點連接到下一層中的所有節點的算法

我想在C#中做到這一點,並正在改變一些細節。

他和我的主要區別是,我不知道從一開始就有多少神經元會在每個節點上。這是我的API將如何在代碼中工作。

class main 
{ 
    static void Main(string[] args) 
    { 
     List<bool> testData = new List<bool>() {true}; 
     System.Console.WriteLine("In MAIN! \n"); 
     int inputNeurons = 64; 
     int outputNeurons = 2; 

     double eta = 0.1; // 0.0..1.0 training rate 
     double alpha = 0.5; // 0.0..n  momentum 

     NeuralNet neuralNet = new NeuralNet(eta, alpha); 
     // order matters, first layer is for input, last layer is for output 
     neuralNet.AddLayer(inputNeurons); // input layer 
              // multiple hidden layers could go here 
     neuralNet.AddLayer(outputNeurons); // output Layer 
     neuralNet.MakeConnections(); 

     neuralNet.Train(testData); 

     neuralNet.GetResults(); 
     Console.ReadLine(); 
    } 
} 

這裏是我的NeuralNet代碼的其餘部分,還有一部分是僞代碼或只是打印報表,現在當我嘗試並獲得的連接工作。

namespace NeuralNetJO 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

     } 
    } 

    public class NeuralNet 
    { 
     public NeuralNet(double newEta, double newAlpha) 
     { 
      numLayers = -1; // numLayers tracks how many layers of neurons the neural net has 
      eta = newEta; 
      alpha = newAlpha; 
     } 

     /** 
     * GetResults() 
     *  returns array of results and weights 
     */ 
     public void GetResults() 
     { 
      foreach (Layer l in n_layer) 
      { 
       foreach (Neuron n in l.n_neurons) 
       { 

       } 
      } 
     } 

     public void MakeConnections() 
     { 
      // For each layer 
      if (numLayers > 0) 
      { 
       for (int i = 0; i < n_layer.Count; i++) 
       { 
        for (int j = 0; j < n_layer[i].n_neurons.Count; j++) 
        { 
         //For each Node in Layer that isn't final layer, connect it to every node in the next layer 

        } 
       } 
      } 
     } 

     public void FeedForward(List<int> inputVals) 
     { 

     } 

     public void BackProp(List<int> targetVals) 
     { 

     } 

     public void AddLayer(int numNeurons) 
     { 
      numLayers++; 
      if (numLayers > 0) //If first layer 
      { 
       Layer layer = new Layer(numNeurons, numLayers, n_layer[numLayers - 1]); 
       n_layer.Add(layer); 
      } 
      else 
      { 
       Layer layer = new Layer(numNeurons, numLayers); 
       n_layer.Add(layer); 
      } 
     } 

     public void Train(List<bool> testData) 
     { 
      Console.WriteLine("Training..."); 
      if (testData[0] == false) 
      { 
       Console.WriteLine("\t False"); 
      } 
      else 
      { 
       Console.WriteLine("\t True"); 
      } 
     } 



     //-------------- Member Variables --------------// 

     private List<Layer> n_layer = new List<Layer>(); // List of layers, layers are comprised of Neurons 
     private int numLayers; 
     double eta; 
     double alpha; 
    } 


    public class Layer 
    { 
     // mumLayer is for debug purposes only 
     public Layer(int numNeurons, int numLayer, Layer prevLayer = null) 
     { 
      myLayer = numLayer; 
      for (int i = 0; i <= numNeurons; ++i) // Add a bias Neuron 
      { 
       System.Console.Write(i + ": "); // Show line number for accurate Neuron count 
       Neuron neuron = new Neuron(i); 

       Console.WriteLine(" in layer #" + numLayer); 
       n_neurons.Add(neuron); 
      } 

      if (prevLayer != null) 
      { 
       foreach (Neuron n in prevLayer) 
       { 

       } 
      } 
     } 

     public List<Neuron> n_neurons = new List<Neuron>(); 
     int myLayer; 
    } 

    /** 
    * Neuron is a class that holds public information about Neurons 
    * This include weights, value, input and output locations. 
    */ 
    public class Neuron 
    { 
     public Neuron(int index) // Constructor 
     { 
      myIndex = index; 
      System.Console.Write("Creating Neuron " + myIndex); 
     } 



     private double transferFunction(double x) 
     { 
      return x; 
     } 

     private double transferFunctionDerivative(double x) 
     { 
      return x; 
     } 

     double randomWeight() 
     { 
      // set weights random 
      Random r = new Random(0); 
      return r.NextDouble() * 2 - 1.0; 
     } 

     public double Value { get; set; } // Output value 
     List<Connection> outPutWeights;  // Fpr each connection for the layer to the right 
     public int numOutputs { set; get; } // This will be set when numLayers > 0; 
     int myIndex; 
     double eta;  // training rate 
     double alpha; // momentum 
     double gradient; 

     private double sumDOW(Layer nextLayer) 
     { 
      return 1; 
     } 
    } 

    public class Connection 
    { 
     public double Weight { get; set; } 
     public double DeltaWeight { get; set; } 
    } 
} 

在教程中,他給每個神經元的下一層神經元的數量。在我的代碼中,我無法做到這一點,因爲我一次只添加一個圖層。第一層添加的是輸入層,第二層到n-1層是隱藏層,最後一層是輸出層。

我在繞過一個很好的算法時會遇到很多麻煩,這些算法可以循環遍歷第一層中的每個神經元並將它們鏈接到第二個神經元等等。我假設它將需要遞歸併以某種方式使用我的'numLayers'變量。

正如您在我的使用代碼中看到的,我撥打電話neuralNet.MakeConnections(),我願意添加連接,因爲我添加了其他圖層;如果任何人都能看到這樣做的好地方。

這是我最初的想法,但是當我被困住時,我畫了一張照片,並決定用這個函數來做它可能會更簡單。

在此先感謝您的幫助!

+0

小心使用'numLayers'。即使'n_layer.Count == 0',你也可以在'-1'開始。然後你用它來決定這是否是你的第一層。爲什麼不使用'if(n_layer.Count == 0)...'來決定何時添加第一層? –

回答

1

re:I am assuming it will need to be recursive

根本不是。對於額外變量numLayers也沒有必要,您已經知道您添加了多少個圖層n_layers.Count

// in class NeuralNet 
public void MakeConnections() 
{ 
    // start at input layer, stop at last hidden layer 
    for(int i=0; i<(n_layer.Count()-1); ++i) 
    { 
    Layer thisLayer = n_layer[i]; // only for typing convenience 
    Layer nextLayer = n_layer[i+1]; 
    for(int n1=0; n1<thisLayer.n_neurons.Count(); ++n1) 
    { 
     Neuron thisNeuron = thisLayer.n_neurons[n1]; 
     for(int n2=0; n2<nextLayer.n_neurons.Count(); ++n2) 
     { 
     thisNeuron.outPutWeights.Add(
      new Connection(randomWeight(),randomWeight()); 
     } 
    } 
    } 
} 

如果你願意,當你添加圖層添加這些連接,那麼它可能是這個樣子:

// in class NeuralNet 
public void AddLayer(int numNeurons) 
{ 
    Layer layer = new Layer(numNeurons, 
          n_layers.Count(), 
          (n_layers.Count > 0) 
          ? n_layer[n_layers.Count-1] 
          : null); 
    n_layers.Add(layer); 
} 

// in class Layer 
public Layer(int numNeurons, 
      int numLayer, 
      Layer prevLayer = null) 
{ 
    for (int i = 0; i <= numNeurons; ++i) 
    { 
    Neuron neuron = new Neuron(i); 
    n_neurons.Add(neuron); 
    } 
    if (prevLayer != null) 
    { 
    for(int i=0; i<prevLayer.n_neurons.Count(); ++i) 
    { 
     for(int j=0; j<n_neurons.Count(); ++j) 
     { 
     prevLayer.n_neurons[i].outputWeights.Add(
      new Connection(randomWeight(), randomWeight())); 
     } 
    } 
    } 
} 

有,當然,沒有需要以兩種風格進行連接。你會有這樣的雙連接。只要一起用MakeConnections立即全部做,或者在飛行中做。

相關問題