图像分割Unet算法及其Pytorch实现

这篇具有很好参考价值的文章主要介绍了图像分割Unet算法及其Pytorch实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

UNet是一种用于图像分割的神经网络,由于这个算法前后两个部分在处理上比较对称,类似一个U形,如下图所示,故称之为Unet,论文链接:U-Net: Convolutional Networks for Biomedical Image Segmentation,全文仅8页。

unet分割需要多少数据,# 用Python实现100种智能算法,算法,pytorch,深度学习,Unet,图像分割,Python

从此图可以看出,左边的基础操作是两次 3 × 3 3\times3 3×3卷积后池化,连续4次,图像从 572 × 572 572\times572 572×572变成 32 × 32 32\times32 32×32。右侧则调转过来,以两次 3 × 3 3\times3 3×3卷积核一个 2 × 2 2\times2 2×2上采样卷积作为一组,再来四次,最后恢复成 388 × 388 388\times388 388×388的图像。

实现

整理一下上图,其计算顺序依次是

  1. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2池化
  2. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2池化
  3. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2池化
  4. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2池化
  5. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2上采样,拼接4的结果
  6. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2上采样,拼接3的结果
  7. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2上采样,拼接2的结果
  8. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 2 × 2 2\times2 2×2上采样,拼接1的结果
  9. 3 × 3 3\times3 3×3卷积-> 3 × 3 3\times3 3×3卷积-> 1 × 1 1\times1 1×1卷积

由于两次 3 × 3 3\times3 3×3卷积累计出现多次,故而先将其封装成类,便于后续调用

import torch
import torch.nn as nn
import torch.nn.functional as F

class DoubleConv(nn.Module):
    def __init__(self, inSize, outSize):
        super().__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(inSize, outSize, kernel_size=3, padding=1),
            nn.BatchNorm2d(outSize),
            nn.ReLU(inplace=True),
            nn.Conv2d(outSize, outSize, kernel_size=3, padding=1),
            nn.BatchNorm2d(outSize),
            nn.ReLU(inplace=True)
        )
    def forward(self, x):
        return self.conv(x)

然后分别实现其降采样、上采样以及最终的输出过程,其中降采样没什么好说的,就是两次卷积一次池化,最终输出的 1 × 1 1\times1 1×1卷积当然就更简单了,二者一并实现如下

class Down(nn.Module):
    def __init__(self, inSize, outSize):
        super().__init__()
        self.conv = nn.Sequential(
            nn.MaxPool2d(2),
            DoubleConv(inSize, outSize))

    def forward(self, x):
        return self.conv(x)

class OutConv(nn.Module):
    def __init__(self, inSize, outSize):
        super(OutConv, self).__init__()
        self.conv = nn.Conv2d(inSize, outSize, 1)

    def forward(self, x):
        return self.conv(x)

上采样过程相对来说复杂一点,多了一个拼接操作,故而其forward函数中,除了需要输入被卷积的数据之外,还要输入U形中,与之对应的那部分计算结果

class Up(nn.Module):
    def __init__(self, inSize, outSize):
        super().__init__()

        self.up = nn.UpsamplingBilinear2d(scale_factor=2)
        self.conv = DoubleConv(inSize, outSize)

    def forward(self, x1, x2):
        x1 = self.up(x1)
        x = torch.cat([x2, x1], dim=1)
        return self.conv(x)

最后,将这几个组分拼接成一个UNet

class UNet(nn.Module):
    def __init__(self, nChannel, nClass):
        super(UNet, self).__init__()
        self.inc = DoubleConv(nChannel, 64)
        self.down1 = Down(64, 128)
        self.down2 = Down(128, 256)
        self.down3 = Down(256, 512)
        self.down4 = Down(512, 512)
        self.up1 = Up(1024, 256)
        self.up2 = Up(512, 128)
        self.up3 = Up(256, 64)
        self.up4 = Up(128, 64)
        self.outc = OutConv(64, nClass)

    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)
        return self.outc(x)

数据集

在具体训练之前,需要准备数据集,其中图像存放在image文件夹中,标签存放在label文件夹中,同名的图像和标签文件一一对应。

from PIL import Image
import os
import numpy as np
from torch.utils.data import Dataset

class ImgData(Dataset):
    def __init__(self, data_path):
        self.path = data_path
        self.imgForder = os.path.join(data_path, "image")

    # 加载图像
    def loadImg(self, path):
        img = np.array(Image.open(path))
        return img.reshape(1, *img.shape)

    # 根据index读取图片
    def __getitem__(self, index):
        pImg = os.path.join(self.path, f"image\{index}.png")
        pLabel = os.path.join(self.path, f"label\{index}.png")
        image = self.loadImg(pImg)
        label = self.loadImg(pLabel)
        # 数据标签归一化
        if label.max() > 1:
            label = label / 255
        # 随机翻转图像,增加训练样本
        flipCode = np.random.randint(3)
        if flipCode!=0:
            image = np.flip(image, flipCode).copy()
            label = np.flip(label, flipCode).copy()
        return image, label

    def __len__(self):
        # 返回训练集大小
        return len(os.listdir(self.imgForder))

训练

接下来就是激动人心的训练过程了,UNet采用RMSprop优化算法和BCEWithLogits损失函数,训练函数如下

from torch.utils.data import DataLoader
from torch import optim
import torch.nn as nn

def train(net, device, path, epochs=40, bSize=1, lr=0.00001):
    igmData = ImgData(path)
    train_loader = DataLoader(igmData, bSize, shuffle=True)
    # 优化算法
    optimizer = optim.RMSprop(net.parameters(),
            lr=lr, weight_decay=1e-8, momentum=0.9)

    criterion = nn.BCEWithLogitsLoss()      # 损失函数
    bestLoss = float('inf')                # 最佳loss,初始化为无穷大

    # 训练epochs次
    for epoch in range(epochs):
        net.train()     # 训练模式
        for image, label in train_loader:
            optimizer.zero_grad()
            # 将数据拷贝到device中
            image = image.to(device=device, dtype=torch.float32)
            label = label.to(device=device, dtype=torch.float32)

            pred = net(image)   # 使用网络参数,输出预测结果
            loss = criterion(pred, label)   # 计算损失
            # 保存loss最小的网络参数
            if loss < bestLoss:
                bestLoss = loss
                torch.save(net.state_dict(), 'best_model.pth')

            loss.backward() # 更新参数
            optimizer.step()

        print(epoch, 'Loss/train', loss.item())

接下来调用训练函数,经过40次训练之后,得到51MB的best_model.pth模型文件,此即最佳测试结果

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = UNet(1, 1)
net.to(device=device)
path = "train/"
train(net, device, path)

预测

所谓预测,无非是重新做一次训练,而且不及损失,只需保存被神经网络处理之后的结果即可,下面是预测一张图像的函数,其输入net即为我们训练好的网络,device为设备。

def predictOne(net, device, pRead, pSave):
    img = Image.open(pRead)
    img = np.array(img)
    img = img.reshape(1, 1, *img.shape)

    img = torch.from_numpy(img)
    img = img.to(device=device, dtype=torch.float32)

    pred = net(img)     # 预测
    pred[pred >= 0.5] = 255
    pred[pred < 0.5] = 0

    pred = np.array(pred.data.cpu()[0])[0]
    img = Image.fromarray(pred.astype(np.uint8))
    img.save(pSave)

最后,批量处理预测数据集,test和predict分别是存放测试文件和预测图像的文件夹。

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net = UNet(1, 1)
net.to(device=device)
net.load_state_dict(torch.load('best_model.pth', map_location=device))

net.eval()      # 测试模式
fs = os.listdir('test')
for f in fs:
    pRead = os.path.join('test', f)
    pSave = os.path.join("predict",f)
    predictOne(net, device, pRead, pSave)

预测结果如下,左侧为图像,右侧为标签。

unet分割需要多少数据,# 用Python实现100种智能算法,算法,pytorch,深度学习,Unet,图像分割,Python文章来源地址https://www.toymoban.com/news/detail-813847.html

到了这里,关于图像分割Unet算法及其Pytorch实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 医学图像分割方向优质的论文及其代码【Medical Image Segmentation】UNet、transformer、计算机视觉

      作者:Yifei Chen, Chenyan Zhang, Yifan Ke, Yiyu Huang, Xuezhou Dai, Feiwei Qin   中文摘要: 由于收集过程具有挑战性、标记成本高、信噪比低以及生物医学图像特征复杂,传统的监督学习方法在医学图像分割方面历来遇到一定的限制。 本文提出了一种半监督模型DFCPS,创新性地融合了

    2024年04月13日
    浏览(51)
  • 语义分割系列7-Attention Unet(pytorch实现)

    继前文Unet和Unet++之后,本文将介绍Attention Unet。 Attention Unet地址,《Attention U-Net: Learning Where to Look for the Pancreas》。 Attention Unet发布于2018年,主要应用于医学领域的图像分割,全文中主要以肝脏的分割论证。 Attention Unet主要的中心思想就是提出来Attention gate模块,使用soft-at

    2024年02月06日
    浏览(40)
  • Python Unet ++ :医学图像分割,医学细胞分割,Unet医学图像处理,语义分割

    一,语义分割:分割领域前几年的发展 图像分割是机器视觉任务的一个重要基础任务,在图像分析、自动驾驶、视频监控等方面都有很重要的作用。图像分割可以被看成一个分类任务,需要给每个像素进行分类,所以就比图像分类任务更加复杂。此处主要介绍 Deep Learning-ba

    2024年02月16日
    浏览(63)
  • 【图像分割】Unet系列深度讲解(FCN、UNET、UNET++)

    1.1 背景介绍: 自2015年以来,在生物医学图像分割领域,U-Net得到了广泛的应用,目前已达到四千多次引用。至今,U-Net已经有了很多变体。目前已有许多新的卷积神经网络设计方式,但很多仍延续了U-Net的核心思想,加入了新的模块或者融入其他设计理念。 编码和解码,早在

    2024年02月03日
    浏览(42)
  • UNet语义分割模型的使用-Pytorch

    最近有时间,跑了一下UNet模型,因为自己的深度学习基础不扎实,导致用了一些时间。目前只停留在使用和理解别人模型的基础上,对于优化模型的相关方法还有待学习。 众所周知,UNent是进行语义分割的知名模型,它的U形结构很多人也都见过,但是如果自己没有亲自试过

    2024年02月03日
    浏览(50)
  • UNet-肝脏肿瘤图像语义分割

    目录 一. 语义分割 二. 数据集 三. 数据增强 图像数据处理步骤 CT图像增强方法 :windowing方法 直方图均衡化 获取掩膜图像深度 在肿瘤CT图中提取肿瘤 保存肿瘤数据  四. 数据加载 数据批处理 ​编辑​编辑 数据集加载   五. UNet神经网络模型搭建          单张图片预测图

    2024年02月04日
    浏览(87)
  • 图像分割UNet (1) : 网络结构讲解

    UNet 论文:Convolutional Networks for Biomedical Image Segmentation 这篇论文主要是针对生物医学影像这个领域提出的,所以一提到UNet一般都会联想到医学影像。 UNet它是一个encoder - decoder的结构,那么encoder对应就是这个u型网络左边这半部分,也就是我们特征提取及下采样这部分。decode

    2024年02月07日
    浏览(74)
  • UNET 架构综合指南 | 掌握图像分割--附源码

    在令人兴奋的计算机视觉主题中,图像包含许多秘密和信息,区分和突出显示项目至关重要。图像分割是将图像分割成有意义的区域或对象的过程,在从医学成像到自动驾驶和对象识别等各种应用中至关重要。准确和自动的分割长期以来一直面临挑战,传统方法经常在准确性

    2024年02月13日
    浏览(50)
  • 【Bubbliiiing视频记录】Pytorch 搭建自己的Unet语义分割平台

    b站 地址 语义分割:对图像每个像素点进行分类 常见神经网络处理过程:Encoder提取特征,接着Docoder恢复成原图大小的图片 分为三个部分 主干特征提取部分: 卷积和最大池化的堆叠 获得五个初步有效特征层 加强特征提取部分: 五个初步有效特征层进行上采样 + 特征融合

    2024年02月12日
    浏览(41)
  • 【图像分割】Unet-ConvLstm利用时序信息进行视频分割

    文章: Exploiting Temporality for Semi-Supervised Video Segmentation 代码: https://github.com/mhashas/Exploiting-Temporality-For-Semi-Supervised-Video-Segmentation 理解: 使用单帧标注,对视频进行分割。利用时间维度信息来推断空间信息。将传统FCN转化成时间-空间FCN。 方法: 通过FCN语义分割网络,对时间

    2023年04月27日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包