Unet论文研读以及pytorch下环境搭建


前言

Unet多应用于CNN中图像分割领域。对于小数据集也有很好的性能。

一、Unet

1.Unet网络框架

   论文中只用分割出细胞边界,所以最后使用的是2个1*1卷积得到背景和目标两个。如果是多目标分割,根据分割目标的种类来决定使用1*1的卷积的数量来输出Segmentation map.注:对于多目标的Label标注:可以使用不同颜色,然后使用One-hot编码生成Label进行训练。
Unet network architecture

2.Unet运用的 Skip connection

语义分割网络在特征融合时也有2种办法:
(1)FCN式的逐点相加,也叫加操作。如图1。
(2)U-Net式的channel维度拼接融合,也叫叠操作。如图2。

FCN的Skip connection

图1 FCN中Skip connection方式

Unet的Skip connection

图2 Unet中Skip connection方式

Copy and crop操作: 经过两次3*3卷积后,大小变为28×28,然后经过一次2*2卷积,变为56×56,这时和左侧大小为64×64的图像进行维度的叠加,但是由于图像大小不同,需要将左侧的64×64大小的图像裁剪为56×56大小,此处的裁剪是合理的,原因看下一步3中讲的Overlap-tile策略。

3.Unet应用的Overlap-tile策略

   可以发现Unet论文中输入的图像是572×572但是输出图像确实388×388.这是不是就意味着原图像存在信息丢失的现象呢?实际上不是的,经过了no padding的卷积操作,输入图像和输出图像肯定是不一样的尺寸,但是Unet在论文中提及了一种策略–Overlap-tile,将图像进行镜像扩充和输入网络,这样经过卷积后得到的输出图像和实际需要提取的图像是相同的尺寸。
   例如下图,实际需要分割的图像是黄色框所选中部分,但是输入到网络中的图像是蓝色部分,对空白部分进行镜像填充,这样经过网络后所得到的的输出大小尺寸适合实际需要分割的图像大小是一样的。
Overkap-tile

4.Unet的LossFunction

   Unet训练时对细胞边界的像素点增加了权重,使用加权损失函数,可以更注重细胞边界分割。此处d1,d2个人不清楚是使用什么计算的距离
LossFunction

二、Pytorch环境搭建及Training

1.相关资源

数据集:https://github.com/Rwzzz/Unet
代码:https://github.com/Rwzzz/Unet

2.实验结果

  • 训练集大小30张图片
  • 训练时间epochs=40,batch_size=1
  • 训练环境 pytorch1.7

在实际训练中为了方便,没有采用Unet中的策略。
统一输入和输出尺寸的两种方案:
1.padding='same’形式
2.对小分辨率特征图进行填充后进行维度的连接。

Loss值

图1.训练的Loss

分割图

图2.测试集预测结果

总结

    Unet模型简单,并且使用较少的数据集,可以达到非常理想的分割效果,对于医学和其他一些数据集比较少的领域优势很大。

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用PyTorch搭建UNet,可以按照以下步骤进行: 1. 导入必要的模块: ```python import torch import torch.nn as nn import torch.nn.functional as F ``` 2. 定义UNet的核心模块: ```python class DoubleConv(nn.Module): def __init__(self, in_channels, out_channels): super(DoubleConv, self).__init__() self.conv = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True), nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True) ) def forward(self, x): return self.conv(x) ``` 3. 定义UNet的编码器: ```python class UNet(nn.Module): def __init__(self, in_channels, out_channels): super(UNet, self).__init__() self.down1 = DoubleConv(in_channels, 64) self.down2 = DoubleConv(64, 128) self.down3 = DoubleConv(128, 256) self.down4 = DoubleConv(256, 512) self.up1 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2) self.up2 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2) self.up3 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2) self.up4 = nn.ConvTranspose2d(64, out_channels, kernel_size=2, stride=2) def forward(self, x): x1 = self.down1(x) x2 = self.down2(F.max_pool2d(x1, 2)) x3 = self.down3(F.max_pool2d(x2, 2)) x4 = self.down4(F.max_pool2d(x3, 2)) x = self.up1(x4) x = self.up2(torch.cat([x, x3], dim=1)) x = self.up3(torch.cat([x, x2], dim=1)) x = self.up4(torch.cat([x, x1], dim=1)) return x ``` 4. 创建UNet实例并定义输入输出通道数: ```python model = UNet(in_channels=3, out_channels=1) ``` 这是一个基本的UNet模型,你可以根据自己的需求进行修改和扩展。记得在训练之前,要根据你的任务定义损失函数和优化器。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值