【问题标题】:Back Propagation Neural Network Hidden Layer all output is 1反向传播神经网络隐藏层所有输出为 1
【发布时间】:2015-11-27 21:56:07
【问题描述】:

我已经创建了一个具有 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

【问题讨论】:

  • 请添加minimal reproducible example 详细说明您的代码。解释它为什么不起作用以及您希望它做什么。
  • 您会得到“隐藏层的输出始终为 1”这样的结果的主要原因是代码中的错误。为了更好地分析可能导致错误的原因,您需要展示您的代码。
  • 您好,感谢您的回复。我在帖子中添加了代码。
  • 正如@NeilSlater 所说,通常是一个错误。您是否试图使网络输出值 > 1?

标签: matlab neural-network


【解决方案1】:

我在您的代码中发现了一些需要修复的明显错误:

1) 初始化时没有负权重。这很可能会导致网络卡住。权重初始化应该是这样的:

weight_input_hidden = 0.2 * rand(numofInputNeurons, numofFirstHiddenNeurons) - 0.1;

2) 你没有实施偏见。这将严重限制网络的学习能力。你应该回到你的笔记并弄清楚,它通常被实现为在确定每一层的激活之前插入输入和激活向量/矩阵的额外列 1,并且应该有一个匹配的附加权重列。

3) 你的输出层增量是错误的。这一行

delta_final_output = learningRate * (targetRow - final_output) .* final_output .* (1 - final_output);

。 . .不是输出层激活的增量。它有一些额外的不想要的因素。

logloss objective function 和输出层中的 sigmoid 激活的正确增量是:

delta_final_output = (final_output - targetRow);

还有其他可能性,具体取决于您的目标函数,未显示。您的原始代码是 close 以纠正均方误差,如果您更改符号并删除 learningRate 的因素,这可能仍然有效

4) 你的隐藏层增量是错误的。这一行:

delta_hidden_output = learningRate * (hidden_output) .* (1-hidden_output) .* (delta_final_output * weight_hidden_output');

。 . .不是隐藏层激活的增量。由于某种原因,您乘以 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 个错误,我可能遗漏了一些。但我认为这已经足够了。

【讨论】:

  • 您好,感谢您的回复,它拯救了我,我是否知道当我的神经网络在多个时期减少误差并增加误差时这是正常的。谢谢
  • @TanK.Seang:在基本的梯度下降方法中,训练误差值可能会上下波动。一个好的模式是错误应该在开始时快速下降,然后可能会开始变化(有时上升,有时下降),但平均而言,在许多时期内仍然会变低。如果值开始持续上升,那么您可能会遇到学习率过高或错误等问题。
  • 再次感谢,我知道这是否也可能是因为我的训练数据不够好,无法分类?这是因为我的识别项目是从图像中识别 24 个静态 ASL 标志,并且某些形状可能相似,所以这是我的疑问。非常感谢
  • 因为我只使用原始像素值,所以我认为这可能是由于我的训练数据。因为我尝试了单隐藏层和双隐藏层也发生了同样的情况,错误值不断增加和下降一段时间。
  • 您可以尝试标准化您的训练数据。去掉所有像素的平均值,然后除以标准差(基于训练数据中的值)。此外,您很快就会想要开始拆分训练数据,以便更好地衡量网络的总体表现,而不仅仅是在训练集上。你在学习课程吗?这些事情通常会在您进行时进行解释。
猜你喜欢
  • 2019-07-04
  • 1970-01-01
  • 2016-10-10
  • 2016-09-21
  • 2015-03-03
  • 2012-02-21
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多