0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

UNet和UNet++:医学影像经典分割网络对比

OpenCV学堂 来源:AI公园 作者:AI公园 2022-04-25 10:38 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

导读

在不同的任务上对比了UNet和UNet++以及使用不同的预训练编码器的效果。

介绍

语义分割是计算机视觉的一个问题,我们的任务是使用图像作为输入,为图像中的每个像素分配一个类。在语义分割的情况下,我们不关心是否有同一个类的多个实例(对象),我们只是用它们的类别来标记它们。有多种关于不同计算机视觉问题的介绍课程,但用一张图片可以总结不同的计算机视觉问题:

5891bd82-c3e2-11ec-bce3-dac502259ad0.png

语义分割在生物医学图像分析中有着广泛的应用:x射线、MRI扫描、数字病理、显微镜、内窥镜等。https://grand-challenge.org/challenges上有许多不同的有趣和重要的问题有待探索。

从技术角度来看,如果我们考虑语义分割问题,对于N×M×3(假设我们有一个RGB图像)的图像,我们希望生成对应的映射N×M×k(其中k是类的数量)。有很多架构可以解决这个问题,但在这里我想谈谈两个特定的架构,Unet和Unet++。

有许多关于Unet的评论,它如何永远地改变了这个领域。它是一个统一的非常清晰的架构,由一个编码器和一个解码器组成,前者生成图像的表示,后者使用该表示来构建分割。每个空间分辨率的两个映射连接在一起(灰色箭头),因此可以将图像的两种不同表示组合在一起。并且它成功了!

58bd8a7a-c3e2-11ec-bce3-dac502259ad0.png

接下来是使用一个训练好的编码器。考虑图像分类的问题,我们试图建立一个图像的特征表示,这样不同的类在该特征空间可以被分开。我们可以(几乎)使用任何CNN,并将其作为一个编码器,从编码器中获取特征,并将其提供给我们的解码器。据我所知,Iglovikov & Shvets 使用了VGG11和resnet34分别为Unet解码器以生成更好的特征和提高其性能。

58dcf5cc-c3e2-11ec-bce3-dac502259ad0.png

TernausNet (VGG11 Unet)

Unet++是最近对Unet体系结构的改进,它有多个跳跃连接。

58f2818a-c3e2-11ec-bce3-dac502259ad0.png

根据论文, Unet++的表现似乎优于原来的Unet。就像在Unet中一样,这里可以使用多个编码器(骨干)来为输入图像生成强特征。

我应该使用哪个编码器?

这里我想重点介绍Unet和Unet++,并比较它们使用不同的预训练编码器的性能。为此,我选择使用胸部x光数据集来分割肺部。这是一个二值分割,所以我们应该给每个像素分配一个类为“1”的概率,然后我们可以二值化来制作一个掩码。首先,让我们看看数据。

5913b238-c3e2-11ec-bce3-dac502259ad0.png

来自胸片X光数据集的标注数据的例子

这些是非常大的图像,通常是2000×2000像素,有很大的mask,从视觉上看,找到肺不是问题。使用segmentation_models_pytorch库,我们为Unet和Unet++使用100+个不同的预训练编码器。我们做了一个快速的pipeline来训练模型,使用Catalyst (pytorch的另一个库,这可以帮助你训练模型,而不必编写很多无聊的代码)和Albumentations(帮助你应用不同的图像转换)。

  1. 定义数据集和增强。我们将调整图像大小为256×256,并对训练数据集应用一些大的增强。
importalbumentationsasA
fromtorch.utils.dataimportDataset,DataLoader
fromcollectionsimportOrderedDict

classChestXRayDataset(Dataset):
def__init__(
self,
images,
masks,
transforms):
self.images=images
self.masks=masks
self.transforms=transforms

def__len__(self):
return(len(self.images))

def__getitem__(self,idx):
"""Willloadthemask,getrandomcoordinatesaround/withthemask,
loadtheimagebycoordinates
"""
sample_image=imread(self.images[idx])
iflen(sample_image.shape)==3:
sample_image=sample_image[...,0]
sample_image=np.expand_dims(sample_image,2)/255
sample_mask=imread(self.masks[idx])/255
iflen(sample_mask.shape)==3:
sample_mask=sample_mask[...,0]
augmented=self.transforms(image=sample_image,mask=sample_mask)
sample_image=augmented['image']
sample_mask=augmented['mask']
sample_image=sample_image.transpose(2,0,1)#channelsfirst
sample_mask=np.expand_dims(sample_mask,0)
data={'features':torch.from_numpy(sample_image.copy()).float(),
'mask':torch.from_numpy(sample_mask.copy()).float()}
return(data)

defget_valid_transforms(crop_size=256):
returnA.Compose(
[
A.Resize(crop_size,crop_size),
],
p=1.0)

deflight_training_transforms(crop_size=256):
returnA.Compose([
A.RandomResizedCrop(height=crop_size,width=crop_size),
A.OneOf(
[
A.Transpose(),
A.VerticalFlip(),
A.HorizontalFlip(),
A.RandomRotate90(),
A.NoOp()
],p=1.0),
])

defmedium_training_transforms(crop_size=256):
returnA.Compose([
A.RandomResizedCrop(height=crop_size,width=crop_size),
A.OneOf(
[
A.Transpose(),
A.VerticalFlip(),
A.HorizontalFlip(),
A.RandomRotate90(),
A.NoOp()
],p=1.0),
A.OneOf(
[
A.CoarseDropout(max_holes=16,max_height=16,max_width=16),
A.NoOp()
],p=1.0),
])


defheavy_training_transforms(crop_size=256):
returnA.Compose([
A.RandomResizedCrop(height=crop_size,width=crop_size),
A.OneOf(
[
A.Transpose(),
A.VerticalFlip(),
A.HorizontalFlip(),
A.RandomRotate90(),
A.NoOp()
],p=1.0),
A.ShiftScaleRotate(p=0.75),
A.OneOf(
[
A.CoarseDropout(max_holes=16,max_height=16,max_width=16),
A.NoOp()
],p=1.0),
])

defget_training_trasnforms(transforms_type):
iftransforms_type=='light':
return(light_training_transforms())
eliftransforms_type=='medium':
return(medium_training_transforms())
eliftransforms_type=='heavy':
return(heavy_training_transforms())
else:
raiseNotImplementedError("Notimplementedtransformationconfiguration")
  1. 定义模型和损失函数。这里我们使用带有regnety_004编码器的Unet++,并使用RAdam + Lookahed优化器使用DICE + BCE损失之和进行训练。
importtorch
importsegmentation_models_pytorchassmp
importnumpyasnp
importmatplotlib.pyplotasplt
fromcatalystimportdl,metrics,core,contrib,utils
importtorch.nnasnn
fromskimage.ioimportimread
importos
fromsklearn.model_selectionimporttrain_test_split
fromcatalyst.dlimportCriterionCallback,MetricAggregationCallback
encoder='timm-regnety_004'
model=smp.UnetPlusPlus(encoder,classes=1,in_channels=1)
#model.cuda()
learning_rate=5e-3
encoder_learning_rate=5e-3/10
layerwise_params={"encoder*":dict(lr=encoder_learning_rate,weight_decay=0.00003)}
model_params=utils.process_model_params(model,layerwise_params=layerwise_params)
base_optimizer=contrib.nn.RAdam(model_params,lr=learning_rate,weight_decay=0.0003)
optimizer=contrib.nn.Lookahead(base_optimizer)
scheduler=torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,factor=0.25,patience=10)
criterion={
"dice":DiceLoss(mode='binary'),
"bce":nn.BCEWithLogitsLoss()
}
  1. 定义回调函数并训练!
callbacks=[
#Eachcriterioniscalculatedseparately.
CriterionCallback(
input_key="mask",
prefix="loss_dice",
criterion_key="dice"
),
CriterionCallback(
input_key="mask",
prefix="loss_bce",
criterion_key="bce"
),

#Andonlythenweaggregateeverythingintooneloss.
MetricAggregationCallback(
prefix="loss",
mode="weighted_sum",
metrics={
"loss_dice":1.0,
"loss_bce":0.8
},
),

#metrics
IoUMetricsCallback(
mode='binary',
input_key='mask',
)

]

runner=dl.SupervisedRunner(input_key="features",input_target_key="mask")
runner.train(
model=model,
criterion=criterion,
optimizer=optimizer,
scheduler=scheduler,
loaders=loaders,
callbacks=callbacks,
logdir='../logs/xray_test_log',
num_epochs=100,
main_metric="loss",
minimize_metric=True,
verbose=True,
)

如果我们用不同的编码器对Unet和Unet++进行验证,我们可以看到每个训练模型的验证质量,并总结如下:

59583070-c3e2-11ec-bce3-dac502259ad0.png

Unet和Unet++验证集分数

我们注意到的第一件事是,在所有编码器中,Unet++的性能似乎都比Unet好。当然,有时这种差异并不是很大,我们不能说它们在统计上是否完全不同 —— 我们需要在多个folds上训练,看看分数分布,单点不能证明任何事情。第二,resnest200e显示了最高的质量,同时仍然有合理的参数数量。有趣的是,如果我们看看https://paperswithcode.com/task/semantic-segmentation,我们会发现resnest200在一些基准测试中也是SOTA。

好的,但是让我们用Unet++和Unet使用resnest200e编码器来比较不同的预测。

597a5e7a-c3e2-11ec-bce3-dac502259ad0.png

Unet和Unet++使用resnest200e编码器的预测。左图显示了两种模型的预测差异

在某些个别情况下,Unet++实际上比Unet更糟糕。但总的来说似乎更好一些。

一般来说,对于分割网络来说,这个数据集看起来是一个容易的任务。让我们在一个更难的任务上测试Unet++。为此,我使用PanNuke数据集,这是一个带标注的组织学数据集(205,343个标记核,19种不同的组织类型,5个核类)。数据已经被分割成3个folds。

59e83314-c3e2-11ec-bce3-dac502259ad0.png

PanNuke样本的例子

我们可以使用类似的代码在这个数据集上训练Unet++模型,如下所示:

5a230200-c3e2-11ec-bce3-dac502259ad0.png

验证集上的Unet++得分

我们在这里看到了相同的模式 - resnest200e编码器似乎比其他的性能更好。我们可以用两个不同的模型(最好的是resnest200e编码器,最差的是regnety_002)来可视化一些例子。

5a37ee2c-c3e2-11ec-bce3-dac502259ad0.png

resnest200e和regnety_002的预测

我们可以肯定地说,这个数据集是一项更难的任务 —— 不仅mask不够精确,而且个别的核被分配到错误的类别。然而,使用resnest200e编码器的Unet++仍然表现很好。

总结

这不是一个全面语义分割的指导,这更多的是一个想法,使用什么来获得一个坚实的基线。有很多模型、FPN,DeepLabV3, Linknet与Unet有很大的不同,有许多Unet-like架构,例如,使用双编码器的Unet,MAnet,PraNet,U²-net — 有很多的型号供你选择,其中一些可能在你的任务上表现的比较好,但是,一个坚实的基线可以帮助你从正确的方向上开始。

审核编辑 :李倩
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编码器
    +关注

    关注

    45

    文章

    3831

    浏览量

    138653
  • 医学影像
    +关注

    关注

    1

    文章

    112

    浏览量

    17619

原文标题:UNet 和 UNet++:医学影像经典分割网络对比

文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RK3576 yolo11-seg训练部署教程

    结构和分割头设计,实现了像素级的精确目标检测与分割,适用于自动驾驶、医学影像、工业检测等对精度和速度要求苛刻的场景。本教程针对目标分割算法yolov11seg的训练和部
    的头像 发表于 07-25 15:21 196次阅读
    RK3576 yolo11-seg训练部署教程

    【正点原子STM32MP257开发板试用】基于 DeepLab 模型的图像分割

    :https://arxiv.org/pdf/1706.05587 应用场景 自动驾驶:用于道路、车辆、行人等目标的精确分割医学影像分析:用于肿瘤、器官等区域的分割。 卫星图像分析:用于土地覆盖、建筑物
    发表于 06-21 21:11

    东软集团入选国家数据局数据标注优秀案例

    近日,东软飞标医学影像标注平台在国家数据局发布数据标注优秀案例集名单中排名第一(案例名称“多模态医学影像智能数据标注平台”)。评选专家认为东软案例取得了显著成效,一方面,抢占了自主可控的数据标注技术
    的头像 发表于 05-09 14:37 589次阅读

    RK3576 yolov11-seg训练部署教程

    级的精确目标检测与分割,适用于自动驾驶、医学影像、工业检测等对精度和速度要求苛刻的场景。        本教程针对目标分割算法yolov11 seg的训练和部署到EASY-EAI-Orin-nano(RK3576)进行说明,而
    的头像 发表于 04-16 09:43 981次阅读
    RK3576 yolov11-seg训练部署教程

    医疗设备工业成像采集卡:提升医疗影像诊断水平的关键组件

    依据。随着医学影像技术的不断进步,例如计算机断层扫描(CT)、磁共振成像(MRI)、超声成像(Ultrasound)以及内窥镜成像等,对成像采集卡的性能要求也越来越
    的头像 发表于 03-19 15:55 360次阅读
    医疗设备工业成像采集卡:提升医疗<b class='flag-5'>影像</b>诊断水平的关键组件

    无法在在DL Workbench中导入unet-camvid-onnx-0001模型之前下载CamVid数据集?

    无法在在 DL Workbench 中导入 unet-camvid-onnx-0001 模型之前下载 CamVid 数据集
    发表于 03-06 07:12

    中信建投报告泄密,AI硬件正在重塑医疗影像与IVD领域的未来

    《2025医疗科技趋势报告》中预判的刚性需求。报告还指出,至2025年,医学影像与体外诊断(IVD)领域将迎来AI应用的深化期,其中AI硬件则会是推动这一变革的关键
    的头像 发表于 02-25 18:03 507次阅读
    中信建投报告泄密,AI硬件正在重塑医疗<b class='flag-5'>影像</b>与IVD领域的未来

    三维测量在医疗领域的应用

    三维测量在医疗领域的应用十分广泛,为医疗诊断、治疗及手术规划等提供了重要的技术支持。以下是对三维测量在医疗领域应用的分析: 一、医学影像的三维重建与分析 CT、MRI等影像的三维重建 : 三维测量
    的头像 发表于 12-30 15:21 774次阅读

    英特尔助力东软PACS&amp;RIS赋能三维可视化与AI辅助诊断

    行软件优化,我们有效了提升了系统性能,在此基础上,我们将以一体化、智能化、专科化为理念,以PACS/RIS产品能力为核心向外延伸,构建智慧医学影像解决方案。” 概 述 医学影像不仅是临床诊断的重要依据、医学决策的重要指导,同时也
    的头像 发表于 12-07 10:45 1109次阅读
    英特尔助力东软PACS&amp;RIS赋能三维可视化与AI辅助诊断

    经典图神经网络(GNNs)的基准分析研究

    本文简要介绍了经典图神经网络(GNNs)的基准分析研究,发表在 NeurIPS 2024。 文章回顾了经典 GNNs 模型在节点分类任务上的表现,结果发现过去 SOTA 图学习模型报告的性能优越
    的头像 发表于 11-27 09:16 869次阅读
    <b class='flag-5'>经典</b>图神经<b class='flag-5'>网络</b>(GNNs)的基准分析研究

    东软发布新一代医学影像解决方案

    近日,东软全新发布新一代医学影像解决方案,以智能化为核心,以数据引擎为驱动,面向未来医学影像行业的发展需求,全新定义医学影像的产品价值,推动医学影像信息化的全面升级与一体化融合。这是东
    的头像 发表于 11-25 09:32 625次阅读

    东软医疗光子计数CT获得革命性突破

    近日,由东软集团旗下的创新公司东软医疗自主研发的国产光子计数CT获得革命性突破,首幅人体影像成功出图!这不仅是东软医疗自主创新的再次突破,更是中国在超高端医学影像设备领域具有里程碑意义的重大突破!
    的头像 发表于 11-06 14:25 1213次阅读

    Dell PowerScale数据湖助力医研一体化建设

    近年来,医疗影像设备不断向更高水平和精密化发展,推动医疗服务向更高更快的品质发展。基于医学影像多学科会诊的协作、智能辅助诊断、智能质控、智能术前规划,将快速推进各项医学科研成果进行规范化的临床应用与转化。
    的头像 发表于 10-16 10:13 726次阅读

    三维可视化技术的应用现状和发展前景

    工程项目的效率与质量。 医学影像 医学领域利用三维可视化技术进行医学影像诊断、手术规划和教育培训。医生可以利用三维重建图像来更好地了解患者病情,规划手术路径,甚至进行虚拟手术模拟,提升治疗效果与安全性。 虚拟现实与游
    的头像 发表于 09-30 17:57 864次阅读

    三维可视化技术主要领域及其具体运用

    运用: 1. 医学领域 医学影像处理: 三维可视化 技术可以将CT、MRI等医学影像数据转化为三维模型,帮助医生更直观地观察和分析患者的病情。医生可以通过旋转、放大等操作,更清晰地了解病变区域的结构和位置,提高诊断的准确
    的头像 发表于 09-11 16:40 995次阅读