语义分割|学习记录(5)Pytorch官方实现的FCN网络结构


前言

Pytorch官方实现的FCN和当年论文的结构图稍有不同,因为现在有了更多的backbone的选择,而且应用了膨胀卷积技术。

FCN网络结构

下图是Pytorch官方实现的FCN网络结构:

请添加图片描述
下图是Resnet的网络结构:
请添加图片描述
对比两个网络进行分析:FCN网络的backbone选择的是Resnet50 backbone,在这一部分的蓝色虚线框的前面的结构和Resnet是一模一样的。

重点关注layer3和layer4的部分。FCN的layer3和layer4对应于Resnet的conv4_x和conv5_x。区别在于:

  • Resnet的conv4_x中的6个残差结构对应FCN的layer3中的1个Bottleneck1和5个Bottleneck2。
  • Resnet的conv5_x中的3个残差结构对应FCN的layer4中的1个Bottleneck12个Bottleneck2

接下来我们重点关注一下Bottleneck1Bottleneck2的结构:

  • Bottleneck1对应残差结构中的虚线结构,在这里和resnet中的区别在于它将捷径分支上的 1 ∗ 1 1*1 11卷积的步距改成了1。因此在这里并没有进行下采样操作,语义分割中下采样倍率过大还原会原图效果会受影响。另外在 3 ∗ 3 3*3 33卷积核处的步距也改成了1,并且引入了膨胀卷积
  • Bottleneck2同样也是引入了膨胀卷积。

接下来再来看一下FCN Head部分:

  • 经过一个3*3的卷积层,输入特征图的channel数被调整为原来的1/4变为512.
  • 通过一个Dropout层
  • 再通过一个1*1卷积层,调整特征层的channel为类别个数。
  • 最后通过一个双线性插值的方法,还原回原来的大小。

另外在右侧还有一个FCN Head,官方给出的理由:防止误差梯度没办法传递到网络浅层,所以这里引入了辅助分类器。
训练的时候可以启用这个辅助分类器,都可以去试一下。在实际部署到真实环境的时候,我们只去利用output。

参考资料

up主霹雳吧啦Wz原视频

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现FCN语义分割的基本步骤如下: 1. 准备数据集:需要一个带有标注的语义分割数据集,可以使用PASCAL VOC2012、COCO等公开数据集,或者自己收集、标注数据。 2. 定义模型:FCN模型是基于CNN的,需要定义卷积层、反卷积层和池化层等。可以使用PyTorch提供的nn.Module类来定义模型。 3. 训练模型:使用数据集进行模型训练,可以使用PyTorch提供的DataLoader类来加载数据集,并使用PyTorch提供的优化器和损失函数进行训练。 4. 模型评估:训练完成后,需要对模型进行评估,可以使用IoU(Intersection over Union)等指标来评价模型的性能。 下面是一个简单的FCN模型实现示例: ```python import torch import torch.nn as nn import torch.nn.functional as F class FCN(nn.Module): def __init__(self, num_classes): super(FCN, self).__init__() # 卷积层1 self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=100) # 卷积层2 self.conv2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1) # 卷积层3 self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) # 卷积层4 self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1) # 卷积层5 self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1) # 卷积层6 self.conv6 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) # 卷积层7 self.conv7 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1) # 反卷积层1 self.deconv1 = nn.ConvTranspose2d(512, 512, kernel_size=3, stride=1, padding=1) # 反卷积层2 self.deconv2 = nn.ConvTranspose2d(512, 256, kernel_size=3, stride=1, padding=1) # 反卷积层3 self.deconv3 = nn.ConvTranspose2d(256, 128, kernel_size=3, stride=1, padding=1) # 反卷积层4 self.deconv4 = nn.ConvTranspose2d(128, 64, kernel_size=3, stride=1, padding=1) # 反卷积层5 self.deconv5 = nn.ConvTranspose2d(64, 32, kernel_size=3, stride=1, padding=1) # 反卷积层6 self.deconv6 = nn.ConvTranspose2d(32, num_classes, kernel_size=3, stride=1, padding=1) def forward(self, x): # 卷积层1 x = F.relu(self.conv1(x)) # 卷积层2 x = F.relu(self.conv2(x)) # 池化层1 x = F.max_pool2d(x, kernel_size=2, stride=2) # 卷积层3 x = F.relu(self.conv3(x)) # 卷积层4 x = F.relu(self.conv4(x)) # 池化层2 x = F.max_pool2d(x, kernel_size=2, stride=2) # 卷积层5 x = F.relu(self.conv5(x)) # 卷积层6 x = F.relu(self.conv6(x)) # 卷积层7 x = F.relu(self.conv7(x)) # 反卷积层1 x = F.relu(self.deconv1(x)) # 反卷积层2 x = F.relu(self.deconv2(x)) # 反卷积层3 x = F.relu(self.deconv3(x)) # 反卷积层4 x = F.relu(self.deconv4(x)) # 反卷积层5 x = F.relu(self.deconv5(x)) # 反卷积层6 x = self.deconv6(x) # 裁剪边缘 x = x[:, :, 19:19+x.size()[2], 19:19+x.size()[3]] return x ``` 训练和评估模型的代码可以参考PyTorch官方文档和示例。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值