gpt4 book ai didi

neural-network - 弹性传播的实现

转载 作者:行者123 更新时间:2023-12-04 05:02:55 28 4
gpt4 key购买 nike

目前我正在尝试为我的网络实现弹性传播。我是基于 encog 实现来做这件事的,但有一件事我不明白:

The documentation对于 RPROP 和 iRPROP+ 表示当变化 > 0 时: weightChange = -sign(gradient) * delta

The source code在第 298 行和第 366 行没有减号!

因为我认为两者在某些情况下都是正确的:为什么两者之间存在差异?

关于梯度:我在输出层中使用 tanh 作为事件。这是梯度的正确计算吗?

gradientOutput = (1 - lastOutput[j] * lastOutput[j]) * (target[j] - lastOutput[j]);

最佳答案

在重新阅读相关论文并在教科书中查找后,我认为 encog 的文档在这一点上是不正确的。为什么不通过在源代码中临时添加减号来尝试一下?如果您使用相同的初始权重,鉴于文档是正确的,您应该得到完全相同的结果。但最终,重要的是您如何使用 weightUpdate 变量。如果文档的作者习惯于从权重中减去 weightUpdate 而不是添加它,这将起作用。

编辑 :我重新审视了我原来的答案中关于梯度计算的部分。

首先,这里简要说明如何想象输出层中权重的梯度。首先,您计算输出和目标值之间的误差。

您现在要做的是“责备”前一层中活跃的那些神经元。想象一下输出神经元说“好吧,我这里有一个错误,谁负责?”。负责的是前一层的神经元。根据输出与目标值相比太小或太大,它将根据它们的活跃程度增加或减少前一层中每个神经元的权重。

x 是隐藏层中神经元的激活。

o 是输出神经元的激活。

φ 是输出神经元的激活函数,φ' 是它的导数。

编辑 2 : 更正了下面的部分。添加了反向传播的矩阵样式计算。

每个输出神经元 j 的误差为:

(1) δout, j = φ'(oj)(t - oj)

连接隐藏神经元 i 和输出神经元 j 的权重梯度:

(2) 梯度, j = xi * δout, j

每个隐藏神经元 i 的反向传播误差,权重为 w:

(3) δhid, i = φ'(x)*∑wi, j * δout, j

通过重复应用公式 2 和 3,您可以反向传播到输入层。

写成循环 ,关于一个训练样本:

每个输出神经元 j 的误差为:

for(int j=0; j < numOutNeurons; j++) {
errorOut[j] = activationDerivative(o[j])*(t[j] - o[j]);
}

连接隐藏神经元 i 和输出神经元 j 的权重梯度:
for(int i=0; i < numHidNeurons; i++) {
for(int j=0; j < numOutNeurons; j++) {
grad[i][j] = x[i] * errorOut[j]
}
}

每个隐藏神经元 i 的反向传播误差:
for(int i=0; i < numHidNeurons; i++) {
for(int j=0; j < numOutNeurons; j++) {
errorHid[i] = activationDerivative(x[i]) * weights[i][j] * errorOut[j]
}
}

在没有卷积或类似的完全连接的多层感知器中,您可以使用 标准矩阵运算 ,这要快得多。

假设您的每个样本都是输入矩阵中的一行,列是其属性,您可以像这样通过网络传播输入:
activations[0] = input;
for(int i=0; i < numWeightMatrices; i++){
activations[i+1] = activations[i].dot(weightMatrices[i]);
activations[i+1] = activationFunction(activations[i+1]);
}

反向传播然后变成:
n = numWeightMatrices;
error = activationDerivative(activations[n]) * (target - activations[n]);
for (int l=n-1; l >= 0; l--){
gradient[l] = activations[l].transposed().dot(error);
if (l > 0) {
error = error.dot(weightMatrices[l].transposed());
error = activationDerivative(activations[l])*error;
}
}

我在上面的解释中省略了偏置神经元。在文献中,建议将偏置神经元建模为每个激活矩阵中的附加列,该矩阵始终为 1.0。您将需要处理一些切片分配。使用矩阵反向传播循环时,不要忘记在每一步之前将偏置位置处的误差设置为0!

关于neural-network - 弹性传播的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15899579/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com