神经网络中的反向传播如何改变权重

How are Weights Changed by Backpropagation in Neural Networks

所以我知道反向传播使用梯度并通过神经网络将它们传回以更新权重。但是中间层的权重究竟是如何更新的。非输出层是否使用与输出层相同的梯度,或者它们是否具有不同的梯度来更新权重?

在每一层中,您的神经网络都会一遍又一遍地进行以下中间计算:

z[l] = a[l] * w[l] + b[l]
a[l+1] = f[l](z[l])

其中 a[0] 是您对神经网络的原始输入。 z[l] 是前一个激活 a[l] 的加权和(记住 a[0] 是输入),l-th 层 w[l] 的权重然后加上 b[l] 这是偏差向量。然后通过在先前计算的 z 上应用激活函数(f[l](x) - 请记住,每一层可以有不同的激活函数)来计算当前层的激活。 这是你的前传球。你一遍又一遍地重复上面的步骤,你有多少层就多少层。

为了向后传播误差,您必须区分每个权重矩阵的成本函数,从最后一个到第一个:

dw[l], dw[l-1], ..., dw[1], dw[0]

让我们举个小例子。您有一个具有单个隐藏层和一个输出层的神经网络,因此您的输入有 a[0],z[0] 作为隐藏层上的加权部分,a[1] 作为隐藏层上的激活, z[1] 作为输出层的加权值,a[2] 作为网络对输入的猜测。隐藏层的权重也有 w[0],输出层的权重有 w[1]。最后当然还有 b[0] 表示隐藏,b[1] 表示输出偏差。

现在,要更新您的权重,您必须找到:

  • dE/dw[1]

  • dE/dw[0]

第一个是输出层的权重,第二个是隐藏层的权重。

dE/dw[0] := dE/da[2] * da[2]/dz[1] * dz[1]/dw[1]

If, E := np.mean(np.sum(.5 * (a[2] - Y)**2, axis=1), axis=0)
then:
dE/da[2] = (a[2] - Y)

For da[2]/dz[1], remember that a[l+1] = f[l](z[1]):
da[2]/dz[1] = df[l](z[1])

Finally:
dz[1]/dw[1] = a[1]

dE/dw[0] = (a[2] - Y) * df[l](z[1]) @ a[1]

其中,*是element-wise乘法,@是标准的well-known矩阵乘法。现在,有不同的方法来初始化权重矩阵和组织 mini-batch 梯度下降的输入矩阵,因此上述仍然需要一些工作。通常你必须转置 a[1] and/or 乘以 a[1].T 与其余部分。但是计算是这样的。 现在,对于隐藏层,事情继续进行:

dE/dw[0] := dE/da[2] * da[2]/dz[1] * dz[1]/da[1] * da[1]/dz[0] * dz[0]/dw[0]

Where dE/da[2] * da[2]/dz[1] is common and is called d[1] a.k.a the delta for the output layer.

dz[1]/da[1] = w[1]
da[1]/dz[0] = df[0](z[0])
dz[0]/dw[0] = a[0]

dE/dw[0] = d[1] @ w[1] * df[0](z[0]) * a[0]

又一次,w[1] 和 a[0] 可能需要调换,这取决于您如何设计网络,但计算是存在的。

长话短说,就是一遍又一遍地应用chain-rule。给定一个层 [i] 你将从下一层得到一些增量 d[i+1] ,然后你需要为当前层计算 dw[i] ,并为前一个 [i-1] 计算 d[i] - 第层:

d[i] = d[i+1] @ w[i+1] * df[i](z[i])
dw[i] = d[i] @ a[i]

并从最后到第一对网络中的所有层重复此操作。我希望一切都解决了。