如何用基于resnet的Unet进行图像分割 基于Pytorch-0.5版本

PyTorch医学图像多任务实战:ResNet/UNet/DeepLabV3+/YOLOv5基线 深度学习在医学影像分析中已成为核心工具,主要涵盖图像分类、语义分割与目标检测三类任务。PyTorch作为主流深度学习框架,提供了从模型定义到训练部署的完整生态。本文以医学图像多任务实验为背景,梳理了ResNet、UNet、DeepLabV3+与YOLOv5四种经典网络的结构原理与适用场景,并讲解了利用PyTorch进行数据准备、环境配置、模型微调与性能评估的完整流程。无论是肺炎X光分类、CT器官分割还是肺结节检测,这套基线方案都能快速搭建并产出可对比的实验结果。文章还强调了医学数据合规、显存优化及实验结果整 阅读详情
AI摘要

本文介绍了一种将ResNet34作为编码器,Unet作为解码器的图像分割模型。该模型针对“少类别”图像分割任务进行了优化,如医学图像分析。文章详细介绍了模型结构,包括使用双线性插值或反卷积进行上采样的解码块。

1、关于Unet

      Unet主要用于医学图像的很多论文中,以及Kaggle竞赛和一些其他竞赛中“少类别”的图像分割。从我做实验的经验来说,像VOC这种类别比较多的分割任务,不容易收敛,效果较为差。

2、Resnet34

     我们的encode部分选择resnet34,decode部分为每一个block制作三层卷积,其中每个的第二层为upsample(bilinear/deconv)

      

#基本的block
class DecoderBlock(nn.Module):
    def __init__(self,
                 in_channels=512,
                 n_filters=256,
                 kernel_size=3,
                 is_deconv=False,
                 ):
        super().__init__()

        if kernel_size == 3:
            conv_padding = 1
        elif kernel_size == 1:
            conv_padding = 0

        # B, C, H, W -> B, C/4, H, W
        self.conv1 = nn.Conv2d(in_channels,
                               in_channels // 4,
                               kernel_size,
                               padding=1,bias=False)
        self.norm1 = nn.BatchNorm2d(in_channels // 4)
        self.relu1 = nonlinearity(inplace=True)

        # B, C/4, H, W -> B, C/4, H, W
        if is_deconv == True:
            self.deconv2 = nn.ConvTranspose2d(in_channels // 4,
                                              in_channels // 4,
                                              3,
                                              stride=2,
                                              padding=1,
                                              output_padding=conv_padding,bias=False)
        else:
            self.deconv2 = nn.Upsample(scale_factor=2,**up_kwargs)

        self.norm2 = nn.BatchNorm2d(in_channels // 4)
        self.relu2 = nonlinearity(inplace=True)

        # B, C/4, H, W -> B, C, H, W
        self.conv3 = nn.Conv2d(in_channels // 4,
                               n_filters,
                               kernel_size,
                               padding=conv_padding,bias=False)
        self.norm3 = nn.BatchNorm2d(n_filters)
        self.relu3 = nonlinearity(inplace=True)

    def forward(self, x):
        x = self.conv1(x)
        x = self.norm1(x)
        x = self.relu1(x)
        x = self.deconv2(x)
        x = self.norm2(x)
        x = self.relu2(x)
        x = self.conv3(x)
        x = self.norm3(x)
        x = self.relu3(x)
        return x


class BasicConv2d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0):
        super(BasicConv2d, self).__init__()
        self.conv = nn.Conv2d(in_planes, out_planes,
                              kernel_size=kernel_size, stride=stride,
                              padding=padding, bias=False)  # verify bias false
        self.bn = nn.BatchNorm2d(out_planes,
                                 eps=0.001,  # value found in tensorflow
                                 momentum=0.1,  # default pytorch value
                                 affine=True)
        self.relu = nn.ReLU(inplace=False)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

接下来,就是模型代码了。

class ResNet34Unet(nn.Module):
    def __init__(self,
                 num_classes,
                 num_channels=3,
                 is_deconv=False,
                 decoder_kernel_size=3,
                 ):
        super().__init__()

        self.mean = (0.485, 0.456, 0.406)
        self.std = (0.229, 0.224, 0.225)

        filters = [64, 128, 256, 512]
        resnet = models.resnet34(pretrained=True)
        self.base_size=512
        self.crop_size=512
        self._up_kwargs={'mode': 'bilinear', 'align_corners': True}
        # self.firstconv = resnet.conv1
        # assert num_channels == 3, "num channels not used now. to use changle first conv layer to support num channels other then 3"
        # try to use 8-channels as first input
        if num_channels == 3:
            self.firstconv = resnet.conv1
        else:
            self.firstconv = nn.Conv2d(num_channels, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3),bias=False)

        self.firstbn = resnet.bn1
        self.firstrelu = resnet.relu
        self.firstmaxpool = resnet.maxpool
        self.encoder1 = resnet.layer1
        self.encoder2 = resnet.layer2
        self.encoder3 = resnet.layer3
        self.encoder4 = resnet.layer4

        # Decoder
        self.center = DecoderBlock(in_channels=filters[3],
                                   n_filters=filters[3],
                                   kernel_size=decoder_kernel_size,
                                   is_deconv=is_deconv)
        self.decoder4 = DecoderBlock(in_channels=filters[3] + filters[2],
                                     n_filters=filters[2],
                                     kernel_size=decoder_kernel_size,
                                     is_deconv=is_deconv)
        self.decoder3 = DecoderBlock(in_channels=filters[2] + filters[1],
                                     n_filters=filters[1],
                                     kernel_size=decoder_kernel_size,
                                     is_deconv=is_deconv)
        self.decoder2 = DecoderBlock(in_channels=filters[1] + filters[0],
                                     n_filters=filters[0],
                                     kernel_size=decoder_kernel_size,
                                     is_deconv=is_deconv)
        self.decoder1 = DecoderBlock(in_channels=filters[0] + filters[0],
                                     n_filters=filters[0],
                                     kernel_size=decoder_kernel_size,
                                     is_deconv=is_deconv)


        self.finalconv = nn.Sequential(nn.Conv2d(filters[0], 32, 3, padding=1, bias=False),
                                       nn.BatchNorm2d(32),
                                       nn.ReLU(),
                                       nn.Dropout2d(0.1, False),
                                       nn.Conv2d(32, num_classes, 1))

    def require_encoder_grad(self, requires_grad):
        blocks = [self.firstconv,
                  self.encoder1,
                  self.encoder2,
                  self.encoder3,
                  self.encoder4]

        for block in blocks:
            for p in block.parameters():
                p.requires_grad = requires_grad

    def forward(self, x):
        # stem
        x = self.firstconv(x)
        x = self.firstbn(x)
        x = self.firstrelu(x)
        x_ = self.firstmaxpool(x)

        # Encoder
        e1 = self.encoder1(x_)
        e2 = self.encoder2(e1)
        e3 = self.encoder3(e2)
        e4 = self.encoder4(e3)

        center = self.center(e4)

        d4 = self.decoder4(torch.cat([center, e3], 1))
        d3 = self.decoder3(torch.cat([d4, e2], 1))
        d2 = self.decoder2(torch.cat([d3, e1], 1))
        d1 = self.decoder1(torch.cat([d2, x], 1))

        f= self.finalconv(d1)
        return tuple([f])

 

ResUnet++ 阅读详情

相关推荐

ResUnet实现(tensorflow2)

  我们将在本篇博客实现Resunet。   首先上Unet图 然后结合Unet和Resnet,就是一个新的网络。 def bn_act(x, act=True): 'batch normalization layer with an optinal activation layer' x = tf.keras.layers.BatchNormalization()(x) ...

m0_37663944的博客 1万+

pytorch实现基于resnet的Unet

resnet可以作为Unet的编码模块,只要把最后的全连接层去掉即可,其它无需改变。 Unet网络的整体结构为编码模块,和解码模块。解码模块要将每个stage模块的中间输出保存下来,以便与对应的解码模块的stage相连接。 Unet的创新之处在于它的解码模块,所以代码实现的时候尤其要关注每个模块的输入输出信道数,解码模块中间几个模块的处理过程相同,可以用for循环处理,而作为解码模块的输入和输出...

weixin_38410551的博客 5603

【医学图像分割网络】之Res U-Net网络PyTorch复现

【医学图像分割网络】之Res U-Net网络PyTorch复现 1.内容 U-Net网络算是医学图像分割领域的开山之作,我接触深度学习到现在大概将近大半年时间,看到了很多基于U-Net网络的变体,后续也会继续和大家一起分享学习。这次分享ResNet+U-Net的一个改进版,ResNet本身就是一个十分优秀的backbone,目前应用仍然十分广泛,我们融合进ResNet后,我们就可以使得U-Net进行迁移学习了。 1.将Resnet作为encoder替换U-Net原始结构 2.U-Net提出时间较早,当时还没

qq_39071739的博客 1万+

ResUNet原理与实现

U-Net的下采样和上采样的设计与许多现在成熟的网络结构异曲同工。因为ImageNet是一个大规模的图像分类数据集,ImageNet预训练权重可以帮助我们在U-Net的训练中使用更好的初始化权重,加快网络的收敛速度并提高网络的泛化能力。但是,U-Net的下采样和上采样的设计思路和现在许多成熟的网络结构相似,因此,可以看作是先驱性的工作。整个网络结构包括了ResNet的残差连接和U-Net的上下采样和跳跃连接思想,可以更好地平衡特征的丰富性和细节的保留性,在图像分割任务中表现出较好的性能。

mefocus的博客 2万+

用Unet实现图像分割(by pytorch)

Segmentation Figure1来自CamVid database,专为目标识别(Object Dection)和图像分割(Image Segmentation)提供训练数据的网站。从图中可以看出,segmentation将图像中不同个体用不同颜色来标记,这里不同的颜色就代表不同的分类,例如红色就是分类1,蓝色就是分类2,可以看出,它就是像素级的图像识别(Image Identifica...

cedi9117的博客 2万+

Unet系列模型对比:从基础Unet到ResNet+Unet++的性能提升全解析(PyTorch版)

本文深入解析了Unet系列模型的演进历程,从基础Unet到融合ResNet的改进版本,再到Unet++的巢状结构创新。通过PyTorch实现的量化指标对比,详细展示了各架构在医学影像分割任务中的性能差异,为开发者提供实用的技术选型指南。特别探讨了ResNet模块如何提升Unet的深度和梯度流动效率。

yellow的专栏 892

深度学习| ResNet和ResUnet

快速理解ResNet和RestUnet。

qq_40306845的博客 1万+

PyTorch医学图像毕设实战:ResNet、UNet、DeepLabV3+与YOLOv5多任务完整复现

深度学习在医学影像分析中的应用日益广泛,核心任务可归纳为图像分类、语义分割与目标检测三大方向。ResNet作为分类任务的经典卷积神经网络,通过残差结构缓解深层梯度消失问题;UNet与DeepLabV3+分别以跳跃连接和空洞卷积实现像素级分割;YOLOv5则凭借高效的目标检测框架成为病灶定位的常用工具。理解这些模型的原理与数据流,是搭建医学图像处理系统的关键。本文围绕PyTorch框架,系统梳理从环境配置、数据集预处理、模型构建到训练评估的完整流程,并展示如何将分类、分割、检测串联为多阶段推理链路,帮助开发者

weixin_34126557的博客 326

【大作业-52】基于改进UNET的细胞图像分割系统

本摘要介绍了基于改进UNET的细胞图像分割系统,该系统整合了UNET、UNET++、R2NET和Attention UNET等多种网络架构,并针对细胞图像分割任务进行了优化。项目提供了完整的配置指南,包括数据集准备、环境配置和模型验证步骤,支持在本地高效运行。系统通过深度学习技术实现了高精度的细胞图像分割,能够有效处理复杂背景和细胞重叠等问题。评估指标包括精确度、召回率、mIoU、mPA和Dice系数,全面衡量模型性能。项目附带图形化界面,便于用户直观操作和结果分析,为生物医学研究提供了实用的图像分析工具。

dejahu的博客 947

医学图像深度学习毕设实战:ResNet分类+UNet分割+YOLOv5检测

深度学习方法在医学影像分析中已成为解决分类、分割和检测任务的主流技术。卷积神经网络通过残差连接、编码器-解码器结构以及目标检测框架,分别实现疾病诊断、病灶定位和异常识别。ResNet利用残差学习缓解深层网络退化,UNet通过跳跃连接保留细节信息,YOLOv5则平衡速度与精度。这些技术可应用于肺炎X光分类、眼底图像分割、CT肺结节检测等常见医学场景。本文围绕PyTorch实现,梳理了从环境配置、数据集组织到模型训练与效果验证的完整流程,覆盖分类、分割、检测三大任务的代码结构和训练要点,为医学图像相关毕业设计提

weixin_34099526的博客 683

ResNet34+Unet 架构对比:3种主流实现方案(PyTorch/SMP/Keras)性能与易用性评测

本文深度评测了ResNet34+Unet架构在PyTorch原生、SMP库和Keras三种实现方案下的性能与易用性。通过CamVid数据集测试,从代码复杂度、训练效率、推理性能和扩展性四个维度对比分析,为开发者提供技术选型参考。结果显示,SMP库方案在训练速度和内存占用上表现最优,而PyTorch原生实现则更适合需要高度定制的场景。

weixin_33726313的博客 430

UNet++图像分割算法解析:从架构原理到PyTorch实战

图像分割是计算机视觉的核心任务,旨在为图像中的每个像素分配语义标签,其关键在于实现像素级的精确分类与边界定位。其技术原理通常基于编码器-解码器架构,通过卷积神经网络提取多尺度特征并进行融合重建。这一技术的核心价值在于为自动驾驶、医学影像分析和工业质检等场景提供高精度的像素级理解能力。针对传统UNet等模型在特征融合时存在的语义鸿沟问题,UNet++通过引入密集嵌套跳跃连接和深度监督机制,实现了渐进式的多尺度特征融合,有效提升了小目标与复杂边界的分割精度。本文以PyTorch框架为例,详细解析了UNet++的

cong84596496的博客 391

Res-Unet调参实战:在PyTorch里复现并优化你的图像分割模型

本文详细介绍了如何在PyTorch中复现并优化Res-Unet图像分割模型,重点解析了残差结构的实现差异、解码器优化技巧以及针对不同数据集的调参策略。通过实战案例,帮助开发者掌握从Keras到PyTorch的框架迁移方法,提升模型在医学影像、卫星图像等场景中的性能表现。

weixin_30580341的博客 457

迁移学习:自己预训练的resnet18模型在Unet上的实现(pytorch版)(有待完善)

文末有resnet18网络结构 下面上一张unet的网络结构 然后根据以上的网络结构图,搭建pytorch模型 def Conv2RELU(inchannels, outchannels, kernel, padding): return nn.Sequential( nn.Conv2d(inchannels, outchannels, kernel, padding=padding), nn.ReLU(inplace=True), ) cla.

ye1391的博客 4640

3种 ResNet34+Unet 实现方案对比:从零手写、SMP库到Hugging Face Hub

本文全面对比了ResNet34+Unet的三种实现方案:从零手写、使用SMP库和Hugging Face Hub预训练模型。详细分析了每种方案在开发效率、模型性能和定制灵活性上的优劣,帮助开发者根据项目需求选择最适合的技术路线。特别适合计算机视觉领域从事语义分割任务的开发者参考。

weixin_30326515的博客 414

UNet++图像分割:密集连接与深度监督原理及PyTorch实战

图像分割是计算机视觉的核心任务之一,旨在将图像划分为具有不同语义的区域。其基本原理是通过编码器提取多尺度特征,再通过解码器重建高分辨率分割图。传统U-Net等编码器-解码器架构通过跳跃连接融合浅层细节与深层语义,但在处理边界模糊、多尺度目标时存在语义鸿沟。UNet++通过引入密集嵌套的跳跃连接,构建了渐进式特征融合的金字塔结构,有效弥合了不同层级特征间的语义差距,提升了分割精度。该技术尤其适用于医学图像分割、遥感影像分析等对边界精度要求高的场景。本文以PyTorch实战为例,结合深度监督机制,详细解析了UN

weixin_33834137的博客 427

基于python实现resnet_基于ResNet的UNet的Pytorch实现

defconvolution_block(x,filters,size,strides=(1,1),padding='same',activation=True):x=Conv2D(filters,size,strides=strides,padding=padding)(x)x=BatchNormalization()(x)ifactivation==True:x=Activation('rel...

weixin_34207865的博客 856

UNet图像分割全解析:从结构原理到PyTorch实战调参

图像分割是计算机视觉中的像素级分类任务,要求同时兼顾空间精度与上下文语义。全卷积网络通过编码器-解码器结构实现端到端预测,而UNet利用跳跃连接把浅层细节与深层语义拼接融合,在小样本和边界敏感场景下具有稳定优势。在PyTorch工程实现中,上采样方式、Dice与交叉熵损失组合、参数量与显存估算都会直接影响收敛速度和分割质量。该方案广泛用于医学影像、遥感地块提取与工业质检,并从结构拆解、代码实现、调参改进到常见避坑提供可复现的实践参考。

weixin_33755557的博客 364
上一篇: dataset for semantic sgementation ,图像分割任务中VOC的augment dataset 到底在哪?
下一篇: LeetCode 3Sum python
Jie Ou
博客等级 码龄10年 176粉丝 111原创
评论 24
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值