我正在努力测试我的神经网络是否正常工作并且我尝试过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是想要的目标。
答案 0 :(得分:2)
首先,应该初始化您的权重,最好是随机值。例如,Ada.Numerics.Float_Random.Random( foo );
其次,如果添加偏置输入(常量输入,例如1.0),您的网络应该学得更好
有了这个,D应该开始收敛到0.0。
通过打印网络中的所有输入/输出和权重(包括隐藏层),您可以在这种情况下帮助自己。在你的情况下,将出现一个不应该存在的模式(所有权重都为0.0的结果)
答案 1 :(得分:1)
一些建议:
Node
作为歧视类型,并将该层的输入数作为判别式。这些建议都不一定能解决您的问题,但有望让您更轻松地找到解决方案。
答案 2 :(得分:0)
XOR是神经网络的一个很好的测试案例,因为感知器不能解决它。反向传播是一种简单的梯度下降技术,具有众多众所周知的缺陷。大多数现代NN培训使用二阶导数信息,从而提供更强大和快速的培训。