【语义分割系列】一图讲解FCN16s实现过程。对照着pytorch代码讲解的。

     自己的学习笔记,怕忘。哈哈 感觉非常适合新手 将理论和代码能够结合到一起看还是很舒服的。 

    看了下fcn的代码和理论。这里就以FCN16s为例讲解,16s清晰了, 8s 与32s  只是在此基础上减,加而已了。

我看的代码是一VGG16为主干网络。关键步骤的解释在下图中已标记清晰,对照其他主干网络代码看也都能看的通。

FCN16s说白了就是 将 1/32图的预测结果做反卷积(上采样双线性插值即可),变成1 /16图。然后再将1 /16图池化层结果做预测,并与前的1/32图

结果做加法。最终得到的是加强版的1/16图的预测结果,再将其反卷积获得原图大小得到最终结果。

 

个过程是看代码才把这个图理顺清楚。所以啊,理解什么算法,最重要的还是看代码 看代码 看代码。

下面把代码贴出来一起看得了。

贴一段fcn16S的代码。

class FCN16(nn.Module):

    def __init__(self, num_classes):
        super().__init__()

        feats = list(models.vgg16(pretrained=True).features.children())
        self.feats = nn.Sequential(*feats[0:16])#卷积加池化和relu进行了三次 得到的是1 /8的池化图
        self.feat4 = nn.Sequential(*
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用PaddlePaddle实现FCN16s模型: ```python import paddle import paddle.nn as nn class FCN16s(nn.Layer): def __init__(self, num_classes=21): super(FCN16s, self).__init__() # 第一段 self.conv1_1 = nn.Conv2D(in_channels=3, out_channels=64, kernel_size=3, padding=100) self.relu1_1 = nn.ReLU() self.conv1_2 = nn.Conv2D(in_channels=64, out_channels=64, kernel_size=3, padding=1) self.relu1_2 = nn.ReLU() self.pool1 = nn.MaxPool2D(kernel_size=2, stride=2, ceil_mode=True) # 第二段 self.conv2_1 = nn.Conv2D(in_channels=64, out_channels=128, kernel_size=3, padding=1) self.relu2_1 = nn.ReLU() self.conv2_2 = nn.Conv2D(in_channels=128, out_channels=128, kernel_size=3, padding=1) self.relu2_2 = nn.ReLU() self.pool2 = nn.MaxPool2D(kernel_size=2, stride=2, ceil_mode=True) # 第三段 self.conv3_1 = nn.Conv2D(in_channels=128, out_channels=256, kernel_size=3, padding=1) self.relu3_1 = nn.ReLU() self.conv3_2 = nn.Conv2D(in_channels=256, out_channels=256, kernel_size=3, padding=1) self.relu3_2 = nn.ReLU() self.conv3_3 = nn.Conv2D(in_channels=256, out_channels=256, kernel_size=3, padding=1) self.relu3_3 = nn.ReLU() self.pool3 = nn.MaxPool2D(kernel_size=2, stride=2, ceil_mode=True) # 第四段 self.conv4_1 = nn.Conv2D(in_channels=256, out_channels=512, kernel_size=3, padding=1) self.relu4_1 = nn.ReLU() self.conv4_2 = nn.Conv2D(in_channels=512, out_channels=512, kernel_size=3, padding=1) self.relu4_2 = nn.ReLU() self.conv4_3 = nn.Conv2D(in_channels=512, out_channels=512, kernel_size=3, padding=1) self.relu4_3 = nn.ReLU() self.pool4 = nn.MaxPool2D(kernel_size=2, stride=2, ceil_mode=True) # 第五段 self.conv5_1 = nn.Conv2D(in_channels=512, out_channels=512, kernel_size=3, padding=1) self.relu5_1 = nn.ReLU() self.conv5_2 = nn.Conv2D(in_channels=512, out_channels=512, kernel_size=3, padding=1) self.relu5_2 = nn.ReLU() self.conv5_3 = nn.Conv2D(in_channels=512, out_channels=512, kernel_size=3, padding=1) self.relu5_3 = nn.ReLU() self.pool5 = nn.MaxPool2D(kernel_size=2, stride=2, ceil_mode=True) # FCN层 self.fc6 = nn.Conv2D(in_channels=512, out_channels=4096, kernel_size=7) self.relu6 = nn.ReLU() self.drop6 = nn.Dropout(p=0.5) self.fc7 = nn.Conv2D(in_channels=4096, out_channels=4096, kernel_size=1) self.relu7 = nn.ReLU() self.drop7 = nn.Dropout(p=0.5) self.score_fr = nn.Conv2D(in_channels=4096, out_channels=num_classes, kernel_size=1) self.upscore = nn.Conv2DTranspose(in_channels=num_classes, out_channels=num_classes, kernel_size=32, stride=16, bias_attr=False) def forward(self, x): # 第一段 x = self.conv1_1(x) x = self.relu1_1(x) x = self.conv1_2(x) x = self.relu1_2(x) x = self.pool1(x) # 第二段 x = self.conv2_1(x) x = self.relu2_1(x) x = self.conv2_2(x) x = self.relu2_2(x) x = self.pool2(x) # 第三段 x = self.conv3_1(x) x = self.relu3_1(x) x = self.conv3_2(x) x = self.relu3_2(x) x = self.conv3_3(x) x = self.relu3_3(x) x = self.pool3(x) pool3_out = x # 第四段 x = self.conv4_1(x) x = self.relu4_1(x) x = self.conv4_2(x) x = self.relu4_2(x) x = self.conv4_3(x) x = self.relu4_3(x) x = self.pool4(x) pool4_out = x # 第五段 x = self.conv5_1(x) x = self.relu5_1(x) x = self.conv5_2(x) x = self.relu5_2(x) x = self.conv5_3(x) x = self.relu5_3(x) x = self.pool5(x) # FCN层 x = self.fc6(x) x = self.relu6(x) x = self.drop6(x) x = self.fc7(x) x = self.relu7(x) x = self.drop7(x) x = self.score_fr(x) x = self.upscore(x, output_size=pool4_out.shape[-2:]) pool4_out = 0.01 * pool4_out x = paddle.add(x, pool4_out) x = self.upscore(x, output_size=pool3_out.shape[-2:]) pool3_out = 0.0001 * pool3_out x = paddle.add(x, pool3_out) x = self.upscore(x, output_size=x.shape[-2:]) return x ``` 这里使用了PaddlePaddle的`nn`模块实现FCN16s模型。在forward方法中,我们按照FCN16s网络结构的方式依次进行了前向计算。其中,我们使用了反卷积(`Conv2DTranspose`)对特征图进行上采样,并使用了跳跃连接(skip connection)将浅层特征和深层特征结合起来进行分割任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值