神经网络异或学习

时间:2015-02-07 17:52:31

标签: neural-network ada xor

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

XOR是一个很好的测试案例,还是我应该使用别的东西?

我在Ada中设置了我的神经网络代码,并且我已经在this tutorial之后建模了。我的神经网络(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;

最后一个输出是:

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

其中Y从神经网络输出,T是想要的目标。

3 个答案:

答案 0 :(得分:2)

首先,应该初始化您的权重,最好是随机值。例如,Ada.Numerics.Float_Random.Random( foo );
其次,如果添加偏置输入(常量输入,例如1.0),您的网络应该学得更好

有了这个,D应该开始收敛到0.0。

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

答案 1 :(得分:1)

一些建议:

  • 考虑将程序的一部分拆分出来。
  • 考虑使用所需的精度声明自己的浮点类型。
  • 考虑将Node作为歧视类型,并将该层的输入数作为判别式。
  • 在纸上运行一个简单的测试用例,并在您手动解决问题时验证您的实现是否与您获得的结果相同。

这些建议都不一定能解决您的问题,但有望让您更轻松地找到解决方案。

答案 2 :(得分:0)

XOR是神经网络的一个很好的测试案例,因为感知器不能解决它。反向传播是一种简单的梯度下降技术,具有众多众所周知的缺陷。大多数现代NN培训使用二阶导数信息,从而提供更强大和快速的培训。