百度飞桨图像分割日打卡训练营之 PaddlePaddle 实现 DeepLab V3
课程链接:https://aistudio.baidu.com/aistudio/course/introduce/1767
本文图片代码来自以上课程
A.理论部分
DeepLab V3 相关论文 :Rethinking Atrous Convolution for Semantic Image Segmentation
1. DeepLab V3 网络框架
可以看到 DeepLab V3 使用 Resnet 作为 backbone,提取 feature map 之后以相比 DeepLab V2 改进的 ASPP 结构加 score 分类作为分割头,还原尺寸并输出
2. upgraded ASPP
其中改进后的 ASPP 结构如下图所示:
从 backbone 提出特征后,进行了四种操作:1x1卷积、dilation 分别为6、12、18的3x3空洞卷积以及 Adaptive pool + interpolation 的操作
当然实际实现过程中空洞卷积的操作可以自己调整,只要能 cover 自己数据集中特征的 scale 就好
提取出尺寸一样的 feature map 后把所有 feature map 进行 concat 操作(如图所示就是堆起来)
之后把堆起来的 feature 进行 1x1卷积降维,维度可以自己设,论文中为256
以上就是 upgraded ASPP 做的全部操作,下面解释一下空洞卷积和 Adaptive pool 的操作,毕竟朱老师上课专门讲了
3. Dilated Convolution
Dilated Convolution 空洞卷积如下图所示:
目的是扩大卷积操作的感受野,除了把 feature map 池化成多个尺度,另一个思路就是把卷积核的 kernal size 变成多个尺度啦
这里的做法是在卷积核中填 0 所以叫空洞卷积,这个 dilation 值在正常的卷积操作中是1,而图中这样子就是2,所以理解为卷积核中相邻元素的距离就好
4. Adaptive pool
Adaptive pool 是朱老师将 PSPNet 的时候讲的,所以这里贴 PSPNet 的课件图:
其实就是把任意尺寸输入 pool 成任意尺寸输出,至于是最大值池化还平均值池化在 API 中还是可以选的区别不大
这里的计算公式计算的是输出中元素 (i, j) 在原图 h/w 方向池化池的范围,floor 指向下取整,H 指的输入输出的尺寸,如果计算 w 方向的范围这里 i 改成 j
这个操作比较省计算量,这里加一个肯定收益大于成本
5. Muiti-Grid
Resnet 就不解释了玩过检测的都熟,这里朱老师也推荐换成 MobileNet 好训练一些。就加一下 DeepLab V3 在 Resnet 中做的 Muiti-Grid 的改进:
把 backbone 中的卷积也改成不同 dilation 指的空洞卷积了,而这个指是作者试验出来效果比较好的值
B. 代码
O嗑诶,下面上代码:
1. main
def main():
place = paddle.fluid.CUDAPlace(0)
with fluid.dygraph.guard(place):
x_data = np.random.rand(2, 3, 512, 512).astype(np.float32)
x = to_variable(x_data)
model = DeepLab(num_classes=59)
model.eval()
pred = model(x)
print(pred.shape)
主函数,随机生成一个 (2, 3, 512, 512) 的 tensor,卷入 DeepLab V3