将 Vision Transformer 用于医学图像的语义分割

关于ViT的关键点如下:

  • ViT架构基于将图像表示为一组补丁。图像补丁是图像的非重叠块。每个块最初都有一个由该块中的图像像素形成的嵌入向量。
  • Transformer编码器是ViT的主要部分,它根据它们的类别归属来训练补丁之间的相似度。它包含一系列线性、归一化和激活层。
  • 在大型数据集(例如ImageNet21K)上预训练的ViT模型可以用于在自定义数据集上进行迁移学习,微调后的模型表现良好。

关于U-Net的关键点如下:

  • U-Net由两部分组成:编码器和解码器。编码器包含一系列用于特征提取和图像缩减的块。解码器对称于编码器,重构图像分辨率。
  • 在CNN中,U-Net是医学图像语义分割的最佳架构之一。

我在我的分割系统中使用了Hugging Face的Swin Transformer V2作为编码器。Swin Transformer(分层视觉Transformer,使用偏移窗口)包含4个阶段的编码器处理嵌入补丁。最初,补丁大小为4x4像素。在每个编码器阶段,通过合并来自前一个阶段较小补丁的嵌入,补丁分辨率会增加两倍。这意味着图像的空间分辨率,以补丁表示,每个后续阶段会减少两倍。下图(来自Hugging Face文档)显示了Swin Transformer的高级架构:

图片

请注意,带有下采样编码器块序列类似于我之前文章中讨论的U-Net编码器的高级架构。还请注意,用于分类的ViT编码器在任何阶段都使用16x16的补丁(参见上图)。

已经训练了用于分割的Swin Transformer的几个模型,包括一个在ImageNet21K数据集上训练的大型模型(~ 1400万张图像)。完整的分割流水线由编码器和解码器组成。使用Hugging Face的Swin Transformer编码器进行以下自定义数据集的微调。换句话说,我使用预训练的Swin Transformer大型模型作为编码器,并实现和训练我的自定义解码器,以构建用于我的数据集的语义分割的完整系统。

从Hugging Face加载的Swin Transformer V2:深入了解

让我们使用以下代码块查看来自Hugging Face的Swin Transformer V2模型:

安装

在这里插入图片描述

导入

在这里插入图片描述

谷歌云硬盘挂载(用于Google Colab)

在这里插入图片描述

CUDA设备配置

device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')

大预训练模型的加载(在ImageNet21K上训练)

from transformers import AutoImageProcessor, Swinv2Model

image_processor = AutoImageProcessor.from_pretrained("microsoft/swinv2-large-patch4-window12-192-22k")
model = Swinv2Model.from_pretrained("microsoft/swinv2-large-patch4-window12-192-22k")

image_processor 定义了一组应用于输入图像的变换,这些图像最初以PIL图像的形式存在:

在这里插入图片描述
在这里插入图片描述

将输入的PIL图像转换为torch张量,将其调整为图像分辨率192x192,并进行归一化。

模型摘要

summary(model=model, input_size=(1, 3, 192, 192), col_names=['input_size', 'output_size', 'num_params', 'trainable'])

图片

这是一个包含超过1.95亿个参数的大型模型。

调用

model.eval()

以查看模型包含的所有层。

Swin Transformer V2模型的部分如下

  • Patch-embeddings 层,将输入图像的分辨率192x192划分为2034=48*48个4x4大小的patch。对于每个patch,形成一个长度为192的线性投影向量。
  • 4个编码器阶段。在每个阶段,进行Multi Head Self Attention的训练。每个阶段中像素大小的补丁会两倍增加(通过补丁嵌入合并)。每个阶段中,以补丁表示的图像分辨率会减少两倍。
  • 对编码器输出进行归一化,以生成来自编码器的last_hidden_state。
  • 对last_hidden_state张量进行平均池化,以生成包含类别嵌入的pooler_output向量。

加载任何图像并通过image_processor对其进行预处理:

在这里插入图片描述

将输入发送到Swin Transformer V2模型。下图说明了按顺序调用Swin Transformer V2的各个部分(如左图所示)等效于将整个模型作为一个整体进行调用(如右图所示):

图片

查看每个编码器阶段的输出:

在这里插入图片描述

我们看到以下形状:

  • im0 -> torch.Size([1, 2304, 192]) -> 2304=48*48 — patch数,192 — patch-embeddings长度
  • im1 -> torch.Size([1, 576, 384]) -> 576=24*24 — patch数,384 — patch-embeddings长度
  • im2 -> torch.Size([1, 144, 768]) -> 144=12*12 — patch数,768 — patch-embeddings长度
  • im3 -> torch.Size([1, 36, 1536]) -> 36=6*6 — patch数,1536 — patch-embeddings长度
  • im4 -> torch.Size([1, 36, 1536]) -> 36=6*6 — patch数,1536 — patch-embeddings长度

这些来自Swin Transformer V2预训练大型模型的输出将成为我的解码器模型的输入。我训练我的解码器以获得大脑MRI异常区域的分割掩模。下图显示了此解码器的高级架构:

图片

请注意,在上图流程图的最后一个块中,“图像调整大小为256x256”是流程图中常规解码器流程的自定义元素:我将大脑MRI的图像分辨率设置为256x256,并将其应用于分割掩模图像。

基于Swin Transformer V2的大脑MRI语义分割系统的实现

让我们回到大脑MRI的语义分割任务。我使用了来自Kaggle的大脑MRI数据集。该数据集包含110位患者的数据:每位患者都有一组带有脑部切片的MRI图像,以及相应的带有异常区域掩码图像的图像。下图显示了“脑部切片图像 + 带有掩码图像”的示例对:

图片

在数据集中,每个人的“脑切片图像+掩模图像”对的数量从20对到88对不等。整个集合包含 3935 对:2556 对具有零掩模,1379 对具有针对异常区域的非零掩模。

我使用PyTorch对基于Swin Transformer V2阶段输出(im0、im1、im2、im3、im4 — 见图1)的自定义解码器模型进行实现和训练。下面的代码显示了对一个图像进行预处理,该图像最初以PIL图像的形式存在,然后转换为来自预训练的Swin Transformer V2模型阶段的im0、im1、im2、im3、im4张量。下面代码中的变量model是加载的在ImageNet21K上预训练的Swin Transformer V2模型(请参阅上一节的代码块):

img = <load PIL Image>
img = image_processor(images=img, return_tensors="pt")

x = model.embeddings(**img)
input_dimensions=x[1]
im0 = x[0].detach().squeeze()

x = model.encoder.layers[0](x[0], input_dimensions=input_dimensions)
im1 = x[0].detach().squeeze()

x = model.encoder.layers[1](x[0], input_dimensions=(input_dimensions[0]//2, input_dimensions[1]//2))
im2 = x[0].detach().squeeze()

x = model.encoder.layers[2](x[0], input_dimensions=(input_dimensions[0]//4, input_dimensions[1]//4))
im3 = x[0].detach().squeeze()

x = model.encoder.layers[3](x[0], input_dimensions=(input_dimensions[0]//8, input_dimensions[1]//8))
x = model.layernorm(x[0])
im4 = x.detach().squeeze()

注意:我使用squeeze()来删除单个图像的批处理维度,因为我假设它将被发送到torch-DataLoader,后者会向图像批次添加批处理维度。

仅对掩模图像应用转换为torch张量和调整大小。来自DataLoader的5个输入张量被发送到以下模型:

class Up_Linear(nn.Module):
    def __init__(self, in_ch, size, coef=1):    
        super(Up_Linear, self).__init__()        
        self.shuffle = nn.PixelShuffle(upscale_factor=2)      
          
        n_ch = int(coef * in_ch)                
        
        self.ln = nn.Sequential(      
            nn.Linear(in_ch * 2, n_ch),            
            nn.ReLU(inplace=True),            
            nn.Linear(n_ch, in_ch * 2),            
            nn.ReLU(inplace=True),        
        )                
        
        self.size = size    
    def forward(self, x1, x2):   
        x = torch.cat((x1, x2), 2)        
        x = self.ln(x)        
        x = x.permute(0, 2, 1)        
        x = torch.reshape(x, (x.shape[0], x.shape[1], self.size, self.size))        
        x = self.shuffle(x)        
        x = torch.reshape(x, (x.shape[0], x.shape[1], self.size*self.size*4))        
        x = x.permute(0, 2, 1)        
        return x

class MRI_Seg(nn.Module):
    def __init__(self):    
        super(MRI_Seg, self).__init__()        
        
        self.ups3 = Up_Linear(1536, 6, 1)        
        self.ups2 = Up_Linear(768, 12, 1)        
        self.ups1 = Up_Linear(384, 24, 2)        
        self.ups0 = Up_Linear(192, 48, 3)      
          
        self.shuffle = nn.PixelShuffle(upscale_factor=2)    
            
        self.out = nn.Sequential(      
            nn.Conv2d(24, 1, kernel_size=1, stride=1),            
            nn.Sigmoid()        
        )    
        
    def forward(self, x0, x1, x2, x3, x4):
        x = self.ups3(x4, x3)        
        x = self.ups2(x, x2)        
        x = self.ups1(x, x1)        
        x = self.ups0(x, x0)      
          
        x = x.permute(0, 2, 1)        
        x = torch.reshape(x, (x.shape[0], x.shape[1], 96, 96))        
        x = self.shuffle(x)        
        x = transforms.Resize((256, 256))(x)       
         
        x = self.out(x)        
        return x  


net = MRI_Seg().to(device)

模型摘要

summary(model=net, input_size=[(1, 2304, 192), (1, 576, 384), (1, 144, 768), (1, 36, 1536), (1, 36, 1536)], col_names=['input_size', 'output_size', 'num_params', 'trainable'])

图片

该模型包含超过1300万个可训练参数(类似于U-Net模型)。

我使用二元交叉熵损失函数来训练我的模型,以使生成的掩码更接近标签(掩码)图像。我使用Adam优化器和学习率0.0001。我同时使用IoU(交并比)和Dice指标作为质量度量:IoU = 1和Dice = 1表示理想质量。请注意,对于包括图片在内的所有结果,我使用经过训练模型生成的分割掩码,并应用阈值:如果掩码像素值小于0.5,则将掩码像素值设置为0,否则将掩码像素值设置为1。

下图显示了对U-Net架构(它们是在此处获得和呈现的)和MRI_Seg模型(上面)的结果进行比较。对于两种模型,我选择了在测试集上显示最佳结果的检查点。对于对U-Net和基于Transformer的模型的性能评估,我使用了来自训练集的550个随机选择的条目和所有394个包含在测试集中的条目(使用相同的训练和测试集):

图片

正如我们所见,基于Transformer的分割模型的性能明显低于U-Net模型的性能。我尝试过改变我的解码器架构和可训练参数的数量,但并未改善性能。

我对MRI和掩码图像应用了水平翻转(改变图像的左右侧),并创建了一个图像数量加倍的数据集。现在,我正在使用这个增强的数据集来训练基于Transformer的模型。下图显示了U-Net架构(在此处获取和呈现)和MRI_Seg模型(上面)在增强数据集上结果的比较。对于两种模型,我选择了在测试集上表现最佳的检查点。对于基于U-Net和Transformer的模型的性能评估,我使用了从训练集中随机选择的550个条目以及测试集中包含的所有787个测试条目(两种模型都使用相同的训练和测试集):

图片

我们可以看到,基于增强数据集训练的基于Transformer的分割模型的性能显着提高,并且接近于U-Net模型的性能。

下面的图片显示了基于Transformer的训练模型在测试图像上的工作结果。

图片

图片

图片

结论

  • Swin Transformer V2的高级架构允许使用U-Net模型的概念来实现自定义解码器的语义分割系统。
  • 自定义数据集的大小应该足够大(约为10K)。在这种情况下,基于Transformer的语义分割系统的性能良好。
  • 基于Transformer的语义分割系统能够获得接近于最佳分割模型(如U-Net)的性能。

· END ·

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/791713.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DLP迎来新机遇 | 天空卫士数据防泄漏防护市场占有率连续三年第一

IDC 于近日发布了《中国数据泄露防护市场份额&#xff0c;2023&#xff1a;DLP迎来新机遇》&#xff08;Doc#CHC50973524 &#xff0c;2024年6月&#xff09;报告&#xff0c;天空卫士DLP产品以21.9%的市场份额再次位列中国数据防泄露防护市场第一。这一成绩体现了天空卫士在技…

2024SpringCloud学习笔记

远程调用Rest Template 服务注册与发现&分布式配置管理 Consul 下载安装 官网https:/ldeveloper.hashicorp.com/consul/downloads 开发者模式启动consul agennt -dev 浏览器访问本地端口:8500 服务注册与发现 Maven引入 <!--SpringCloud consul discovery -->…

基于 BERT 的非结构化领域文本知识抽取

文章目录 题目摘要方法实验 题目 食品测试的大型语言模型 论文地址&#xff1a;https://arxiv.org/abs/2103.00728 摘要 随着知识图谱技术的发展和商业应用的普及&#xff0c;从各类非结构化领域文本中提取出知识图谱实体及关系数据的需求日益增加。这使得针对领域文本的自动化…

MechMind结构光相机 采图SDK python调用

测试效果 Mech-Mind结构光相机 Mech Mind(梅卡曼德)的结构光相机,特别是Mech-Eye系列,是工业级的高精度3D相机,广泛应用于工业自动化、机器人导航、质量检测等多个领域。以下是对Mech Mind结构光相机的详细解析: 一、产品概述 Mech Mind的结构光相机,如Mech-Eye PRO,…

极狐GitLab X 中科星图,用实际行动赋能空天行业开发者

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…

RFID技术革新养猪业,构建智能化养殖场

RFID技术作为无线射频识别技术的一种&#xff0c;凭借着非接触、高效识别的特性&#xff0c;在养殖业行业中得到了广泛的应用&#xff0c;为构建智能化、高效化的养殖场提供了强大的技术支持&#xff0c;给传统养殖业带来了一场前所未有的技术变革。以下是RFID技术在养猪行业不…

podman 替代 docker ? centos Stream 10 已经弃用docker,开始用podman了!

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

记一次Ueditor上传Bypss

前言 前一段时间和小伙伴在某内网进行渗透测试&#xff0c;目标不给加白&#xff0c;只能进行硬刚了&#xff0c;队友fscan一把梭发现某资产疑似存在Ueditor组件&#xff0c;但初步测试是存在waf和杀软的&#xff0c;无法进行getshell&#xff0c;经过一番折腾最终getshell&am…

Python基础语法:运算符详解(算术运算符、比较运算符、逻辑运算符、赋值运算符)②

文章目录 Python中的运算符详解一、算术运算符二、比较运算符三、逻辑运算符四、赋值运算符五、综合示例结论 Python中的运算符详解 在Python编程中&#xff0c;运算符用于执行各种操作&#xff0c;例如算术计算、比较、逻辑判断和赋值。了解并掌握这些运算符的使用方法是编写…

【观成科技】Websocket协议代理隧道加密流量分析与检测

Websocket协议代理隧道加密流量简介 攻防场景下&#xff0c;Websocket协议常被用于代理隧道的搭建&#xff0c;攻击者企图通过Websocket协议来绕过网络限制&#xff0c;搭建一个低延迟、双向实时数据传输的隧道。当前&#xff0c;主流的支持Websocket通信代理的工具有&#xf…

物联网系统中市电电量计量方案(二)

上文我们主要介绍了电量计量中最重要的组成部分——电量计量芯片&#xff08;如果没有阅读该文章的&#xff0c;可以点击这里&#xff09;。本文会再为大家介绍电量计量的另外一个组成部分——电流互感器。 电流互感器的定义 电流互感器是一种可将一次侧大电流转换为二次侧小电…

AppStandby白名单机制

背景&#xff1a;原生机制中AppStandby机制的白名单是共享Doze白名单&#xff0c;即一旦设置doze白名单&#xff0c;也即AppStandby的白名单 需求&#xff1a;如何建立AppStandby自己的白名单 技术原理&#xff1a;可以使用setAppStandbyBucket接口实现 setAppStandbyBucket…

Java内存划分详解:从基础到进阶

Java内存划分详解&#xff1a;从基础到进阶 1. 程序计数器&#xff08;Program Counter Register&#xff09;2. Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff09;3. 堆&#xff08;Heap&#xff09;4. 方法区&#xff08;Method Area&#xff09;5. 运行时常量…

揭秘”大模型加速器”如何助力大模型应用

文章目录 一、大模型发展面临的问题二、“大模型加速器”助力突破困难2.1 现场效果展示2.1.1 大模型加速器——文档解析引擎2.2.2 图表数据提取 三、TextIn智能文档处理平台3.1 在线免费体验3.1.1 数学公式提取3.1.2 表格数据提取 四、acge文本向量化模型4.1 介绍4.2 技术创新4…

前端面试题40(浅谈MVVM双向数据绑定)

MVVM&#xff08;Model-View-ViewModel&#xff09;架构模式是一种用于简化用户界面&#xff08;UI&#xff09;开发的软件架构设计模式&#xff0c;尤其在现代前端开发中非常流行&#xff0c;例如在使用Angular、React、Vue.js等框架时。MVVM模式源于经典的MVC&#xff08;Mod…

网络协议(TCP三次握手,四次断开详解)

TCP的详细过程&#xff1a; TCP&#xff08;传输控制协议&#xff09;的三次握手和四次断开是其建立连接和终止连接的重要过程&#xff0c;以下是详细解释&#xff1a; 三次握手&#xff1a; 1. 第一次握手&#xff1a;客户端向服务器发送一个 SYN&#xff08;同步&#x…

【python】QWidget父子关系,控件显示优先级原理剖析与应用实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

51单片机嵌入式开发:8、 STC89C52RC 操作LCD1602原理

STC89C52RC 操作LCD1602原理 1 LCD1602概述1.1 LCD1602介绍1.2 LCD1602引脚说明1.3 LCD1602指令介绍 2 LCD1602外围电路2.1 LCD1602接线方法2.2 LCD1602电路原理 3 LCD1602软件操作3.1 LCD1602显示3.2 LCD1602 protues仿真 4 总结 1 LCD1602概述 1.1 LCD1602介绍 LCD1602是一种…

室内精准定位哪个产品抗干扰能力强?可以用于哪些方面?

室内精准定位产品其实有很多&#xff0c;其实它是安装在室内接收型号的一个基站&#xff0c;并且范围有一定的限制&#xff0c;而被定位的人员需要携带定位产品&#xff0c;那么通过室内基站收集到的信息&#xff0c;将会通过专业的系统处理后呈现在相应的设备上&#xff0c;比…

elementui实现复杂表单的实践

简介 文章主要讲述在vue3项目中使用elementui框架实现复杂表单的方式。表单中涉及动态组件的生成、文件上传和富文本编辑器的使用&#xff0c;只会将在实现过程中较复杂的部分进行分享&#xff0c;然后提供一份完整的前端代码。 表单效果演示 基础信息 spu属性 sku详情 关键…