图像语义分割(一) —— Fully Convolutional Networks理解与实现

语义分割 - FCN (Fully Convolutional Networks) 目录FCN论文精读本文的创新点先验知识感受野(感受域) Receptive field全局信息与局部信息算法架构训练技巧算法实现定义配置文件 cfg.py数据集处理 dataset.py导入包※※※ 对标签图像编码为什么要对标签图像编码代码实现加载数据集模型的建立 FCN.py导入包自定义双向线性插值卷积核线性插值与双线性插值代码实现卷积核效果构建网络卷积与反卷积尺寸计算公式vgg16的结构代码实现 FCN论文精读 本文的创新点 将分类网络改编为全卷积网络,具体为全连接层转化为卷积层以及通过反卷积 阅读详情

语义分割(零) https://blog.youkuaiyun.com/Qer_computerscience/article/details/84778682

来自伯克利的2014CVPR、2015PAMI非常经典的一篇用FCN进行语义分割的文章,后续也都基于此FCN架构进行进一步拓展。

下面对论文中主要思想进行总结

一、文章主要贡献

1.全卷积

常用的分类网络例如VGG、GoogleNet、AlexNet等,都是由features和classifier构成,由全连接层进行分类任务。同时也正是由于全连接的存在,导致网络只能接受固定大小的输入以适应固定数量的全连接神经元,而卷积网本身并没有对图像的size进行限制,不同的input size,卷积核依然有固定大小的感受野来产生corresponding features。作者采用了FCN架构,将传统分类网络的分类连接层转换成全卷积网络。(抛弃分类层,或构成dense conv层),在语义分割任务中,只需要将卷积层的输入,上采样缩小倍数到原始大小,就可以统计每一个pixel的误差进而反向传播。

2.多层信息融合

网络本身由很多个卷积部分构成,例如VGG16包含了5个卷积池化组,而global information解决是什么的问题,local information解决在哪里的问题,在卷积网中体现在深层和浅层信息中。Combining what and where,采用多层融合信息,更有利于最终的semantic segmentation。

3.end-to-end

网络端到端训练,基于FCN构成了end to end结构。

二、算法细节

在这里插入图片描述
文章采用了将全连接替换成全卷积层,通过1x1卷积核获得相应的感受野,但可以处理不同的输入尺寸了。

混合层的实现需要通过上采样,以VGG的conv5输入为例,经过卷积与池化,map的size经过了32x的下采样,我们可以通过插值的方式实现上采样,同样也可以通过deconvolution实现,同时卷积参数可以学习,能够达到非线性插值的效果。

在混合多层map的时候,如将32x上采样(deconv)2倍到16x,即可以与conv4的16x特征输出层混合,文中采用直接相加的方式,以此类推混合从深到浅层的信息。

三、简单实现

在这里我写了一个简单的pytorch实现版本,基于vgg16模型,混合了32s,16s,8s特征。
net结构如下所示:

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import models


#build vgg16 net
cfg = {'vgg16' : [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M']}
ranges = {'vgg16': ((0, 5), (5, 10), (10, 17), (17, 24), (24, 31))}
def make_layers(cfg, batch_norm = False):
    layers = []
    in_channels = 3
    for val in cfg:
        if val == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            conv2d = nn.Conv2d(in_channels, val, kernel_size=3, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(val), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
            in_channels = val
    return nn.Sequential(*layers)

class VGGNet(nn.Module):
    def __init__(self, features):
        super(VGGNet, self).__init__()
        self.features = features
        self.ranges = ranges['vgg16']
        # self._init_weights()
    def _init_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
    def forward(self, x):
        output = {}
        for i in range(len(self.ranges)):
            for layer in range(self.ranges[i][0], self.ranges[i][1]):
                x = self.features[layer](x)
            output['x%d'%(i+1)] = x
        return output

class FCN32s(nn.Module):
    def __init__(self, base_model, n_class):
        super().__init__()
        self.n_class = n_class
        self.base_model = base_model
        self.conv = nn.Conv2d(512, n_class, kernel_size=1)
        self.relu = nn.ReLU(inplace=True)
        self.deconv = nn.ConvTranspose2d(n_class, n_class, kernel_size=64, stride=32, padding=16)

    def forward(self, x):
        output = self.base_model(x)
        x5 = output['x5']
        score = self.relu(self.conv(x5))
        score = self.deconv(score)
        return score

class FCN16s(nn.Module):
    def __init__(self, base_model, n_class):
        super().__init__()
        self.n_class = n_class
        self.base_model = base_model
        self.relu = nn.ReLU(inplace=True)
        self.conv = nn.Conv2d(512, n_class, kernel_size=1)
        self.deconv = nn.ConvTranspose2d(n_class, n_class, kernel_size=4, stride=2, padding=1)
        self.deconv2 = nn.ConvTranspose2d(n_class, n_class, kernel_size=32, stride=16, padding=8)
        self.bn = nn.BatchNorm2d(n_class)
    
    def forward(self, x):
        output = self.base_model(x)
        x5 = output['x5']
        x4 = output['x4']
        score = self.relu(self.conv(x5))
        score = self.bn(self.deconv(score) + self.relu(self.conv(x4)))
        score = self.deconv2(score)
        return score

class FCN8s(nn.Module):
    def __init__(self, base_model, n_class):
        super().__init__()
        self.n_class = n_class
        self.base_model = base_model
        self.relu = nn.ReLU(inplace=True)
        self.conv5 = nn.Conv2d(512, n_class, kernel_size=1)
        self.conv4 = nn.Conv2d(512, n_class, kernel_size=1)
        self.conv3 = nn.Conv2d(256, n_class, kernel_size=1)
        self.deconv5 = nn.ConvTranspose2d(n_class, n_class, kernel_size=4, stride=2, padding=1)
        self.deconv4 = nn.ConvTranspose2d(n_class, n_class, kernel_size=4, stride=2, padding=1)
        self.deconv3 = nn.ConvTranspose2d(n_class, n_class, kernel_size=16, stride=8, padding=4)
        self.bn1 = nn.BatchNorm2d(n_class)
        self.bn2 = nn.BatchNorm2d(n_class)
    
    def forward(self, x):
        output = self.base_model(x)
        x5 = output['x5']
        x4 = output['x4']
        x3 = output['x3']
        score = self.relu(self.conv5(x5))
        score = self.bn1(self.deconv5(score) + self.relu(self.conv4(x4)))
        score = self.bn2(self.deconv4(score) + self.relu(self.conv3(x3)))
        score = self.deconv3(score)
        return score

if __name__ == '__main__':
    print('main:')
    model = VGGNet(make_layers(cfg['vgg16']))
    # fine-tune model.
    model.load_state_dict(torch.load('vgg16_features.pth'))

    input = torch.autograd.Variable(torch.randn(5, 3, 160, 160))
    y = torch.autograd.Variable(torch.randn(5, 20, 160, 160), requires_grad=False)
    fcn = FCN8s(model, 20)
    
    #test loss decrease.
    Loss = nn.BCEWithLogitsLoss()
    optimizer = optim.SGD(fcn.parameters(), lr=1e-3, momentum=0.9)
    for i in range(10): 
        optimizer.zero_grad()
        output = fcn(input)
        loss = Loss(output, y)
        loss.backward()
        print("iter{}, loss {}".format(i, loss.data.item()))
        optimizer.step()




语义分割系列1-FCN(全卷积网络)(pytorch实现) 本文复现了全卷积网络FCN(Fully Convolutional Networks)论文,使用pytorch框架构建FCN结构,在PascalVOC2012数据集上实现复现。 阅读详情

相关推荐

FCN的学习及理解(Fully Convolutional Networks for Semantic Segmentation)

论文Fully Convolutional Networks for Semantic Segmentation 是图像分割的milestone论文。理清一下我学习过程中关注的重点。fcn开源代码github下载地址https://github.com/shelhamer/fcn.berkeleyvision.org核心思想该论文包含了当下CNN的三个思潮- 不含全连接层(fc)的全卷积(fu...

凹酱的DEEP LEARNING 29万+

FCN网络详解

FCN网络结构详解

ThreeStones1029的博客 1160

论文精读及分析:Fully Convolutional Networks for Semantic Segmentation

  本文主要内容为论文《Fully Convolutional Networks for Semantic Segmentation》 的阅读笔记,在原始论文的基础上加入了自己的一些理解,内容和图片主要参考该论文。其中一部分的翻译参考了 “一生不可自决” 的博客《Fully Convolutional Networks for semantic Segmentation(深度学习经典论文翻译)》...

dugudaibo的博客 1万+

【深度学习项目】语义分割-FCN网络(原理、网络架构、基于Pytorch实现FCN网络)

FCN(Fully Convolutional Networks,全卷积网络)是一种用于计算机视觉任务的神经网络架构,尤其擅长处理像素级别的分类问题,例如语义分割。FCN 的核心思想是将传统的 CNN(卷积神经网络)中的全连接层替换为卷积层,这样可以接受任意大小的输入图像,并输出同样大小的概率图,其中每个像素点对应于该位置属于某个类别的概率。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

论文笔记《Fully Convolutional Networks for Semantic Segmentation》

《Fully Convolutional Networks for Semantic Segmentation》,CVPR 2015 best paper,pixel level, fully supervised。 主要思路是把CNN改为FCN,输入一幅图像后直接在输出端得到dense prediction,也就是每个像素所属的class,从而得到一个end-to-end的方法来实现ima

July's Pensieve 2万+

全卷积网络(Fully Convolutional Networks, FCN)

全卷积网络

PeterClerk的博客 1388

语义分割—FCN网络 学习笔记 (附代码)

语义分割—FCN网络 学习笔记 (附代码)

PLANTTHESON的博客 2136

FCN网络结构图.zip

基于PASCAL的FCN网络结构图,使用Caffe深度学习框架绘制,内容为FCN8s.png,FCN16s.png,FCN32s.png

Fully Convolutional Networks for Semantic Segmentation

Fully Convolutional Networks for Semantic Segmentation 论文阅读 论文:Fully Convolutional Networks for Semantic Segmentation(2015 CVPR) 作者:Jonathan Long Evan Shelhamer Trevor Darrell -UC Berkeley 图像分割领域的开山之作 1.1 研究成果 将分类网络改变为全卷积神经网络,具体包括全连接层转换为卷积层以及通过反卷积进行

weixin_49708196的博客 5590

使用海康机器人的SDK进行DWS开发时如何筛选不同类型的相机

使用MVIDCodeReader、MvCodeReaderSDK、MvVolMeasureSDK联合开发时,通常会做一些设备枚举列表,但是不同类型的设备需要枚举在不同的列表中,便于软件使用者配置参数,例如: 如何保证枚举出来的设备是可以选择的对应的设备。我们通常枚举出来的是这样的: 解决办法 在联合开发中,我们发现,只有MvVolMeasureSDK的枚举设备接口EnumStereoCamEx可以正确的只枚举出网络内的体积设备,其余的MVIDCodeReader、MvCodeReaderS

qq_29123967的博客 2730

软考中级-系统集成项目管理工程师**的超详细知识点笔记。

软考中级系统集成项目管理工程师核心知识点摘要 综合知识:涵盖信息化基础(国家信息化六要素、信息系统开发方法)、系统集成特点(高技术性、团队协作)、IT服务管理(ITIL流程)、网络技术(OSI模型、TCP/IP)、信息安全(CIA三要素、加密技术)、软件工程(生命周期、测试类型)、面向对象分析与设计(UML图)、新一代信息技术(云计算、大数据、物联网)。 案例分析:聚焦项目管理十大知识领域,重点包括: 整体管理(项目章程、变更控制流程) 范围管理(WBS分解、需求跟踪矩阵) 进度管理

最爱で毛毛熊的博客 1986

[论文笔记]彻底讲透FCN语义分割开山之作Fully Convolutional Networks

FCN模型的三大优势 (1)全卷积Fully Convoluition (2)Upsamping via Deconvlution (3)Skip architecture

专注“目标检测”领域技术分享 2556

从ADS到HFSS:耦合线带通滤波器的设计与模型转换实战

本文详细介绍了耦合线带通滤波器的完整设计流程,重点阐述了从ADS电路级快速优化到HFSS三维电磁场精确验证的模型转换实战方法。通过对比ADS理想模型仿真与HFSS全波仿真结果,指导读者进行参数校准与迭代优化,并分享了关键的板材选择、加工误差及端口设置等避坑指南,确保设计性能与实物测试高度一致。

weixin_29290863的博客 343

FCN——深度学习领域图像分割(Fully Convolutional Networks for Semantic Segmentation)

深度学习领域图像分割FCN(Fully Convolutional Networks for Semantic Segmentation)

Keep_Trying_Go的博客 1931

Clion编译stm32cube初始化工程时non constant or forward reference address expression for section .ARM.extab报错

相信应该有同学在看了稚晖君关于clion开发stm32的文章之后也想在自己PC上实现“优雅の嵌入式开发”遇到和我类似的问题。他的文章是22年写的,我个人猜测应当是版本更新导致的不适配。意思就是说 READONLY 只能在gcc11以后的版本中使用,gcc10及以前的版本将无法正确识别,也就有如下错误。或者就可以将gcc升级至最新的版本。记得在clion工具链中修改c,cpp编译器的位置。可以将文本括号中的 READONLY 全部删除。当时由于没有注意到这行注释导致在这里卡了好久。

2301_77256849的博客 2510

本地生成无限量的AI图像和视频——无需网络,无限制,本地人工智能图像和视频生成的实用指南

我们将使用ComfyUI,这是一个功能强大的基于节点的 AI 图像和视频生成可视化界面。如果您是 ComfyUI 的新手,请不要担心。ComfyUI是什么?ComfyUI 是一款可视化工具,可让您在自己的计算机上生成 AI 图像和视频。您无需一次性理解所有内容。在本指南中,我们将从现成的工作流程入手,逐步帮助您建立信心。乍一看,内容似乎很庞杂——但本指南将着重于:-简单的工作流程-预构建示例-最少的配置我想向你展示使用这个工具最简单的工作流程。

iCloudEnd的博客 1798

Fully convolutional networks

前言   最近在看计算机图像和视觉方面的论文,FCN(Fully convolutional networks)是一篇非常成功的论文,图像语义分割这一块就靠它入门了。为了写博客更加方便,打算将论文讲解和实现分开成两篇博客,这样写起来也轻松一些。 原理   在讨论语义分割以前,我们先来讨论图像分类与物体检测。 图像分类 卷积神经网络的最基础的应用应该就是图像分类,图像分类的输入是二维图像数据,输...

rauchy的博客 3295

Synthesia技术浅析(四):自然语言处理

Synthesia 的自然语言处理(NLP)模块是其核心技术之一,涵盖了文本转语音(TTS)、情感分析以及多语言支持等多个方面。

m0_75253143的博客 1166

【图像分割】FCN (Fully Convolutional Networks)

目录FCN (Fully Convolutional Networks)核心思想优点和不足网络结构训练过程upsample 过程loss的计算 FCN (Fully Convolutional Networks) 原文: 《Fully Convolutional Networks for Semantic Segmentation》 实现: https://github.com/shelha...

爱学习的齐立青 769

ArcGIS Pro符号化教程

本文详细介绍了ArcGIS Pro的软件设置和符号化操作步骤。主要包括:1)设置默认工程目录和关闭地图自动加载;2)创建新工程的基本流程;3)点要素的单一符号化方法,包括样式修改和图层调整;4)图表符号显示过滤器的使用,涉及字段添加、图表类型选择和背景设置。文章还提供了操作截图和数据下载链接,适合GIS初学者学习ArcGIS Pro的基础符号化操作。

WwLK123的博客 548

如何用Python打造PubMed API客户端:科研文献检索自动化实践

PubMed提供了官方的Entrez E-utilities API接口,支持程序化检索文献,但直接调用API需处理请求重试、参数封装、数据解析等问题。批量获取文献ID及结构化详情(标题、作者、DOI等)内置重试机制,应对网络波动或API限流统一数据输出格式,便于后续分析(如文献计量、AI文本处理)灵活适配不同检索需求(如指定数据库、结果数量)本文实现的PubMed API客户端,通过封装API请求、重试机制、数据解析,让科研文献检索从“手动点击”变为“代码自动化”。

ASKCOS博客 357

基于全卷积的图像语义分割—《Fully Convolutional Networks for Semantic Segmentation》

两年前,我曾想做一个自动抠“人”的系统,目标是去除路人甲或者自动合成照片。当时“井底之蛙”般搞了一个混合高斯模型,通过像素聚类的方式来抠“人”。这个模型,每跑一张小图片需要几分钟,抠出来的前景“噪音”很严重,完全没办法使用。最后这个通过“抠人”去除路人甲的项目告吹。两年后的今天,这种“去除路人甲”的软件好像早已经有了,并且笨妞也发现,换成现在的我,做一个效果好的“抠人”神器太容易了。下载deepl...

老笨妞 3272

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【论文阅读】Fully Convolutional Networks for Semantic Segmentation FCN阅读、理解和复现

全卷积神经网络(FCN)论文阅读

pl23k的专栏 3124

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: 图像语义分割 (零) —— 基本概念、数据集、方法
下一篇: 图像语义分割(二) —— denseCRF模型用于图像语义分割
Qer_
博客等级 码龄11年 34粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值