本文实现了使用pytorch搭建DeepLab。算是第一批采用Pytorch的吧,到目前为止,网上还没有类似的实现。
DeepLab简介
DeepLab文章的下载地址:https://arxiv.org/abs/1606.00915
该文章的主要思想之一:
提出了Atrous convolution(带孔卷积)。
扩大视野但不增加计算量。
所谓的带孔卷积,就是在卷积核之间加上0。rate参数为2(torch中对应的参数为dilation)的示意图如下
rate = 2就是在原卷积核相邻两个元素之间补上一个0,假设原卷积核为3x3,rate = 2的带孔卷积核的大小就为3+(3-1) × (rate-1)=5
。
下图是不同rate的带孔卷积。
以rate = 12
为例,带孔卷积的核的大小为:3+(3-1)x(12-1)=25
,即新卷积核的大小为:25*25
。
总的来说,对于rate=r
的带孔卷积,在连接着的卷积核元素间插入r-1
个元素。因此,扩展后的卷积核大小为$k_{new}=k+(k-1)(r-1)$。
pytorch实现deeplab
笔者主要目的是实现一下不同视野的concat过程。
在torch中,卷积函数如下:
其中的dilation参数就是带孔卷积的参数(也就是tensorFlow下的rate),默认情况下为1,就是普通的卷积,所以带孔卷积只需要修改这个参数就可以了。
比如说,我们已经写好了不同的视野下的卷积,然后需要将他们的feature map叠加起来,torch中使用torch.cat(inputs, dimension=0)
函数来进行叠加。torch的参数一般是四个维度的:[n_batch_size, n_feature_map, height, weight]
,所以参数中的dimension = 1
就是对feature map
叠加。代码如下:
|
|
叠加的这一步非常容易出错,原因在于,要求叠加的所有图片大小是一样的。而视野不同导致的卷积核的大小不同,也会导致最终输出的图像大小的变化,因此,需要恰当的调整zero-padding的数目来使得最终输出图像的大小保持一致。
另外稍微提一下,全连接层的输入向量大小的确定方法。全连接层是将上一步所得到的图像reshape为一个一维的向量之后,作为它的输入,因此,输入向量的长度为: in_channels = nFeatureMap * height * weight
。
网络整体代码如下: