图源自网络,后面会出现多次。为了方便萌新看懂,本文会指出每个部分对应代码的哪一段。
PS:该框架图只表示大概流程,具体数字在代码中会有变动。
一般都是在终端运行python tools/train.py ./configs/你的配置文件 --work-dir 指定的工作目录
执行命令
要调试代码,就要在pycharm里debug它,所以不能用终端的命令。
进入mmsegmentation/tools/train.py
parse_args()是个函数,定义在111行前面。
进入函数,发现用的是args = parser.parse_args()
接收终端的命令
把它注释掉,改成新的命令。
其中 ../configs/MySP/deeplabv3plus_r101-d8_512x512_20k_MySP-Test.py
是配置文件
--work-dir ../work/Test
自建的工作区,是用来试错的输出。
查看该配置文件的详细配置
python tools/print_config.py ./configs/MySP/deeplabv3plus_r101-d8_512x512_20k_MySP-Test.py
发现decode_head是DepthwiseSeparableASPPHead,就去找它
在mmsegmentation/mmseg/models/decode_heads/sep_aspp_head.py
里找到了该类
这里就是要改的地方 ,直接看forword函数
这两个绿虫子都可以点,开始调试。就在train里开始调试就行。
经过了transform_inputs函数后,进了decode_head.py。直接是else情况,in_index=3,说明是最高级的feature map(卷的最深产生的)
aspp_outs是x产生的。image_pool里是1x1卷积,通道数由2048改为512
x给了aspp_modules,产生了其余四个列表。extend后,内有5个列表
对应图中:
bottleneck做了一个1*1的卷积,output就是绿块
对应:
还记得最开始的inputs吗?inputs[0]就是低级特征
回看inputs
inputs[0]对应这里:
c1_bottleneck也是1*1卷积,得到的c1_output就是粉块
Output(绿色高级语义信息)经过2倍上采样后,128*128
框架图里是4倍上采样,但它只表示大概过程,这里代码其实做的是2倍上采样,都是可以改的
对应:
由于我做的是二分类问题,所以最后通道为2。
到这里就跑完了原有的deeplabV3+的流程。
结束了吗?NO
最后的output是128*128,没有那个4倍上采样,return后在encoder_decoder.py里做的最后的上采样。(这里只做补充说明,不影响加入Attention机制)
SE(压缩激励)的介绍网上有很多,此处不再赘述
加入位置:(可以改,不固定)
代码:
class SELayer(nn.Module):
def __init__(self, channel, reduction=16):
super(SELayer, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channel, channel // reduction, bias=False),
nn.ReLU(inplace=True),
nn.Linear(channel // reduction, channel, bias=False),
nn.Sigmoid()
)
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, c)
y = self.fc(y).view(b, c, 1, 1)
return x * y.expand_as(x)
SE代码也是我在网上找的,改了一点就加进来了,可见注意机制还是好用的。
"""se"""
reduction = 16
self.se1 = SELayer(10 * c1_in_channels, reduction)
self.se2 = SELayer(c1_in_channels, reduction)
"""SE"""
aspp_outs = self.se1(aspp_outs)
"""SE"""
low_feat = self.se2(inputs[0]) # low_feat是SE增强后的低级特征
c1_output = self.c1_bottleneck(low_feat) # 粉色
# c1_output = self.c1_bottleneck(inputs[0]) # 原来的代码,注释了
照猫画虎,加入ECA机制进行对比。最后的mIoU是 加入ECA > 加入SE > 不使用注意机制
可见加入注意力机制后,效果还是可以的。