Unet网络架构详解
创作时间:
作者:
@小白创作中心
Unet网络架构详解
引用
CSDN
1.
https://blog.csdn.net/weixin_40641178/article/details/143460158
Unet是一种用于图像分割的深度学习网络架构,其核心特点是通过编码器-解码器结构实现特征的提取和还原,并通过"copy and crop"操作实现高分辨率特征图和低分辨率特征图的融合。本文将从零开始,详细讲解Unet网络的实现过程。
整体架构图
网络讲解
编码器部分
Unet的编码器部分由多个卷积块组成,每个卷积块包含两个卷积层和一个ReLU激活函数,最后接一个最大池化层。具体实现如下:
class DoubleConv(nn.Module):
"""(convolution => [BN] => ReLU) * 2"""
def __init__(self, in_channels, out_channels, mid_channels=None):
super().__init__()
if not mid_channels:
mid_channels = out_channels
self.double_conv = nn.Sequential(
nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1),
nn.BatchNorm2d(mid_channels),
nn.ReLU(inplace=True),
nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True)
)
def forward(self, x):
return self.double_conv(x)
class Down(nn.Module):
"""Downscaling with maxpool then double conv"""
def __init__(self, in_channels, out_channels):
super().__init__()
self.maxpool_conv = nn.Sequential(
nn.MaxPool2d(2),
DoubleConv(in_channels, out_channels)
)
def forward(self, x):
return self.maxpool_conv(x)
解码器部分
解码器部分主要由上采样层和卷积层组成。上采样层可以使用转置卷积或双线性插值,然后通过卷积层进行特征融合。具体实现如下:
class Up(nn.Module):
"""Upscaling then double conv"""
def __init__(self, in_channels, out_channels, bilinear=True):
super().__init__()
# if bilinear, use the normal convolutions to reduce the number of channels
if bilinear:
self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) # 双线性插值
self.conv = DoubleConv(in_channels, out_channels, in_channels // 2)
else:
self.up = nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size=2, stride=2) # 转置卷积
self.conv = DoubleConv(in_channels, out_channels)
def forward(self, x1, x2):
x1 = self.up(x1)
# input is CHW
diffY = x2.size()[2] - x1.size()[2]
diffX = x2.size()[3] - x1.size()[3]
x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
diffY // 2, diffY - diffY // 2])
x = torch.cat([x2, x1], dim=1)
return self.conv(x)
输出层
最后通过一个1x1的卷积层输出最终的分割结果:
class OutConv(nn.Module):
def __init__(self, in_channels, out_channels):
super(OutConv, self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)
def forward(self, x):
return self.conv(x)
整体网络结构
将上述组件组合成完整的Unet网络:
class UNet(nn.Module):
def __init__(self, args, n_channels, n_classes, bilinear=True):
super(UNet, self).__init__() # 简单点讲:就是子类使用父类的初始化方法进行初始化,这会使得代码非常的整洁
self.n_channels = n_channels
self.n_classes = n_classes
self.bilinear = bilinear
"""DoubleConv <-> (convolution => [BN] => ReLU) * 2"""
self.inc = DoubleConv(n_channels, 64)
self.down1 = Down(64, 128)
self.down2 = Down(128, 256)
self.down3 = Down(256, 512)
factor = 2 if bilinear else 1
self.down4 = Down(512, 1024 // factor)
self.up1 = Up(1024, 512 // factor, bilinear)
self.up2 = Up(512, 256 // factor, bilinear)
self.up3 = Up(256, 128 // factor, bilinear)
self.up4 = Up(128, 64, bilinear)
self.outc = OutConv(64, n_classes)
def forward(self, x):
x1 = self.inc(x)
x2 = self.down1(x1)
x3 = self.down2(x2)
x4 = self.down3(x3)
x5 = self.down4(x4)
x = self.up1(x5, x4)
x = self.up2(x, x3)
x = self.up3(x, x2)
x = self.up4(x, x1)
logits = self.outc(x)
return logits
"Copy and Crop"操作
在Unet的解码器部分,需要将上采样得到的特征图与编码器对应位置的特征图进行拼接。由于上采样后的特征图尺寸可能与编码器特征图尺寸不匹配,因此需要进行"copy and crop"操作,即对编码器特征图进行中心裁剪,使其与上采样特征图尺寸一致,然后再进行拼接。
# 中心裁剪函数
def crop_tensor(self, tensor, target_tensor):
target_size = target_tensor.size()[2]
tensor_size = tensor.size()[2]
delta = tensor_size - target_size
delta = delta // 2
return tensor[:, :, delta:tensor_size - delta, delta:tensor_size - delta]
# 拼接操作示例
up1 = self.up_conv_1(x10) # 得到56*56*512
crop1 = self.crop_tensor(x8, up1) # 对x8进行裁剪
up_1 = torch.cat([crop1, up1], dim=1) # 拼接操作
总结
Unet网络通过编码器-解码器结构实现特征的提取和还原,并通过"copy and crop"操作实现高分辨率特征图和低分辨率特征图的融合。这种结构在医学图像分割、遥感图像分析等领域有广泛应用。
热门推荐
新手投资者如何避免股市超买陷阱?
成都82路公交带你打卡古迹景点
自来水可以直接浇花吗
【韶山一日游全攻略】轻松游遍,避坑指南!
北京朝阳区两大庙会热闹迎春节
开封旅游攻略:3天2晚深度游,2天1晚特种兵玩法,清明上河园最强游玩时间表
【民航安检科普】为什么我的充电宝不能带上飞机?
房间太潮湿,如何有效除湿?
钟繇VS王羲之:谁的楷书更美?
钟繇《宣示表》:书法界的米其林三星推荐
钟繇:三国时期的楷书鼻祖传奇
钟繇:三国时期的楷书鼻祖
标杆分析法(Benchmarking Analysis Method)
马齿苋营养价值、活性成分和药理活性研究进展
南宁出发一小时可达10个目的地,动车带你轻松畅游广西
中式别墅装饰艺术:传统与现代的完美融合
新乡化工企业环保升级,蓝天保卫战显成效
探索云南野象谷:门票价格及旅行建议
秋冬脑溢血康复全攻略:从生活调理到专业治疗
当心爱的“土琵琶”再次弹起
创业过程中的成本控制和利润最大化策略
产品定价模型:用数学建模实现利润最大化
二元一次方程在利润计算中的应用
北京科技风格MG动画制作的8个特殊之处
如何做好创意项目管理:给创意项目团队的5个阶段建议
王羲之PK王献之:谁是书圣?
普洱茶饮用后胃部不适:探究原因与解决方法
历史的“弹幕”:层累泰山经石峪
《小鲤鱼历险记》角色设计大揭秘!
《小鲤鱼历险记》:一首唱响勇气与梦想的动画赞歌