neural-network - 弹性传播的实现

标签 neural-network

目前我正在尝试为我的网络实现弹性传播。我正在根据 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) 梯度i, 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/

相关文章:

python - TensorFlow:TypeError:不允许将 `tf.Tensor` 用作 Python `bool`

neural-network - Tensorflow tf.train.Saver 保存可疑的大 .ckpt 文件?

python - 为什么我的简单线性模型在数据集 g(X) 上学习阈值函数 f(x) = (x > 0) 但在 X 上表现不佳?

machine-learning - 寻找依赖于8个参数的近似函数

tensorflow - keras.model.predict 引发 ValueError : Error when checking input

artificial-intelligence - 可以使用感知器来检测手写数字吗?

neural-network - 预测数字序列中的模式

python - 来自 tensorflow 的用于图像分割的 sigmoid_cross_entropy 损失函数

machine-learning - 实例标准化与批量标准化

python - 理解 Michael Nielsen 的反向传播代码