图文+代码分析:caffe卷积层反向传播实现原理
参考博客:
http://lib.****.net/article/aiframework/62849
http://jermmy.xyz/2017/12/16/2017-12-16-cnn-back-propagation/
http://www.zhihu.com/question/58716267
https://blog.****.net/l297969586/article/details/79701522
https://blog.****.net/buyi_shizi/article/details/51512848
首先进行定义
卷积层输入:(bottom_data)
卷积层输出:(top_data)
在正向传播时,将进行预处理获得方便计算的矩阵形式bottom_data_col_buff,设为(caffe中有函数im2col用来完成这一操作,其逆向操作为col2im即从矩阵形式转换为原特征图形式)只考虑一个样本一个输入通道一个输出通道的情况如下(caffe中对多样本多输入输出通道的情况在最后说明):
示例中卷积核size为3*3,stride=2,pad=1,bottom_data不包括四周填充的0。
则
卷积层输出位置处梯度:(top_diff)
卷积层输入位置处梯度:(bottom_diff)
权值梯度:(weight_diff)
偏置梯度:(bias_diff)
bottom_diff,weight_diff,bias_diff都通过top_diff反向传播计算
caffe代码实现如下:
下面详细介绍bottom_diff,weight_diff,bias_diff具体求解原理
1.bottom_diff
先计算,由于
是由
中的某一位置的值
赋值而来,
一般会在bottom_data_col_buff矩阵中多个位置进行赋值,设这种关系为
,一般有若干个
,则
,在caffe实现中只需要计算出各个位置的
,即获得与bottom_data_col_buff同维度的bottom_diff_col_buff,然后col2im还原为原始特征图尺寸即可。具体如下图:
caffe代码实现如下:
2.weight_diff
caffe代码实现如下:
3.bias_diff
,将所有的
求和即可,实现形式为top_diff与一个全1向量相乘:
caffe代码实现如下:
对于batchsize,输入通道,输出通道不等于1的情况讨论:
1. batchsize不等于1时,caffe对一个batch内每个样本分别处理计算,把结果相加
2.输入通道,输出通道不等于1时,weight,top_data表示为一个矩阵而不是向量,bias表示为一个向量而不是一个数值
设输入feature map 尺寸H1*W1*C1,卷积核大小kw*kh,输出feature map 尺寸H2*W2*C2
则在参与矩阵运算时
top_data,top_diff的尺寸为:C2行*(H1*W1)列
weight,weight_diff的尺寸为:C2行*(kw*kh*C1)列
bottom_data,bottom_diff的尺寸为:(kw*kh*C1)行*(H1*W1)列
bias,bias_diff的尺寸为:C2行*1列