MATLAB 解决方案
问题在于您选择的隐藏层和输出层隶属函数 ,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
in training的全范围,而不是像以前那样只使用上半部分。现在,就像上面一样,您需要制作一些额外的数据来训练:
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 Solution(似乎更直观)
如果您有 Octave,它基本上是 MATLAB 的免费和开源版本,您可以使用以下nnet
包生成所需的网络。请注意,该nnet
包使用先前(已停产)的 MATLAB 语法定义每个输入范围的矩阵 ( Pr
),然后是每层中节点数的向量 ( 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]
非常接近[0 1 1 1]
我们期望得到的结果。