🍁🍁🍁图像分割实战-系列教程 总目录
有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
deeplab系列算法概述
deeplabV3+ VOC分割实战1
deeplabV3+ VOC分割实战2
deeplabV3+ VOC分割实战3
deeplabV3+ VOC分割实战4
deeplabV3+ VOC分割实战5
本项目的网络结构在network文件夹中,主要在modeling.py和_deeplab.py中:
modeling.py:指定要用的骨干网络是什么
_deeplab.py:根据modeling.py指定的骨干网络构建实际的网络结构
7、_deeplab.py的 ASPP类
ASPP,Atrous Spatial Pyramid Pooling,空洞空间卷积池化金字塔
class ASPP(nn.Module):
def __init__(self, in_channels, atrous_rates):
super(ASPP, self).__init__()
out_channels = 256
modules = []
modules.append(nn.Sequential(
nn.Conv2d(in_channels, out_channels, 1, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True)))
rate1, rate2, rate3 = tuple(atrous_rates)
- 定义了一个名为 ASPP 的类,继承自 PyTorch 的 nn.Module 基类
- ASPP 类的构造函数,接收输入通道数 in_channels 和一组膨胀率 atrous_rates 作为参数
- 调用基类的构造函数来正确初始化 ASPP 类
- 定义 ASPP 模块的输出通道数
- 初始化一个空的模块列表,用于存放构成 ASPP 的不同组件
- 添加一个执行序列模块到 modules 列表
- 这个执行序列由 1x1 卷积
- 批量归一化
- ReLU激活组成
- 解包膨胀率
modules.append(ASPPConv(in_channels, out_channels, rate1))
modules.append(ASPPConv(in_channels, out_channels, rate2))
modules.append(ASPPConv(in_channels, out_channels, rate3))
modules.append(ASPPPooling(in_channels, out_channels))
self.convs = nn.ModuleList(modules)
self.project = nn.Sequential(
nn.Conv2d(5 * out_channels, out_channels, 1, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True),
nn.Dropout(0.1), )
- 对膨胀率rate1添加一个ASPPConv空洞卷积层到 modules
- 对膨胀率rate2添加一个ASPPConv空洞卷积层到 modules
- 对膨胀率rate3添加一个ASPPConv空洞卷积层到 modules
- 添加一个 ASPPPooling 层到 modules
- 将 modules 列表转换为 nn.ModuleList,modules 是python的list数据类型,将其转换成对应的pytorch的数据类型
- 定义一个名为project 的执行序列,这个执行序列包含
- 一个1*1的二维卷积
- 一个批量归一化
- 一个ReLU 激活
- 一个 Dropout
def forward(self, x):
res = []
for conv in self.convs:
res.append(conv(x))
res = torch.cat(res, dim=1)
return self.project(res)
- ASPP 类的前向传播函数
- 初始化一个空列表,用于存放不同卷积层的输出
- 遍历 self.convs 中的每个卷积层
- 将每个卷积层对输入 x 的处理结果添加到 res 列表
- 将 res 列表中的所有输出在特征通道维度(dim=1)上进行拼接操作
- 将连接后的结果传递给投影层 self.project,并返回最终结果
8、_deeplab.py的 ASPPConv类
class ASPPConv(nn.Sequential):
def __init__(self, in_channels, out_channels, dilation):
modules = [
nn.Conv2d(in_channels, out_channels, 3, padding=dilation, dilation=dilation, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True)
]
super(ASPPConv, self).__init__(*modules)
这里是一个单独的模块,只有定义,也就是说只有在构建网络时使用构造函数才会使用这个类,可以多次调用,每次都是一个二维卷积、批归一化、ReLU激活。
这里的卷积实际上就是deeplab非常核心的空洞卷积,仅仅只有两个参数与一般卷积不同,那就是指定了padding=dilation
和dilation=dilation
9、_deeplab.py的 ASPPPooling类
class ASPPPooling(nn.Sequential):
def __init__(self, in_channels, out_channels):
super(ASPPPooling, self).__init__(
nn.AdaptiveAvgPool2d(1),
nn.Conv2d(in_channels, out_channels, 1, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True))
def forward(self, x):
size = x.shape[-2:]
x = super(ASPPPooling, self).forward(x)
return F.interpolate(x, size=size, mode='bilinear', align_corners=False)
- 定义了一个名为
ASPPPooling
的类,继承自 PyTorch 的nn.Sequential
ASPPPooling
类的构造函数,接收in_channels
、out_channels
参数- 调用基类的构造函数来初始化序列模块,包含4个模块:
- 一个自适应平均池化层,将输入的每个通道池化为 1x1 的输出,实现全局平均池化
- 一个 1x1 卷积层,用于调整通道数
- 一个批量归一化
- 一个ReLU激活函数
- 定义前向传播函数
- 存储输入
x
的高度和宽度 - 基类的
forward
方法执行序列中的池化、卷积、归一化和激活操作 - 将处理后的特征图
x
上采样回原始的空间维度,这里使用双线性插值进行上采样。
总体来说,ASPPPooling
类实现了一个全局平均池化操作,随后通过 1x1 卷积调整通道数,并进行上采样以匹配原始输入的空间尺寸。这种处理方式有助于在 DeepLabV3+ 模型中捕获全局上下文信息,对于提升分割精度非常重要。
deeplab系列算法概述
deeplabV3+ VOC分割实战1
deeplabV3+ VOC分割实战2
deeplabV3+ VOC分割实战3
deeplabV3+ VOC分割实战4
deeplabV3+ VOC分割实战5