反向传播神经网络隐藏层所有输出为1
Back Propagation Neural Network Hidden Layer all output is 1
每个人我都创建了一个具有 1600 个输入、一个具有不同数量的神经元节点和 24 个输出神经元的隐藏层的神经网络。
我的代码显示我可以减少每个时期的错误,但隐藏层的输出始终为 1。由于这个原因,调整后的权重总是对我的测试数据产生相同的结果。
我在 ANN 中尝试不同数量的神经元节点和学习率,并随机初始化我的初始权重。我使用 sigmoid 函数作为我的激活函数,因为我的输出在不同的输出中不是 1 就是 0。
请问隐藏层输出总是1的主要原因是什么,应该怎么解决?
这个神经网络的目的是识别字母表的 24 种手形,我在项目的第一阶段尝试强度数据。
我尝试了 30 个隐藏神经节点、100 个神经节点甚至 1000 个神经节点,但隐藏层的输出仍然是 1。由于这个原因,测试数据中的所有结果总是相似的。
我为我的网络添加了代码
谢谢
g = inline('logsig(x)');
[row, col] = size(input);
numofInputNeurons = col;
weight_input_hidden = rand(numofInputNeurons, numofFirstHiddenNeurons);
weight_hidden_output = rand(numofFirstHiddenNeurons, numofOutputNeurons);
epochs = 0;
errorMatrix = [];
while(true)
if(totalEpochs > 0 && epochs >= totalEpochs)
break;
end
totalError = 0;
epochs = epochs + 1;
for i = 1:row
targetRow = zeros(1, numofOutputNeurons);
targetRow(1, target(i)) = 1;
hidden_output = g(input(1, 1:end)*weight_input_hidden);
final_output = g(hidden_output*weight_hidden_output);
error = abs(targetRow - final_output);
error = sum(error);
totalError = totalError + error;
if(error ~= 0)
delta_final_output = learningRate * (targetRow - final_output) .* final_output .* (1 - final_output);
delta_hidden_output = learningRate * (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');
for m = 1:numofFirstHiddenNeurons
for n = 1:numofOutputNeurons
current_changes = delta_final_output(1, n) * hidden_output(1, m);
weight_hidden_output(m, n) = weight_hidden_output(m, n) + current_changes;
end
end
for m = 1:numofInputNeurons
for n = 1:numofFirstHiddenNeurons
current_changes = delta_hidden_output(1, n) * input(1, m);
weight_input_hidden(m, n) = weight_input_hidden(m, n) + current_changes;
end
end
end
end
totalError = totalError / (row);
errorMatrix(end + 1) = totalError;
if(errorThreshold > 0 && totalEpochs == 0 && totalError < errorThreshold)
break;
end
end
我发现您的代码中有一些明显的错误需要修复:
1)初始化时没有负权重这很可能会卡住网络。权重初始化应该是这样的:
weight_input_hidden = 0.2 * rand(numofInputNeurons, numofFirstHiddenNeurons) - 0.1;
2) 你还没有实现偏置。 这将严重限制网络的学习能力。你应该回到你的笔记并弄清楚,它通常被实现为在确定每一层的激活之前插入输入和激活 vectors/matrix 的额外列 1,并且应该有一个匹配的附加权重列.
3) 你的输出层delta是错误的。这一行
delta_final_output = learningRate * (targetRow - final_output) .* final_output .* (1 - final_output);
。 . .不是输出层激活的增量。它有一些额外的不需要的因素。
输出层 logloss objective function 和 sigmoid 激活的正确增量为:
delta_final_output = (final_output - targetRow);
还有其他可能性,具体取决于您的 objective 功能,未显示。您的原始代码是 close 以更正均方误差,如果您更改符号并删除 learningRate
的因子,它可能仍然有效
4) 你的隐藏层增量是错误的。 这一行:
delta_hidden_output = learningRate * (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');
。 . .不是隐藏层激活的增量。由于某种原因,您已经乘以 learningRate
(与其他增量相结合,这意味着您有一个 learningRate 平方因子)。
正确的增量是:
delta_hidden_output = (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');
5) 您的权重更新步骤需要调整以匹配对 (3) 和 (4) 的修复。 这些行:
current_changes = delta_final_output(1, n) * hidden_output(1, m);
需要进行调整以获得正确的符号和学习率乘数
current_changes = -learningRate * delta_final_output(1, n) * hidden_output(1, m);
这是通过查看代码得出的 5 个错误,我可能遗漏了一些。但我认为现在已经足够了。
每个人我都创建了一个具有 1600 个输入、一个具有不同数量的神经元节点和 24 个输出神经元的隐藏层的神经网络。 我的代码显示我可以减少每个时期的错误,但隐藏层的输出始终为 1。由于这个原因,调整后的权重总是对我的测试数据产生相同的结果。 我在 ANN 中尝试不同数量的神经元节点和学习率,并随机初始化我的初始权重。我使用 sigmoid 函数作为我的激活函数,因为我的输出在不同的输出中不是 1 就是 0。 请问隐藏层输出总是1的主要原因是什么,应该怎么解决? 这个神经网络的目的是识别字母表的 24 种手形,我在项目的第一阶段尝试强度数据。 我尝试了 30 个隐藏神经节点、100 个神经节点甚至 1000 个神经节点,但隐藏层的输出仍然是 1。由于这个原因,测试数据中的所有结果总是相似的。 我为我的网络添加了代码 谢谢
g = inline('logsig(x)');
[row, col] = size(input);
numofInputNeurons = col;
weight_input_hidden = rand(numofInputNeurons, numofFirstHiddenNeurons);
weight_hidden_output = rand(numofFirstHiddenNeurons, numofOutputNeurons);
epochs = 0;
errorMatrix = [];
while(true)
if(totalEpochs > 0 && epochs >= totalEpochs)
break;
end
totalError = 0;
epochs = epochs + 1;
for i = 1:row
targetRow = zeros(1, numofOutputNeurons);
targetRow(1, target(i)) = 1;
hidden_output = g(input(1, 1:end)*weight_input_hidden);
final_output = g(hidden_output*weight_hidden_output);
error = abs(targetRow - final_output);
error = sum(error);
totalError = totalError + error;
if(error ~= 0)
delta_final_output = learningRate * (targetRow - final_output) .* final_output .* (1 - final_output);
delta_hidden_output = learningRate * (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');
for m = 1:numofFirstHiddenNeurons
for n = 1:numofOutputNeurons
current_changes = delta_final_output(1, n) * hidden_output(1, m);
weight_hidden_output(m, n) = weight_hidden_output(m, n) + current_changes;
end
end
for m = 1:numofInputNeurons
for n = 1:numofFirstHiddenNeurons
current_changes = delta_hidden_output(1, n) * input(1, m);
weight_input_hidden(m, n) = weight_input_hidden(m, n) + current_changes;
end
end
end
end
totalError = totalError / (row);
errorMatrix(end + 1) = totalError;
if(errorThreshold > 0 && totalEpochs == 0 && totalError < errorThreshold)
break;
end
end
我发现您的代码中有一些明显的错误需要修复:
1)初始化时没有负权重这很可能会卡住网络。权重初始化应该是这样的:
weight_input_hidden = 0.2 * rand(numofInputNeurons, numofFirstHiddenNeurons) - 0.1;
2) 你还没有实现偏置。 这将严重限制网络的学习能力。你应该回到你的笔记并弄清楚,它通常被实现为在确定每一层的激活之前插入输入和激活 vectors/matrix 的额外列 1,并且应该有一个匹配的附加权重列.
3) 你的输出层delta是错误的。这一行
delta_final_output = learningRate * (targetRow - final_output) .* final_output .* (1 - final_output);
。 . .不是输出层激活的增量。它有一些额外的不需要的因素。
输出层 logloss objective function 和 sigmoid 激活的正确增量为:
delta_final_output = (final_output - targetRow);
还有其他可能性,具体取决于您的 objective 功能,未显示。您的原始代码是 close 以更正均方误差,如果您更改符号并删除 learningRate
4) 你的隐藏层增量是错误的。 这一行:
delta_hidden_output = learningRate * (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');
。 . .不是隐藏层激活的增量。由于某种原因,您已经乘以 learningRate
(与其他增量相结合,这意味着您有一个 learningRate 平方因子)。
正确的增量是:
delta_hidden_output = (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');
5) 您的权重更新步骤需要调整以匹配对 (3) 和 (4) 的修复。 这些行:
current_changes = delta_final_output(1, n) * hidden_output(1, m);
需要进行调整以获得正确的符号和学习率乘数
current_changes = -learningRate * delta_final_output(1, n) * hidden_output(1, m);
这是通过查看代码得出的 5 个错误,我可能遗漏了一些。但我认为现在已经足够了。