U-Net 网络结构讲解

※ 这是学习 B站博主霹雳吧啦Wz  的  深度学习-语义分割篇-UNet网络结构讲解视频 所做的笔记。


论文名称:U-Net: Convolutional Netorks for Biomedical Image Segmentation

发布时间:2015年

论文地址:https://arxiv.org/abs/1505.04597

这篇论文是针对生物医学影像领域提出的,所以一提到UNet,我们很容易就想到医学影像。

关于 UNet 网络结构:

UNet是一个 Encoder-Decoder 的结构(编码-解码)。

Encoder 对应的是我们这个U型结构的左半部分,也就是我们特征提取以及下采样的部分。

Decoder 就是右半部分,经过一系列的上采样,最终得到一个分割图。

在论文当中,对于我们左边这一侧的叫做 contracting path (收缩路径),右边这一侧叫做 expanding path (扩张路径)。

在这张图中,每一个长条矩形对应的都是一个特征程,每一个箭头都是一种操作(操作类型在图的右下角)。

1. 网络结构讲解

我们从输入开始看

这里是以572×572的单通道的图像为例(说单通道的原因在于第一个长条上面标的是数字1)。

首先我们会先经过一个卷积层(就是第一个蓝色的箭头),这个卷积层的卷积核大小是3×3,后面跟着一个ReLU函数。注意:这个卷积层的步长为1,而且 padding 为0。

所以我们会发现,经过这个卷积层后,该图像的高和宽都会减小,变为了570×570,然后又经过一个卷积层,变成了568×568,channel 为64。(由于这篇论文是15年发表的,当时BN也就是batch normalization 还没火起来,所以当时还没使用到BN这个模块)

接下里就是经过一个下采样 max pool 2×2,池化大小2×2,那么图像的高和宽就会缩小为原来的一半,从568变为了284,channel 依旧不变,是64。

接着,又进行了两个卷积层,从284变成了280,channel 翻倍。(经历完下采样,再进行卷积层的时候,channel就会翻倍)

然后循环往下进行,直到特殊层的高和宽变为32,再经过两个3×3卷积层后,32变为28,channel变为1024。

特征提取到此结束下面是上采样部分

接下来,我们先进行了一个绿色箭头,也就是说上采样 up-conv 2×2 ,这是一个转置卷积。经过转置卷积后,高和宽变为原来的2倍,也就是说从28变为原来的56,channel为原来的一半,也就是512。

但是呢,注意这里有个灰色箭头,copy and crop,是将左边的蓝色特征图进行了裁剪并与之拼接,所以channel=512+512=1024。(之所以裁剪是因为,左边的图是64×64,所以要先把它中心裁剪成56×56.)

然后我们再经过两个3×3卷积层,将channel变为512,再通过一个上采样,高和宽变为原来的两倍,channel减半,但是又通过裁剪拼接,channel依旧是512.

然后循环往下进行,直到变为高宽为388×388,channel变为64,最后再通过一个青蓝色的箭头,conv 1×1,卷积核为1×1的卷积层,最后得到一个388×388×2的一个分割图。

所以,这张网络结构图输入的是572×572,但得到的是388×388那个区域的分割图,并不是针对原图的分割图。

2. 网络结构更改点

但是,我们现在的比较主流的一种实现方式,并没有严格按照论文上的网络结构图。

(1)在卷积层上加了一个padding

        作用:这样我们经过卷积层后就不会更改我们的高和宽

(2)在卷积层和ReLU之间加入了一个BN模块。

        作用:对输入张量的每一个通道都进行归一化操作。

这是一种conv+bn+relu组合。

import torch.nn as nn

conv_bn_relu = nn.Sequential(
    nn.Conv2d(in_channels=2, out_channels=8, kernel_size=3, stride=1, padding=1),
    nn.BatchNorm2d(num_features=16),
    nn.ReLU()
)

上述代码将卷积层、BN层和ReLU层依次组合在一起,形成了一个三层的卷积神经网络模型,该模型输入为一个(样本数,2,高度,宽度)的四维张量,输出为一个(样本数,8,高度,宽度)的四维张量。(kernel_size = 3 是指卷积核为3×3的大小,stride = 1 是指步长为1,padding = 1 有填充) 

如果不懂得 stride 和 padding,可以在CSDN中找找内容,有很多博主讲过。

下面这个博主就讲的很清楚。

CNN中stride(步幅)和padding(填充)的详细理解_cnn stride-CSDN博客文章浏览阅读5.1w次,点赞210次,收藏599次。网上一些解释,我觉还是有点不全面,我梳理一手:步幅:卷积核经过输入特征图的采样间隔填充:在输入特征图的每一边添加一定数目的行列,使得输出的特征图的长、宽 = 输入的特征图的长、宽两个参数的核心:设置步幅的目的:希望减小输入参数的数目,减少计算量设置填充的目的:希望每个输入方块都能作为卷积窗口的中心在边长=5的输入矩阵各边填充1层,全部填充0,采用边长=3的卷积核,全部卷积核的中心构成原输入首先从一个问题入手:问题:一个尺寸 a*a 的特征图,经过 b*b 的卷积层,步幅(stri_cnn stridehttps://blog.csdn.net/weixin_42899627/article/details/108228008

3.论文中的一些图像

(1)下面是论文里面的图2。我们输入的是蓝色线圈起来的方框大小,但我们得到的是黄色线圈住的区域。

如果说我们想要通过红色部分这一区域进行分割得到黄色部分,这样是不可以的。因为这一边缘的蓝色区域的这些像素我们是没有的,所以对于这些缺失的数据,论文作者说这里采用了镜像的原则。(也就是说蓝色区域是以红色线为中心线对原图进行镜像得到的)这样通过镜像处理,我们就可以分割图像边缘位置的信息了。

注意:如果我们要针对一个特别大的图像,也就是非常高分分辨率的图片。如果直接把整张图片放到模型中进行检测,可能我们的显存就要爆了,所以现在比较常见的一种方法:我们每次只去分割一小块区域,然后再分割下一个区域,但是呢,一般情况下,这两个相邻的区域之间会有一个重叠的部分,目的是为了更好的分割这个边界区域的一个信息。

(2)下面这张图是论文里的图3。

图A对应的我们要分割的一个原图像的灰度图;

图B是通过人工标注出来的一个实例分割的标签数据,每个细胞用不同的颜色进行表示;

(其实对于语义分割而言,我们就只有两个类别:一个前景,一个背景,前景是白色,背景是黑色)

图C语义分割图

图D热力图 (细胞与细胞之间的区域权重比较大,是红色的)

(作者说细胞与细胞之间的这些区域分割是有一定的困难,所以作者提出了一个 pixel-wise loss weight 的这么一个方案,也就是说在这些细胞与细胞之间的这些背影区,我们给它施加一个更大的权重,而对于这大片的黑色背影区,我们给它施加一个比较小的权重。比如说我们在计算损失的时候,这些细胞与细胞之间的背影区域,它们所对应的权重要更大一些。)


下节内容是 使用PyTorch搭建U-Net网络并基于DRIVE数据集训练。

  • 30
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值