我正试图用这个https://www.youtube.com/watch?v=KkwX7FkLfug教程编写一个使用反向传播的神经网络。
我试着用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(),我愿意在添加其他层时添加连接;如果有人能看到这样做的好地方的话。
这是我最初的想法,但当我陷入困境时,我给自己画了一张图,并决定在这个函数中做它可能会更简单。
提前感谢您的帮助!

最佳答案

回复: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一次全部完成,要么在飞行中完成。

关于c# - 用于将一层中的所有节点连接到下一层中的所有节点的算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38929881/

10-11 15:21