图像分割-FCN全卷积神经网络(完整代码详解)

这篇具有很好参考价值的文章主要介绍了图像分割-FCN全卷积神经网络(完整代码详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

FCN全卷积神经网络

实现过程

全卷积

反卷积

FCN的三点创新

code

FCN全卷积神经网络

        FCN为深度学习在语义分割领域的开山之作,提出使用卷积层代替CNN中的全连接操作,生成热力图heat map而不是类别。

图像分割-FCN全卷积神经网络(完整代码详解)

实现过程

图像分割-FCN全卷积神经网络(完整代码详解)

图1  FCN网络结构

        包括全卷积过程以及反卷积过程。

        全卷积:使用经典的CNN网络作为骨架网络,例如:Vgg ResNet AlexNet等。本文使用Vgg16作为骨架网络,提取feature map。

        反卷积:将feature map上采样回去(通过转置卷积等上采样方式),恢复原图大小。

        然后,将预测结果和真实label的像素一一对应分类,也称为像素级分类。从而,将分割问题转化为分类问题。

全卷积

        蓝色指卷积操作,绿色为池化操作(图像宽高减半)。因此,按照图1,网络结构为:conv1(2层卷积)、pool1、conv2(2层卷积)、pool2、conv3(3层卷积)、pool3(向下输出预测的第一个分支)、conv4(3层卷积)、pool4(向下输出预测的第二个分支)、conv5(3层卷积)、pool5、conv6、conv7(向下输出的最后一个分支)。提取得到pool3 pool4 conv7,用于后面的特征融合以及反卷积操作。

反卷积

图像分割-FCN全卷积神经网络(完整代码详解)

        FCN分为FCN-32S,FCN-16s,FCN-8s三种网络结构。

        FCN-8s获取过程:conv7特征进行2倍上采样,与pool4融合,将融合后的进行2倍上采样,与pool3融合,最后进行8倍上采样得到原图大小的特征图。FCN-32s获取过程:conv7直接32倍上采样得到原图大小的特征图。

        由于FCN-8s综合较多层的特征,因此效果最好;而FCN-32s只使用了最后一层conv7上采样32倍进行预测,特征图较小,丢失了很多信息。

         注意:FCN-8s  (conv7 2倍上采样 + pool4) 2倍上采样 + pool3 -> 8倍上采样

        卷积过程中,特征经过pool操作,h w为奇数时,池化后的特征图的h1 w1不一定是原来h w的1/2,因此转置卷积2倍上采样后的shape与原来的h w有区别,因此需先通过插值方式torch.nn.functional.interpolate方式调整特征图大小,确保可以和上一层的特征融合。

   

FCN的三点创新

(1)全卷积:将传统CNN最后的全连接层转化为卷积层,实现分类器变为稠密预测dense prediction(即分割)。

具体操作:把原来CNN操作中的全连接变成卷积操作(见图1中conv6、conv7),此时图像的featureMap数量改变但是图像大小依然为原图的1/32,图像不再叫featureMap而是叫heatMap。

(2)上采样:由于骨架网络提取特征的过程采取了一系列下采样(池化操作),使得特征图大小减小,为了得到和原图大小一致的预测层,采用上采样(如转置卷积操作)

(3)跳跃结构:类似于ResNet,将不同层的feature map进行融合,在分类预测时可以综合多层信息。

code

FCN-8s实现过程,其他网络结构可直接修改FCN类中的forward函数实现。

import torch
from torch import nn
from torchvision.models import vgg16
import torch.nn.functional as F


def vgg_block(num_convs, in_channels, out_channels):
    """
    vgg block: Conv2d ReLU MaxPool2d
    """
    blk = []
    for i in range(num_convs):
        if i == 0:
            blk.append(nn.Conv2d(in_channels, out_channels, kernel_size=(3, 3), padding=1))
        else:
            blk.append(nn.Conv2d(out_channels, out_channels, kernel_size=(3, 3), padding=1))
        blk.append(nn.ReLU(inplace=True))
    blk.append(nn.MaxPool2d(kernel_size=(2, 2), stride=2))
    return blk


class VGG16(nn.Module):
    def __init__(self, pretrained=True):
        super(VGG16, self).__init__()
        features = []
        features.extend(vgg_block(2, 3, 64))
        features.extend(vgg_block(2, 64, 128))
        features.extend(vgg_block(3, 128, 256))
        self.index_pool3 = len(features)  # pool3
        features.extend(vgg_block(3, 256, 512))
        self.index_pool4 = len(features)  # pool4
        features.extend(vgg_block(3, 512, 512))  # pool5

        self.features = nn.Sequential(*features)  # 模型容器,有state_dict参数(字典类型)

        """ 将传统CNN中的全连接操作,变成卷积操作conv6 conv7 此时不进行pool操作,图像大小不变,此时图像不叫feature map而是heatmap"""
        self.conv6 = nn.Conv2d(512, 4096, kernel_size=1)   # conv6
        self.relu = nn.ReLU(inplace=True)
        self.conv7 = nn.Conv2d(4096, 4096, kernel_size=1)  # conv7

        # load pretrained params from torchvision.models.vgg16(pretrained=True)
        if pretrained:
            pretrained_model = vgg16(pretrained=pretrained)
            pretrained_params = pretrained_model.state_dict()  # state_dict()存放训练过程中需要学习的权重和偏置系数,字典类型
            keys = list(pretrained_params.keys())
            new_dict = {}
            for index, key in enumerate(self.features.state_dict().keys()):
                new_dict[key] = pretrained_params[keys[index]]
            self.features.load_state_dict(new_dict)  # load_state_dict必须传入字典对象,将预训练的参数权重加载到features中

    def forward(self, x):
        pool3 = self.features[:self.index_pool3](x)  # 图像大小为原来的1/8
        pool4 = self.features[self.index_pool3:self.index_pool4](pool3)  # 图像大小为原来的1/16
        # pool4 = self.features[:self.index_pool4](x)    # pool4的第二种写法,较浪费时间(从头开始)

        pool5 = self.features[self.index_pool4:](pool4)  # 图像大小为原来的1/32

        conv6 = self.relu(self.conv6(pool5))  # 图像大小为原来的1/32
        conv7 = self.relu(self.conv7(conv6))  # 图像大小为原来的1/32

        return pool3, pool4, conv7


class FCN(nn.Module):
    def __init__(self, num_classes, backbone='vgg'):
        """
        Args:
            num_classes: 分类数目
            backbone: 骨干网络 VGG
        """
        super(FCN, self).__init__()
        if backbone == 'vgg':
            self.features = VGG16()  # 参数初始化

        # 1*1卷积,将通道数映射为类别数
        self.scores1 = nn.Conv2d(4096, num_classes, kernel_size=1)  # 对conv7操作
        self.relu = nn.ReLU(inplace=True)
        self.scores2 = nn.Conv2d(512, num_classes, kernel_size=1)   # 对pool4操作 
        self.scores3 = nn.Conv2d(256, num_classes, kernel_size=1)   # 对pool3操作

        self.upsample_8x = nn.ConvTranspose2d(num_classes, num_classes, kernel_size=8, stride=8)  # 转置卷积
        self.upsample_2x = nn.ConvTranspose2d(num_classes, num_classes, kernel_size=2, stride=2)


    def forward(self, x):
        b, c, h, w = x.shape
        pool3, pool4, conv7 = self.features(x)

        conv7 = self.relu(self.scores1(conv7))

        pool4 = self.relu(self.scores2(pool4))

        pool3 = self.relu(self.scores3(pool3))

        # 融合之前调整一下h w
        conv7_2x = F.interpolate(self.upsample_2x(conv7), size=(pool4.size(2), pool4.size(3)))  # conv7 2倍上采样,调整到pool4的大小
        s=conv7_2x+pool4  # conv7 2倍上采样与pool4融合

        s=F.interpolate(self.upsample_2x(s),size=(pool3.size(2),pool3.size(3)))  # 融合后的特征2倍上采样,调整到pool3的大小
        s = pool3 + s     # 融合后的特征与pool3融合

        out_8s=F.interpolate(self.upsample_8x(s) ,size=(h,w))  # 8倍上采样得到 FCN-8s,得到和原特征x一样大小的特征

        return out_8s

if __name__=='__main__':
    model = FCN(num_classes=12)

    fake_img=torch.randn((4,3,360,480))  # B C H W

    output_8s=model(fake_img)
    print(output_8s.shape)


输出:

torch.Size([4, 12, 360, 480])文章来源地址https://www.toymoban.com/news/detail-450392.html

到了这里,关于图像分割-FCN全卷积神经网络(完整代码详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【CNN回归预测】基于卷积神经网络的数据回归预测附matlab完整代码

    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 基于卷积神经网络(Convolutional Neural Network,CNN)的数据回归预测是一种利用CNN模型来进行数据回归问题的预测和估计。以下是一种

    2024年02月04日
    浏览(47)
  • 基于计算机视觉,深度学习、机器学习,OpenCV,图像分割,目标检测卷积神经网络计算机毕业设计选题题目大全选题指导

    随着深度学习、机器学习和神经网络技术的快速发展,计算机视觉领域的应用变得越来越广泛和有趣。本毕业设计旨在探索这一领域的前沿技术,将深度学习模型、神经网络架构、OpenCV图像处理工具,以及卷积神经网络(CNN)的强大能力结合起来,以解决实际图像处理问题。

    2024年02月08日
    浏览(73)
  • 【图像分类】基于卷积神经网络和主动学习的高光谱图像分类(Matlab代码实现)

     💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 文献来

    2024年02月12日
    浏览(44)
  • 卷积神经网络 —— 图像卷积

    卷积神经网络是最具代表性的深度学习算法之一,目前已经被大范围的应用与计算机视觉等领域,并且取得了众多突破性的进展,在学习卷积神经网络之前,我们需要学习图像卷积运算。 图像卷积运算是一种图像处理算法。通过它可以实现很多不同的效果。例如,模糊图像中

    2024年02月07日
    浏览(50)
  • 【YOLOv8改进】MCA:用于图像识别的深度卷积神经网络中的多维协作注意力 (论文笔记+引入代码)

    先前的大量研究表明,注意力机制在提高深度卷积神经网络(CNN)的性能方面具有巨大潜力。然而,大多数现有方法要么忽略通道和空间维度的建模注意力,要么引入更高的模型复杂性和更重的计算负担。为了缓解这种困境,在本文中,我们提出了一种轻量级且高效的多维协

    2024年03月18日
    浏览(79)
  • 图神经网络:(图像分割)三维网格图像分割

    文章说明: 1)参考资料:PYG的文档。文档超链。斯坦福大学的机器学习课程。课程超链。(要挂梯子)。博客原文。原文超链。(要挂梯子)。原文理论参考文献。提取码8848。 2)我在百度网盘上传这篇文章的jupyter notebook以及预训练模型。提取码8848. 3)博主水平不高,如有错误,还

    2024年02月13日
    浏览(39)
  • 图神经网络:(图像分割)3D人物图像分割

    文章说明: 1)参考资料:PYG的文档。文档超链。斯坦福大学的机器学习课程。课程超链。(要挂梯子)。博客原文。原文超链。(要挂梯子)。原文理论参考文献。提取码8848。 2)我在百度网盘上传这篇文章的jupyter notebook以及预训练模型。提取码8848. 3)博主水平不高,如有错误,还

    2024年02月12日
    浏览(52)
  • 基于多任务学习卷积神经网络的皮肤损伤联合分割与分类

    在皮肤病计算机辅助诊断中,皮肤病变的分割和分类是两项至关重要且相互关联的任务。联合执行这两个任务可以利用它们之间的相关性来获得性能提升,但这仍然是一个具有挑战性的主题。本文提出了一种端到端多任务学习卷积神经网络(MTL-CNN)用于关节皮肤病变的分割和分

    2024年02月14日
    浏览(43)
  • 卷积神经网络实现图像识别

    目的: 实现昆虫的图像分类,同时该模型也可以用于其他图像的分类识别,只需传入相应的训练集进行训练,保存为另一个模型即可,进行调用使用。 配置环境: pycharm(python3.7),导入pytotch库 知识预备: 需要了解卷积神经网络的基本原理与结构,熟悉pytorch的使用,csdn有

    2023年04月09日
    浏览(35)
  • 图像分类卷积神经网络模型综述

    图像分类:核心任务是从给定的分类集合中给图像分配一个标签任务。 输入:图片 输出:类别。 MNIST数据集是用来识别手写数字,由0~9共10类别组成。 从MNIST数据集的SD-1和SD-3构建的,其中包含手写数字的二进制图像: MNIST数据集将SD-3作为训练集,将SD-1作为测试集,但SD-3比

    2023年04月14日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包