语义分割 - SegNet / DeconvNet
这里写目录标题
- 论文精读
- 先验知识
- 编码器 - 解码器结构(Encoder - Decoder frame)
- 随机丢弃层(Dropout)
- 反池化(unpooling)
- SegNet
- 本文创新点
- 算法架构
- DeconvNet
- 本文创新点
- 算法架构
- 算法实现
- SegNet.py
- 导入包
- 解码器中的卷积部分的定义
- 构建网络
- DeconvNet.py
- 导入包
- 解码器中反卷积的部分的定义
- 构建网络
论文精读
先验知识
编码器 - 解码器结构(Encoder - Decoder frame)
编码器结构:
由普通卷积层和下采样层将特征图尺寸缩小
解码器结构:
由普通卷积、上采样层和融合层组成,用来逐渐恢复空间维度,在尽可能减少信息损失的前提下完成同尺寸输入输出
随机丢弃层(Dropout)
当一个复杂的前馈神经网络被训练在小数据集上时,容易造成过拟合。Dropout通过忽略特征检测器来减少过拟合现象。
反池化(unpooling)
解码器中每一个最大池化层的索引都存储起来,用于之后在解码器中进行反池化操作。
- 有助于保持高频信息的完整性
- 对低分辨率的特征图进行反池化时,会忽略临近的信息
SegNet
本文创新点
- SegNet 核心的训练引擎包括一个 encoder 网络和一个对称的 decoder 网络,即编码器 - 解码器结构
- decoder 中直接利用与之对应的 encoder 阶段中最大池化时保留的 pooling index 来反池化
算法架构
DeconvNet
本文创新点
- 编码部分使用 VGG-16 卷积层
- 解码部分使用反卷积和反池化
- 特殊方法:将 object proposal 送入训练后的网络,整幅图像是由 proposal 分割结果的组合,解决了物体太大或太小带来的分割问题
算法架构
DeconvNet 与 SegNet 的不同之处主要在于
- 反池化与反卷积结合来形成 decoder
- encoder 和 decoder 之间加入了全连接
算法实现
除了模型以外,其他部分与FCN无异
SegNet.py
导入包
import torch
import torchvision.models as models
from torch import nn
解码器中的卷积部分的定义
def decoder(input_channel, output_channel, num=3):if num == 3:decoder_body = nn.Sequential(nn.Conv2d(input_channel, input_channel, 3, padding=1),nn.Conv2d(input_channel, input_channel, 3, padding=1),nn.Conv2d(input_channel, output_channel, 3, padding=1))elif num == 2:decoder_body = nn.Sequential(nn.Conv2d(input_channel, input_channel, 3, padding=1),nn.Conv2d(input_channel, output_channel, 3, padding=1))return decoder_body
构建网络
torch.nn.MaxPool2d() 用法
torch.nn.MaxUnpool2d() 用法
vgg16_pretrained = models.vgg16(pretrained=True)class VGG16_seg(torch.nn.Module):def __init__(self):super(VGG16_seg, self).__init__()pool_list = [4, 9, 16, 23, 30]for index in pool_list:vgg16_pretrained.features[index].return_indices = True # 让pooling层返回索引self.encoder1 = vgg16_pretrained.features[:4]self.pool1 = vgg16_pretrained.features[4]self.encoder2 = vgg16_pretrained.features[5:9]self.pool2 = vgg16_pretrained.features[9]self.encoder3 = vgg16_pretrained.features[10:16]self.pool3 = vgg16_pretrained.features[16]self.encoder4 = vgg16_pretrained.features[17:23]self.pool4 = vgg16_pretrained.features[23]self.encoder5 = vgg16_pretrained.features[24:30]self.pool5 = vgg16_pretrained.features[30]self.decoder5 = decoder(512, 512)self.unpool5 = nn.MaxUnpool2d(2, 2)self.decoder4 = decoder(512, 256)self.unpool4 = nn.MaxUnpool2d(2, 2)self.decoder3 = decoder(256, 128)self.unpool3 = nn.MaxUnpool2d(2, 2)self.decoder2 = decoder(128, 64, 2)self.unpool2 = nn.MaxUnpool2d(2, 2)self.decoder1 = decoder(64, 12, 2)self.unpool1 = nn.MaxUnpool2d(2, 2)def forward(self, x): # 3, 352, 480encoder1 = self.encoder1(x) # 64, 352, 480output_size1 = encoder1.size() # 64, 352, 480pool1, indices1 = self.pool1(encoder1) # 64, 176, 240encoder2 = self.encoder2(pool1) # 128, 176, 240output_size2 = encoder2.size() # 128, 176, 240pool2, indices2 = self.pool2(encoder2) # 128, 88, 120encoder3 = self.encoder3(pool2) # 256, 88, 120output_size3 = encoder3.size() # 256, 88, 120pool3, indices3 = self.pool3(encoder3) # 256, 44, 60encoder4 = self.encoder4(pool3) # 512, 44, 60output_size4 = encoder4.size() # 512, 44, 60pool4, indices4 = self.pool4(encoder4) # 512, 22, 30encoder5 = self.encoder5(pool4) # 512, 22, 30output_size5 = encoder5.size() # 512, 22, 30pool5, indices5 = self.pool5(encoder5) # 512, 11, 15unpool5 = self.unpool5(input=pool5, indices=indices5, output_size=output_size5) # 512, 22, 30decoder5 = self.decoder5(unpool5) # 512, 22, 30unpool4 = self.unpool4(input=decoder5, indices=indices4, output_size=output_size4) # 512, 44, 60decoder4 = self.decoder4(unpool4) # 256, 44, 60unpool3 = self.unpool3(input=decoder4, indices=indices3, output_size=output_size3) # 256, 88, 120decoder3 = self.decoder3(unpool3) # 128, 88, 120unpool2 = self.unpool2(input=decoder3, indices=indices2, output_size=output_size2) # 128, 176, 240decoder2 = self.decoder2(unpool2) # 64, 176, 240unpool1 = self.unpool1(input=decoder2, indices=indices1, output_size=output_size1) # 64, 352, 480decoder1 = self.decoder1(unpool1) # 12, 352, 480return decoder1
DeconvNet.py
除了结构中加入了
导入包
import torch
import torchvision.models as models
from torch import nn
解码器中反卷积的部分的定义
与 SegNet 的不同点之一就是 decoder 部分采用了反卷积
def decoder(input_channel, output_channel, num=3):if num == 3:decoder_body = nn.Sequential(nn.ConvTranspose2d(input_channel, input_channel, 3, padding=1),nn.ConvTranspose2d(input_channel, input_channel, 3, padding=1),nn.ConvTranspose2d(input_channel, output_channel, 3, padding=1))elif num == 2:decoder_body = nn.Sequential(nn.ConvTranspose2d(input_channel, input_channel, 3, padding=1),nn.ConvTranspose2d(input_channel, output_channel, 3, padding=1))return decoder_body
构建网络
构建网络中,与 SegNet 不同点在于其加入了全连接部分,并在全连接后将数据 reshape 成了解码器的结束时的图片尺寸
class VGG16_deconv(torch.nn.Module):def __init__(self):super(VGG16_deconv, self).__init__()pool_list = [4, 9, 16, 23, 30]for index in pool_list:vgg16_pretrained.features[index].return_indices = Trueself.encoder1 = vgg16_pretrained.features[:4]self.pool1 = vgg16_pretrained.features[4]self.encoder2 = vgg16_pretrained.features[5:9]self.pool2 = vgg16_pretrained.features[9]self.encoder3 = vgg16_pretrained.features[10:16]self.pool3 = vgg16_pretrained.features[16]self.encoder4 = vgg16_pretrained.features[17:23]self.pool4 = vgg16_pretrained.features[23]self.encoder5 = vgg16_pretrained.features[24:30]self.pool5 = vgg16_pretrained.features[30]self.classifier = nn.Sequential(torch.nn.Linear(512 * 11 * 15, 4096),torch.nn.ReLU(),torch.nn.Linear(4096, 512 * 11 * 15),torch.nn.ReLU(),)self.decoder5 = decoder(512, 512)self.unpool5 = nn.MaxUnpool2d(2, 2)self.decoder4 = decoder(512, 256)self.unpool4 = nn.MaxUnpool2d(2, 2)self.decoder3 = decoder(256, 128)self.unpool3 = nn.MaxUnpool2d(2, 2)self.decoder2 = decoder(128, 64, 2)self.unpool2 = nn.MaxUnpool2d(2, 2)self.decoder1 = decoder(64, 12, 2)self.unpool1 = nn.MaxUnpool2d(2, 2)def forward(self, x): # 3, 352, 480encoder1 = self.encoder1(x) # 64, 352, 480output_size1 = encoder1.size() # 64, 352, 480pool1, indices1 = self.pool1(encoder1) # 64, 176, 240encoder2 = self.encoder2(pool1) # 128, 176, 240output_size2 = encoder2.size() # 128, 176, 240pool2, indices2 = self.pool2(encoder2) # 128, 88, 120encoder3 = self.encoder3(pool2) # 256, 88, 120output_size3 = encoder3.size() # 256, 88, 120pool3, indices3 = self.pool3(encoder3) # 256, 44, 60encoder4 = self.encoder4(pool3) # 512, 44, 60output_size4 = encoder4.size() # 512, 44, 60pool4, indices4 = self.pool4(encoder4) # 512, 22, 30encoder5 = self.encoder5(pool4) # 512, 22, 30output_size5 = encoder5.size() # 512, 22, 30pool5, indices5 = self.pool5(encoder5) # 512, 11, 15# 在输入全连接前要将其打平成(batchsize, -1)pool5 = pool5.view(pool5.size(0), -1)fc = self.classifier(pool5) # 在全连接结束后返回的也是(batchsize, -1)的打平形式fc = fc.reshape(1, 512, 11, 15)unpool5 = self.unpool5(input=fc, indices=indices5, output_size=output_size5) # 512, 22, 30decoder5 = self.decoder5(unpool5) # 512, 22, 30unpool4 = self.unpool4(input=decoder5, indices=indices4, output_size=output_size4) # 512, 44, 60decoder4 = self.decoder4(unpool4) # 256, 44, 60unpool3 = self.unpool3(input=decoder4, indices=indices3, output_size=output_size3) # 256, 88, 120decoder3 = self.decoder3(unpool3) # 128, 88, 120unpool2 = self.unpool2(input=decoder3, indices=indices2, output_size=output_size2) # 128, 176, 240decoder2 = self.decoder2(unpool2) # 64, 176, 240unpool1 = self.unpool1(input=decoder2, indices=indices1, output_size=output_size1) # 64, 352, 480decoder1 = self.decoder1(unpool1) # 12, 352, 480return decoder1
语义分割 - SegNet / DeconvNet相关推荐
- 语义分割 | segnet 制作自己的数据,如何训练,如何测试,如何评价
本博文介绍如何手把手制作自己的数据集,并使用SegNet网络进行语义分割,如何训练,如何测试自己的分割模型. --------------------------------------------- ...
- 语义分割-- SegNet:A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation
SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation PAMI 2017 http://mi ...
- 一文概览主要语义分割网络:FCN,SegNet,U-Net...
本文来自 CSDN 网站,译者蓝三金 图像的语义分割是将输入图像中的每个像素分配一个语义类别,以得到像素化的密集分类.虽然自 2007 年以来,语义分割/场景解析一直是计算机视觉社区的一部分,但与计算 ...
- DL之SegNet:SegNet图像分割/语义分割算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
DL之SegNet:SegNet图像分割/语义分割算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 导读 基于CNN的神经网络SegNet算法可进行高精度地识别行驶环境. 目录 SegN ...
- 干货 | 一文概览主要语义分割网络,FCN、UNet、SegNet、DeepLab 等等等等应有尽有
翻译不易,麻烦 Ctrl-C Ctrl-V 之后标注转载并加上原译者!! 部分内容翻译,部分内容原创. 内容较多,可以传送门直达.新网络待更- 文章目录 介绍 网络架构 Fully Convoluti ...
- 制作自己的segnet数据集_语义分割【论文解读】经典网络SegNet 值得仔细反复阅读...
摘要: 提出了一种新颖而实用的深度全卷积神经网络结构用于语义像素分割称为SegNet.这个核心的可训练分割引擎包括一个编码器网络,一个相应的解码器网络,以及一个像素级的分类层.编码器网络的架构与VGG ...
- 语义分割中的深度学习方法全解:从FCN、SegNet到各版本DeepLab
语义分割中的深度学习方法全解:从FCN.SegNet到各版本DeepLab 原文:https://www.sohu.com/a/155907339_610300 图像语义分割就是机器自动从图像中分割出 ...
- 【Deep Learning笔记】语义分割网络-Segnet的探索
文章目录 1 简介 2 网络框架 3 Encoder 4 Pooling&Upsampling(decoder): 5 Batch Normlization 6 Loss Function 7 ...
- 【Keras】基于SegNet和U-Net的遥感图像语义分割
from:[Keras]基于SegNet和U-Net的遥感图像语义分割 上两个月参加了个比赛,做的是对遥感高清图像做语义分割,美其名曰"天空之眼".这两周数据挖掘课期末projec ...
最新文章
- 【2017-02-19】数据类型、类型转换、常量、变量、转义符。
- Visual C++中MFC消息的分类
- 利用ASP.NET向服务器上传文件[转]
- Java多线程学习十七:读锁应该插队吗?什么是读写锁的升降级?
- 被腾讯看上,叽里呱啦获近亿美元C轮融资
- 滴滴司机问我会 LRU 吗?
- std::thread参数传递包含引用时的注意事项
- 计算机光驱启动设置,光驱启动怎么设置
- ios快捷指令 python_手把手教你使用 iOS 效率神器 「快捷指令」
- 军犬舆情每日热点:台湾海峡发生6.2级地震;泉州通报碳九泄漏事件处理结果
- Derivative Filter(导数过滤器)
- 2017年中秋前记录
- 健身预约小程序的设计与实现
- 数字图像处理:像素间的一些基本关系
- Linux基础命令-tar打包压缩文件
- 解决,微信网页开发,网页授权域名数量不足问题
- 基于java/php/python的毕业设计管理系统开题报告
- 一次挖矿木马病毒排查过程
- 提取微信记录为csv文件或txt文件(免root,免安装java)
- python不改变图片尺寸压缩到指定大小 1