Neural network 神经网络异或学习

Neural network 神经网络异或学习,neural-network,ada,xor,Neural Network,Ada,Xor,我正在努力测试我的神经网络是否正常工作,我已经尝试过XOR,因为这是一个简单的测试用例 XOR是一个好的测试用例还是应该使用其他的 我已经在Ada中设置了我的神经网络代码,并按照它建模。我的神经网络(2输入,3隐藏,1输出)不能学习异或。下面的代码有什么问题 with Ada.Text_IO;use Ada.Text_IO; with Ada.Float_Text_IO;use Ada.Float_Text_IO; with Ada.Numerics.Generic_Elementary_Fun

我正在努力测试我的神经网络是否正常工作,我已经尝试过XOR,因为这是一个简单的测试用例

XOR是一个好的测试用例还是应该使用其他的

我已经在Ada中设置了我的神经网络代码,并按照它建模。我的神经网络(2输入,3隐藏,1输出)不能学习异或。下面的代码有什么问题

with Ada.Text_IO;use Ada.Text_IO;
with Ada.Float_Text_IO;use Ada.Float_Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;


procedure Main is

   Learning_Rate : Float := 0.5;

   function Sigmoid(X : Float) return Float is
      package Math is new Ada.Numerics.Generic_Elementary_Functions(Float); use Math;
      e : constant Float := 2.7;
   begin
      return 1.0 / (1.0 + e**(-X));
   end;

   function Sigmoid_Derivative (X : Float) return Float is
   begin
      return Sigmoid(X) * (1.0 - Sigmoid(X));
   end;


   type Float_Array is array (Positive range <>) of Float;
   type Node;
   type Node is record
      S : Float := 0.0; --Summation
      Y : Float := 0.0; --Output
      W : Float_Array(1..10) := (others => 0.0); --Weigths
      D : Float := 0.0; --Delta error
   end record;
   type Layer is array (Positive range <>) of Node;



   --Forward calculations

   procedure Calculate_Summation (N : in out Node; L : in Layer) is
   begin
      N.S := 0.0;
      for Index in L'Range loop
         N.S := N.S + L(Index).Y * N.W(Index);
      end loop;
   end;

   procedure Calculate_Summation (Destination : in out Layer; Source : in Layer) is
   begin
      for N of Destination loop
         Calculate_Summation(N, Source);
      end loop;
   end;

   procedure Calculate_Output (L : in out Layer) is
   begin
      for N of L loop
         N.Y := Sigmoid(N.S);
      end loop;
   end;


   --Backpropogation

   procedure Calculate_Delta (L : in out Layer; N : in Node ) is
   begin
      for Index in L'Range loop
         L(Index).D := L(Index).D + N.D * N.W(Index);
      end loop;
   end;

   procedure Calculate_Delta (Destination : in out Layer; Source : in Layer) is
   begin
      for N of Source loop
         Calculate_Delta(Destination, N);
      end loop;
   end Calculate_Delta;


   function Calculate_Delta_Weight(D, S, X : Float) return Float is
   begin
      return Learning_Rate * D * Sigmoid_Derivative(S) * X;
   end;


   --Weight adjustment

   procedure Calculate_Weight(N : in out Node; L : in Layer) is
   begin
      for Index in L'Range loop
         N.W(Index) := N.W(Index) + Calculate_Delta_Weight(N.D, N.S, L(Index).Y);
      end loop;
      N.D := 0.0;
   end;

   procedure Calculate_Weight(Destination : in out Layer; Source : in Layer) is
   begin
      for N of Destination loop
         Calculate_Weight(N, Source);
      end loop;
   end;

   LI : Layer(1..2);
   LH : Layer(1..3);
   LO : Layer(1..1);

   procedure Learn (A, B, Target : Float) is
   begin

      LI(1).Y := A;
      LI(2).Y := B;

      Calculate_Summation( Source => LI, Destination => LH );
      Calculate_Output(LH);

      Calculate_Summation( Source => LH, Destination => LO );
      Calculate_Output(LO);

      LO(1).D := Target - LO(1).Y;

      Put("A,B,T ="); Put(A, 3,3,0);Put(B, 3,3,0);Put(Target, 3,3,0);
      Put("     Y ="); Put(LO(1).Y, 3,3,0);
      Put("     D ="); Put(LO(1).D, 3,3,0);

      Calculate_Delta(Source => LO, Destination => LH);

      Calculate_Weight(Source => LH, Destination => LO);
      Calculate_Weight(Source => LI, Destination => LH);

   end;


begin

   for I in 1..1000 loop
      Learn(1.0, 1.0, 0.0);New_Line;
      Learn(1.0, 0.0, 1.0);New_Line;
      Learn(0.0, 1.0, 1.0);New_Line;
      Learn(0.0, 0.0, 0.0);New_Line;
      New_Line;
   end loop;
end Main;
其中Y是神经网络的输出,T是目标。

一些建议:

  • 考虑将程序的一部分拆分成一个包
  • 考虑使用所需的精度声明自己的浮点类型
  • 考虑将
    节点
    设置为一个有区别的类型,将层的输入数量作为区别
  • 在纸上运行一个简单的测试用例,并验证您的实现在手动解决问题时得到的结果是否与您得到的结果相同

这两个建议都不一定能解决您的问题,但它们有望使您更容易找到解决方案。

XOR是神经网络的一个很好的测试案例,因为它不能由感知器解决。反向传播是一种简单的梯度下降技术,有许多众所周知的缺陷。大多数现代神经网络训练都使用二阶导数信息,因此训练更加稳健和快速。

首先,应该初始化权重,最好是随机值。例如,
Ada.Numerics.Float\u Random.Random(foo)
第二,如果您添加了偏差输入(恒定输入,例如1.0),您的网络应该会学习得更好

这样,D应该开始向0.0收敛


在这种情况下,您可以通过打印网络中的所有输入/输出和权重(包括隐藏层)来帮助自己。在您的情况下,将出现一个不应该出现的模式(所有权重均为0.0的结果)

您的网络拓扑似乎与教程不匹配(3个输入神经元,2个隐藏,1个输出)可能有意义吗?@Brian Drummond该教程是神经网络背后逻辑的一个例子,与XOR门无关。XOR绝对是一个很好的测试,因为它不是线性可分的,所以需求需要一个工作的隐藏层。你考虑过迭代的第一步是如何偏离预期结果的吗?我发现了一些额外的信息。在设置(x1,x2,bias=1)->(h1,h2,h3)->(y1)和随机权重的情况下,需要对4个训练行进行大约1000次迭代来学习XOR或XNOR门。完全读入时,权重可能在-10.0到10.0之间变化。有时输出收敛到0.5而不是1.0。因此,增量误差并不总是收敛到0.0。
A,B,T =  1.000  1.000  0.000     Y =  0.497     D = -0.497
A,B,T =  1.000  0.000  1.000     Y =  0.495     D =  0.505
A,B,T =  0.000  1.000  1.000     Y =  0.494     D =  0.506
A,B,T =  0.000  0.000  0.000     Y =  0.505     D = -0.505