反卷积公式的理解

卷积基础已知。
定义
i 输入尺寸
o 输出尺寸
p 填充padding
s 步长,这里面似乎应该解释为放大倍数
k 卷积核大小

卷积操作尺寸计算公式为 o = (i +2p -k)/s +1
反卷积的计算公式
(1)如果 (i + 2p - k)%s= 0, 则关系为i= s(o-1)-2p+k,
(2)如果(i + 2p -k)%s!=0, 则关系为i=s(o-1)-2p+k+ (o+2p-k)%s
看了网上不少内容,介绍了很多反卷积的东西,但是没有解释这个公式的

简单的理解
算一下就知道,实际上式如其名,反卷积的公式就是卷积反过来,通过o加上参数去求i。第二种情况,式子中有个余数,就是考虑卷积过程中,多了个余数mod,由于最后一步不够长,没有用来生成o的尺寸,那么o反过去算i的时候,是没有算这个mod的,所以最后加上它。

更深的理解:
实际上卷积操作可以转化成两个矩阵相乘实现。把输入的二维矩阵拉成一列x,然后构造一个矩阵c,让c的每一行和x的一列相乘相当于一次卷积。如下图,44的矩阵,用33的卷积核,步长为1,padding =0,变成2*2的矩阵,可以转化成如下两个矩阵的相乘。
反卷积公式的理解
从这个角度也可以理解在神经网络中通过卷积得到下一层,实际上和全连接层乘以参数矩阵得到下一层类似,卷积层参数就相当特殊的稀疏权重矩阵的参数。

看网上很多内容加了上面一段,太菜,理解不到有什么和下面的反卷过程有什么关系,不过这个内容本身挺有意义的。

根据卷积的特点来考虑反卷积,卷积的时候是考虑x的kk个相邻像素之间的相关性,利用卷积核,生成一个特征,或者说合成一个更高级的像素,然后跨过s步继续合成下一个像素,最后形成y。反过来看,首先想到的是y的1个像素生成kk个x的像素,但是实际上y的相邻像素之间也是有相关性的,并且根据卷积的形成过程,y的两个像素A,B对应到x的小矩阵Ax,Bx,是有重合的。所以这个反向过程也是一种卷积的操作,根据y相邻像素,合成x的像素,并且x的像素也具有相关性。所以反卷积也应该是一种卷积操作。
关于跨步stride,正向卷积的时候,主要通过跨步缩小y的尺寸,那么反卷积的时候,不可能跨步,跨步是减小尺寸,不是增大,跨步之后的尺寸字才能≤x,那么怎么办呢。想到扩大原来的矩阵,就是填充。怎么填充呢?不能直接在边上填充。得想到原来y左上角的像素是和x左上角的像素对应起来的,如果只是在边缘填充,那么不能保持这种对应,y左上角的像素只能对应到x中间的像素。考虑跨步的时候是ss的像素区域变成了1个像素,这里的填充的时候就在每个像素的周围填充像素,也就是1个像素变成ss个像素,如下图,就是没两行/列像素之间,填充s-1行/列。然后反卷积的跨步长度取1进行卷积,就能保证这种相关性了。这个stride应该称作放大倍数更好,现在的很多代码平台参数是称它为跨步,所以从跨步的角度来解释应该是这样的。实际上直接理解成放大倍数应该更好吧。
反卷积公式的理解
考虑stride,填充y,y的尺寸变成了s(o - 1) +1

再考虑padding,卷积中关于padding的作用,反卷积过程中这个padding作用大概类似吧,不然没必要加。这里加上padding的尺寸=为了对y做卷积之后尺寸能还原成x的大小即可。代入最上面的知道其他参数,由o求i公式一,即有:
s(o-1)+1+2p’-(k-1) = i = s(o-1)-2p+k
可得p’ = k - p -1,
有余数的时候对应加上就行
综上,反卷积的时候,在输入矩阵行/列中间插入s-1行/列,然后加上p’宽的padding,然后做s=1,核为k的卷积就完了。