当我运行以下代码时
input=[0 0; 0 1; 1 0; 1 1]; % OR example
input=transpose(input);
target=[0;1;1;1];
target=transpose(target);
net=newff(input,target,5,{'logsig','logsig'});
net=train(net,input,target);
result=sim(net,input);
% result is like this
%0.5000 1.000 1.000 1.000
%but want my output as
%0 1 1 1
当我看到网络的性能时, 0.125 。但我希望它 0.0001 。即使尝试将目标降低到1e-30,性能也不会降低,而是会增加。请给我一个改善这个网络性能的解决方案,因为这只是一个示例代码,借助于此我需要构建一个具有419个输入和2个输出的大型网络。
请清除我的怀疑。
提前致谢。
答案 0 :(得分:3)
问题在于您选择的隐藏和输出图层成员函数logsig
以及您选择的输入和目标范围[0, 1]
。如果你去MATLAB并输入logsig(0)
,你会得到0.5
的答案。基本上,通过使隐藏图层和输出图层都使用logsig
,您最终会从隐藏图层中获取False
个案例([0 0]
的输入)中的一个非常小的数字,这反过来为您提供logsig(0) = 0.5
的网络输出。有两种方法可以解决这个问题。
使用purelin
作为输出图层,并通过复制您正在使用的现有培训示例添加一些额外的培训示例。这可确保您的输出是隐藏图层输出的线性组合:
input = repmat(input, 1, 5); % make more input data
target = repmat(target, 1, 5); % make more target data
net = newff(input, target, 5, {'logsig', 'purelin'}); % note the output tf 'purelin'
% Proceed as before.
现在,当您将[0 0]
传递到隐藏图层时,您将从隐藏图层中获得一个非常小的数字,这些小数字的线性组合将为您提供接近0
的内容。
将所有输入和定位缩放到[-1, 1]
范围而不是[0, 1]
范围。这基本上可以确保训练功能可以在训练中使用全范围的logsig
,而不是像以前那样只使用上半部分。现在,就像上面一样,你需要制作一些额外的数据来训练:
input = [-1 -1; -1 1; 1 -1; 1 1]'; % note the apostrophe (') takes the transpose of the matrix
target = [-1 1 1 1]; % no transpose needed
input = repmat(input, 1, 5); % make more input data
target = repmat(target, 1, 5); % make more target data
net = newff(input, target, 5, {'logsig', 'logsig'}); % note the output tf 'logsig'
% Proceed as before.
这两种方法都让我得到了我想要的结果。
注意:通常,仅复制数据不足以增加数据集的大小。我认为它适用于这种情况,因为您的数据集涵盖了 OR 电路的所有可能输入。通常,您需要做的不仅仅是复制,因为这会导致过度拟合。您需要做什么取决于您使用的数据类型。例如,如果您正在进行图像识别,则可能会对图像添加失真:放大部分,倾斜图像等,而不是随机噪声。这个想法是模仿“现实生活”的例子。
如果你有Octave,它基本上是MATLAB的免费和开源版本,你可以使用nnet
包生成所需的网络,如下所示。请注意,nnet
包使用先前(已停止)MATLAB语法定义每个输入(Pr
)的范围矩阵,然后使用每个层中节点数量的向量({{ 1}})。
Ss
我在Pr = [0 1; 0 1];
Ss = [2 5 1];
net = newff(Pr, Ss, {'purelin', 'logsig', 'purelin'});
net = train(net, input, target);
result = sim(net, input)
范围内使用了您的原始输入和目标向量,最终结果为[0 1]
,这非常接近我们期望得到的[-1.7e-16, 1, 1, 1]