仅用于学习目的,参考网上资源较多,若未注明请联系,感谢
bilinear
双线性插值是目前在语义分割中用的比较多的一种方式,比如FCN中就是用的这种方法。
这种方法特点是不需要进行学习,运行速度快,操作简单。只需要设置好固定的参数值即可,设置的参数就是中心值需要乘以的系数。
一个简单的例子可以参考如下(来自互联网):
依照代码简单分析就可以发现bilinear的具体计算流程如下:
(1) 64%2 == 0,所以center的坐标为(31.5, 31.5),note在python中下标从0开始
(2) 计算出一个64x64的矩阵,每个位置根据代码所示填数,其实就是线性规则
(3) 二维来看,将score_fr层的16x16的每一个位置的坐标放在31.5位置,也就是在相邻元素之间插入32个位置,周边补充32个位置,不同元素对插入的不同值有影响,则相互叠加,最后将原来的16x16的元素移除,也就形成了32x17 = 544,也就是具体upscore层算出来的值
放点东西,形象表示一下:
32个元素 [16x16中的(0,0)元素] 32个元素 [16x16中的(0,1)元素] 32个元素 …
其中,中括号中的元素不可见
Deconvolution
Deconvolution是目前争议比较多的方法,主要是名字上的争议,由于实现上采用转置卷积核的方法,所以有人说应该叫(transposed convolution),但是思想上是为了还原原有特征图,类似消除原有卷积的某种效果,所以叫反卷积(deconvolution). Caffe中叫deconvolution,这里就继续沿用这个名字.
要理解deconv,要先了解conv的具体是实现方式,在实现过程中,为了使卷积运算更快的执行,通常转化为矩阵乘法进行处理(因为矩阵乘法有一些加速计算库)。卷积计算通常的两种实现方式是:在caffe中使用im2col的方法,在其他的地方使用toeplitz matrix(托普利兹矩阵)进行实现。
具体例子参看知乎https://www.zhihu.com/question/43609045?sort=created
为了更容易地实现deconvolution,直接使deconv的前向传播模拟conv的反向传播,当然,这里只是为了保证尺寸大小互逆,并不能保证值的还原。具体思路可以参考这篇博客http://blog.csdn.net/zsz_shsf/article/details/53201669。
做几个小例子帮助理解:
(1) 关于第一节中bilinear的在caffe中使用deconvolution进行实现,上节的bilinear论述过程中使用固定值计算的方法,本节从deconv可视化计算的角度进行理解,https://github.com/vdumoulin/conv_arithmetic
63个元素 [16x16中的(0,0)元素] 31个元素 [16x16中的(0,1)元素] 31个元素
其中,中括号中的元素可见
对以上过程进行卷积运算,注意这里stride 使用1, 最终输出大小为(63+32x15+64-64)/1 + 1 = 544
这里可以脑补一下计算过程,相当于第一节中的手算叠加
(2) 对bilinear使用转置运算进行实现,先将64x64的卷积核转化为toeplitz matrix,然后转置,得到544x544,256的矩阵,然后将score_fr转化为1, 256的矩阵,两者矩阵乘法,得到544x544的最终结果,具体过程脑补吧
unpooling
也就是反池化,不需要学习,用的不是太多,参考论文Visualizing and Understanding Convolutional Networks,还有SegNet和DeconvNet
简单原理:在池化过程中,记录下max-pooling在对应kernel中的坐标,在反池化过程中,将一个元素根据kernel进行放大,根据之前的坐标将元素填写进去,其他位置补0
实现代码可以看SegNet的实现
引用 https://blog.csdn.net/u014451076/article/details/79156967/
网友评论