向AI转型的程序员都关注了这个号????????????
机器学习AI算法工程 公众号:datayx
什么是图像分割问题呢?简单的来讲就是给一张图像,检测是用框出框出物体,而图像分割分出一个物体的准确轮廓。也这样考虑,给出一张图像 I,这个问题就是求一个函数,从I映射到Mask。至于怎么求这个函数有多种方法。我们可以看到这个图,左边是给出图像,可以看到人和摩托车,右边是分割结果。
求这个函数有很多方法,但是第一次将深度学习结合起来的是这篇文章全卷积网络(FCN),利用深度学习求这个函数。在此之前深度学习一般用在分类和检测问题上。由于用到CNN,所以最后提取的特征的尺度是变小的。和我们要求的函数不一样,我们要求的函数是输入多大,输出有多大。为了让CNN提取出来的尺度能到原图大小,FCN网络利用上采样和反卷积到原图像大小。然后做像素级的分类。
可以看图二,输入原图,经过VGG16网络,得到特征map,然后将特征map上采样回去。再将预测结果和ground truth每个像素一一对应分类,做像素级别分类。也就是说将分割问题变成分类问题,而分类问题正好是深度学习的强项。如果只将特征map直接上采样或者反卷积,明显会丢失很多信息。
FCN采取解决方法是将pool4、pool3、和特征map融合起来,由于pool3、pool4、特征map大小尺寸是不一样的,所以融合应该前上采样到同一尺寸。这里的融合是拼接在一起,不是对应元素相加。
FCN是深度学习在图像分割的开山之作,FCN优点是实现端到端分割等,缺点是分割结果细节不够好,可以看到图四,FCN8s是上面讲的pool4、pool3和特征map融合,FCN16s是pool4和特征map融合,FCN32s是只有特征map,得出结果都是细节不够好,具体可以看自行车。由于网络中只有卷积没有全连接,所以这个网络又叫全卷积网络。
本文将先简单介绍Unet的理论基础,然后使用pytorch一步一步地实现Unet图像分割。因为主要目的是提供一个baseline模型给大家,所以代码主要关注在如何构造Unet的网络结构。
Unet
图1: Unet的网络结构
Unet主要用于图像分割问题。图1是Unet论文中的网络结构图。
https://arxiv.org/abs/1505.04597
很多分割网络都是基于FCNs做改进,包括Unet。Unet包括两部分,可以看右图,第一部分,特征提取,VGG类似。第二部分上采样部分。由于网络结构像U型,所以叫Unet网络。
- 特征提取部分,每经过一个池化层就一个尺度,包括原图尺度一共有5个尺度。
- 上采样部分,每上采样一次,就和特征提取部分对应的通道数相同尺度融合,但是融合之前要将其crop。这里的融合也是拼接。
个人认为改进FCN之处有:
- 多尺度
- 适合超大图像分割,适合医学图像分割
可以看出Unet是一个对称的结构,左半边是Encoder,右半边是Decoder。图像会先经过Encoder处理,再经过Decoder处理,最终实现图像分割。它们分别的作用如下:
- Encoder:使得模型理解了图像的内容,但是丢弃了图像的位置信息。
- Decoder:使模型结合Encoder对图像内容的理解,恢复图像的位置信息。
Encoder的部分和传统的网络结构类似,可以选择图中的结构,也可以选择VGG,ResNet等。随着卷积层的加深,特征图的长宽减小,通道增加。虽然Encoder提取了图像的高级特征,但是丢弃了图像的位置信息。所以在图像识别问题中,模型只需要Encoder的部分。因为图像识别不需要位置信息,只需要提取图像的内容信息。
Decoder的部分是Unet的重点。Decoder中涉及upconvolution这个概念。关于upconvolution,这里不做详细介绍,简单来说就是convolution的反向运算。Decoder的每一层都通过upconvolution(图中绿色箭头),并且和Encoder相对应的初级特征结合(图中的灰色箭头),逐渐恢复图像的位置信息。在Decoder中,随着卷积层的加深,特征图的长宽增大,通道减少。
Unet——输入输出
医学图像是一般相当大,但是分割时候不可能将原图太小输入网络,所以必须切成一张一张的小patch,在切成小patch的时候,Unet由于网络结构原因适合有overlap的切图,可以看图,红框是要分割区域,但是在切图时要包含周围区域,overlap另一个重要原因是周围overlap部分可以为分割区域边缘部分提供文理等信息。可以看黄框的边缘,分割结果并没有受到切成小patch而造成分割情况不好。
本文用到的数据来源于Kaggle盐体分割比赛。这次比赛的问题是一个非常典型的图像分割问题。比赛中的大佬们基本上都用的Unet。
我们的目标就是将图片中的盐体找出来。盐体有一些我不太懂的经济价值,反正是很有意义的。
以下是一些图片样例:
PyTorch实现
代码 以及运行教程 获取:
关注微信公众号 datayx 然后回复 分割 即可获取。
AI项目体验地址 https://loveai.tech
Unet
本文定义的Unet网络结构和论文中的略有不同,但本质都采用的是Encoder和Decoder的结构。主要的不同点是:
- Encoder的backbone基于ResNet18
- 输入和输出图像大小一致
以下是Unet网络结构的pytorch代码,代码后附了详细的解释。
- 这里定义了两个class:
Decoder
和 Unet
。Unet
是整个模型的结构,Decoder
则是模型Decoder中的单层。 - 使用pytorch构造模型时,需要基于
nn.Module
定义类。forward
函数定义前向传播的逻辑。 -
Decoder
中的up
运算定义为nn.ConvTranspose2d
,也就是upconvolution;conv_relu
则定义为nn.Conv2d
和nn.ReLU
的组合。pytorch中需要用到nn.Sequential
将多个运算组合在一起。 -
Decoder
中forward
函数定义了其前向传播的逻辑:1. 对特征图x1做upconvolution。2. 将x1和x2(encoder中对应的特征图)组合(concatenate)。3. 对组合后的特征图做卷积和relu。 - 因为
Unet
基于resnet18,所以定义运算时从torchvision.models.resnet18
取出来就可以。因为resnet18默认的是适用于RGB图片,而比赛中的图片是灰的,只有一个通道,所以layer1
中的卷基层需要自己定义。 -
layer1
到layer5
属于encoder,encode4
到encode0
属于decoder,呈对称结构。 - 下表是经过各层的处理后,特征图的长/宽和通道数:
Dataset
如果你了解keras,那么就会发现pytorch中的Dataset
和keras中的DataGenerator
类似。不同的是pytorch定义的Dataset
只返回1个样本,再通过DataLoader
定义batch_size
。
Dataset的逻辑很简单,分为以下几步:
- 读取图片
- 预处理(resize, pad, 数据增强等)
- 返回图片和Mask
Pytorch代码如下:
Optimizer
optimizer采用的是SGD,同时用到了余弦退火学习率和快照集成来提升模型效果。
结论
在没有数据增强和TTA等其他手段的情况下,本文的代码能够拿到0.76的成绩,是一个不错的baseline模型。
阅读过本文的人还看了以下文章:
基于40万表格数据集TableBank,用MaskRCNN做表格检测
【全套视频课】最全的目标检测算法系列讲解,通俗易懂!
《深度学习入门:基于Python的理论与实现》高清中文PDF+源码
2019最新《PyTorch自然语言处理》英、中文版PDF+源码
《21个项目玩转深度学习:基于TensorFlow的实践详解》完整版PDF+附书代码
PyTorch深度学习快速实战入门《pytorch-handbook》
【下载】豆瓣评分8.1,《机器学习实战:基于Scikit-Learn和TensorFlow》
李沐大神开源《动手学深度学习》,加州伯克利深度学习(2019春)教材
笔记、代码清晰易懂!李航《统计学习方法》最新资源全套!
《神经网络与深度学习》最新2018版中英PDF+源码
FashionAI服装属性标签图像识别Top1-5方案分享
【Keras】完整实现‘交通标志’分类、‘票据’分类两个项目,让你掌握深度学习图像分类
如何利用全新的决策树集成级联结构gcForest做特征工程并打分?
Machine Learning Yearning 中文翻译稿
斯坦福CS230官方指南:CNN、RNN及使用技巧速查(打印收藏)
python+flask搭建CNN在线识别手写中文网站
中科院Kaggle全球文本匹配竞赛华人第1名团队-深度学习与特征工程
不断更新资源
深度学习、机器学习、数据分析、python
搜索公众号添加: datayx
机大数据技术与机器学习工程
搜索公众号添加: datanlp
长按图片,识别二维码
标签:盐体,分割,特征,Decoder,pytorch,学习,Unet,图像 From: https://blog.51cto.com/u_15404184/5797843