在之前的博客文章中,我试图解释以下几点
- 网络简介与数据处理
- 卷积运算
- RELU、MaxPooling和SoftMax
- 通过全连通层的反向传播
在这篇文章中,我将尝试介绍通过最大池和卷积层的反向传播。我们已经用我们的方式计算了梯度,直到第一个完全连接的层。通过下面的手绘图像,让?euro™再次参观该架构。
到目前为止,我们已经计算了平坦层的梯度。
我们现在需要计算神经网络睡觉处的梯度。
计算最大池化图层处的渐变
假设第一个完全连接层是最大池层的重塑版本,我们只需要在第一个完全连接层重塑梯度矩阵,回到最大池层的形状。相同的代码片段如下所示
delta_maxpool = delta_0.reshape(X_maxpool.shape)
计算卷积层的梯度
最大池化操作使用固定大小的滤镜来提取与过滤大小相同的图像区域中的最大像素值。此过滤使用两个用户定义的参数在图像中移动:Stride和过滤大小。
为了计算卷积层的梯度,我们需要将每个梯度元素移回卷积层中提取最大像素值的位置。
delta_conv = np.zeros(X_conv.shape)
for image in range(len(max_indices)):
indices = max_indices[image]
for p in indices:
delta_conv[image:image+1,p[1],p[2],p[3]] = delta_maxpool[image:image+1,p[5],p[6],p[7]]
delta_conv = np.multiply(delta_conv,dReLU(X_conv))
卷积过滤梯度的计算
现在我们已经找到了卷积层的梯度,接下来我们需要计算卷积过滤的梯度。然后,这将用于在每个学习步骤中优化过滤。
计算误差的简单伪码
设G是卷积层的梯度矩阵。它的维度为(1,2,24,24)。设i是Shape(1,1,28,28)的输入图像。
上面的伪代码是针对单个图像的,我们需要对整个批次重复该代码。
以下来自HackMD的GIF更好地解释了该过程HackMD
考虑到我们必须逐像素找出卷积过滤的梯度,这个过程将花费大量的时间和精力。解决此问题的一种方法是使用im2ol()函数。
快速计算卷积过滤梯度的伪码
设G为卷积运算后该层的梯度矩阵。它的形状是(1,2,24,24)。让卷积过滤的输入由i定义。它的形状为(1,1,28,28)。
下面的代码片段提供了重塑梯度矩阵的函数
def error_layer_reshape(error_layer):
test_array = error_layer
test_array_new = np.zeros((test_array.shape[1],test_array.shape[0]*test_array.shape[2]*test_array.shape[3]))
for i in range(test_array_new.shape[0]):
test_array_new[i:i+1,:] = test_array[:,i:i+1,:,:].ravel()
return test_array_new
找到卷积过滤的梯度的代码片段如下
X_batch_im2col = im2col(X=X_batch,conv1=conv1, stride=1, pad=0)
delta_conv = np.random.rand(10,2,24,24)
delta_conv_reshape = error_layer_reshape(delta_conv)
conv1_delta = (delta_conv_reshape@X_batch_im2col.T).reshape(2,1,5,5)
有用的资源
- 快速实现有线电视新闻网(CNN)
反馈
感谢您的阅读!如果您有任何反馈/建议,请在下面自由评论/给我发电子邮件至padhokshaja@gmail.com
下一篇帖子
把这一切放在一起Putting it all together
原创文章,作者:fendouai,如若转载,请注明出处:https://panchuang.net/2021/06/21/%e4%bd%bf%e7%94%a8numpy%e7%9a%84%e7%ae%80%e5%8d%95%e6%9c%89%e7%ba%bf%e7%94%b5%e8%a7%86%e6%96%b0%e9%97%bb%e7%bd%91%e7%ac%ac%e4%ba%94%e9%83%a8%e5%88%86%e9%80%9a%e8%bf%87%e6%9c%80%e5%a4%a7%e6%b1%a0/