我知道反向传播使用梯度并将其传递回神经网络以更新权重。但是,中层的权重具体是如何更新的呢?非输出层是否使用与输出层相同的梯度来更新权重,还是它们有不同的梯度来更新权重?
回答:
在每一层中,你的神经网络会反复进行以下中间计算:
z[l] = a[l] * w[l] + b[l]a[l+1] = f[l](z[l])
其中a[0]是你输入到神经网络的原始数据。z[l]是前一层激活a[l]的加权和(记住a[0]是输入),然后是第l层的权重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]如果,E := np.mean(np.sum(.5 * (a[2] - Y)**2, axis=1), axis=0)那么:dE/da[2] = (a[2] - Y)对于da[2]/dz[1],记住a[l+1] = f[l](z[1]):da[2]/dz[1] = df[l](z[1])最后:dz[1]/dw[1] = a[1]dE/dw[0] = (a[2] - Y) * df[l](z[1]) @ a[1]
其中,*是逐元素乘法,@是标准的矩阵乘法。现在,有不同的方法来初始化权重矩阵和组织输入矩阵以进行小批量梯度下降,因此上述内容仍需一些工作。通常你需要转置a[1]和/或将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]其中dE/da[2] * da[2]/dz[1]是共用的,被称为d[1],也就是输出层的delta。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]可能需要根据你设计网络的方式进行转置等,但计算方法已经给出。
长话短说,这只是反复应用链式法则。对于第[i]层,你将从下一层得到某个delta 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]
并从最后一层到第一层重复此操作。我希望这能澄清问题。