在训练心脏数据集时碰到的问题汇总

news2024/11/19 13:40:50

在训练心脏数据集时碰到的问题汇总:

1.nii数据处理问题

心脏CT数据集采用的是医学图像常用的压缩文件格式nii,且储存的图像为3D图像,不能直接使用。
首先应导入SimpleITK包,利用如下三个函数进行nii格式文件的提取。

sitk.ReadImage(imagebatch)
sitk.Cast(sitk.RescaleIntensity(img)
sitk.sitkUInt8) sitk.GetArrayFromImage(img)

对于常见的nii.gz格式图像,可采用如下代码处理:

def Gettensorfromnii(root):
    a=sorted(glob.glob(root))
    imgcat = torch.Tensor(0,320,320)
    for i, imagebatch in enumerate(a):
        img = sitk.ReadImage(imagebatch)
        img = sitk.Cast(sitk.RescaleIntensity(img), sitk.sitkUInt8)
        img = sitk.GetArrayFromImage(img)
        trans=torchvision.transforms.ToTensor()
        img=trans(img)
        img=img.permute(1,2,0)
        img = img.type(torch.FloatTensor)
        imgcat=torch.cat((imgcat,img),0)
    print("full imagcat:",imgcat.shape)
    return imgcat

因为本次训练准备采用单个slice进行训练,因此预处理代码思路是,先提取为numpy格式,然后转换为tensor格式,最后将所有tensor按通道concat在一起,得到全部的数据。

数据处理完毕后,我们得到的是两个大概(3000,320,320)的包含全部数据信息与label信息的tensor,对其进行切片处理,创建Heartdataset数据集:

class Heartdataset(Dataset):#本身已经是tensor,只需要一些处理
    def __init__(self,trainimages,labelimages,mode):
        self.trans = torchvision.transforms.Compose([
            torchvision.transforms.RandomCrop(256),
            torchvision.transforms.RandomAffine(90, translate=None, scale=(0.5,2), shear=None, resample=0, fillcolor=0)
        ])

        if mode=='train':#16,4
            self.origin=trainimages[:int(0.8*len(trainimages))]
            self.label=labelimages[:int(0.8*len(labelimages))]
            #print(self.origin.shape)
        elif mode=='val':#20
            self.origin=trainimages[int(0.8*len(trainimages)):]
            self.label=labelimages[int(0.8*len(labelimages)):]
        elif mode=='test':
            self.origin=trainimages
            self.label=labelimages

    def __len__(self):
        return len(self.origin)

    def __getitem__(self, index):
        img_origin=self.origin[index]
        img_origin=img_origin.unsqueeze(0)
        img_label=self.label[index]
        img_label=img_label.unsqueeze(0)

        seed = torch.random.seed()
        torch.random.manual_seed(seed)
        img_origin = self.trans(img_origin)
        torch.random.manual_seed(seed)
        img_label = self.trans(img_label)
        return img_origin,img_label

值得注意的是,由于处理对象是tensor,因此本数据集的处理相较图片的处理有所不同。
本次训练中train:val=4:1

2.out与predict问题

在训练中,本人遇到的最为困惑的问题就是在可视化界面中发现输出与label一个是灰度图一个是二值图的问题,这其实是因为在写如下代码时:

inputs,labels=inputs.to(self.device),labels.to(self.device)
out=self.net(inputs)
                #predict=np.argmax(out.cpu().detach().numpy(),axis=1)#最终分类就是像素为1或者0,经过sigmoid的数字很接近0或者1,但是没有到,
                #这就导致了预测图不是二值图,因此要使用argmax(多分类多通道问题),如果只有单通道,直接对元素处理如下:
                # a中大于0.5的用zero(0)替换,否则a替换,即不变
                

将out的与predict混淆,没有加入predict而直接输出了out导致的。
实际上,out得到的结果是网络最后一层sigmoid函数得到的结果,可以将其作为loss与label进行计算但是不能直接使用out来作为预测的分割结果,如果输出是单通道,应该加入如下语句来获得predict:

zero = torch.zeros_like(out)
one = torch.ones_like(out)
predict=torch.where(out>=0.5,one,out)
predict=torch.where(out<0.5,zero,predict)

对于单通道分类问题,我们也可以转化为多通道(channel=2)问题来解决,这种方法更为通用,可以用来解决多分类问题:

即网络的输出 output 为 [batch_size, num_class, height, width] 形状。其中 batch_szie 为批量大小,num_class 表示输出的通道数与分类数量一致,height 和 width 与输入图像的高和宽保持一致。

在训练时,输出通道数是 num_class(这里取2),网络得到的 output 包含的数值是任意的数。在二分类问题中,给定的 target ,是一个单通道标签图,数值只有 0 和 1 (背景与前景)这两种。为了让网络输出 output 不断逼近这个标签,首先会让 output 经过一个 softmax 函数,使其数值归一化到[0, 1],得到 output1 ,在各通道中,这个数值加起来会等于1。对于target 他是一个单通道图,首先使用onehot编码,转换成 num_class个通道的图像,每个通道中的取值是根据单通道中的取值计算出来的,例如单通道中的第一个像素取值为1(0<= 1 <=num_class-1,这里num_class=2),那么onehot编码后,在第一个像素的位置上,两个通道的取值分别为0,1。也就是说像素的取值决定了对应序号的通道取1,其他的通道取0,这个非常关键。上面的操作执行完后得到target1,让这个 output1 与 target1 进行交叉熵计算,得到损失值,反向传播更新网路权重。最终,网络经过学习,会使得 output1 逼近target1(在各通道层面上)。

训练结束后,网络已经具备让输出的 output 经过转换从而逼近 target 的能力。计算 output 中各通道每一个像素位置上,取值最大的那个对应的通道序号,从而得到预测图 predict。后续则是一些评估相关的计算。

output = net(input)  # net的最后一层没有使用sigmoid
predict = output.argmax(dim=0)#原帖为dim=1,但个人认为通道方向上应该是dim=0

多通道问题对于图像上的某个像素,他只在结果对应的通道上的x,y处为1,其余点为0,因此可以使用argmax求出最大通道数的索引(0,1,2,3,4,5,6,7…)对应的编号就是对应的通道,也就是对应的分割对象。

3.loss函数与最后一层输出函数选取问题

根据输出函数是否用到了sigmoid,有两种loss选取方法,如果选取错误可能会导致loss为负或者报错:

output = net(input) # net的最后一层没有使用sigmoid
loss_func1 => torch.nn.BCEWithLogitsLoss()
loss = loss_func1(output, target)

output = net(input) # net的最后一层没有使用sigmoid
output = F.sigmoid(output)#加入sigmoid
loss_func1 = torch.nn.BCELoss()
loss = loss_func1(output, target)

4.过拟合问题

在训练中,我的loss一度达到了10e-6级别,但是validation效果很差,dice约在0.44左右,这时候就要考虑是否陷入了过拟合。
经分析,本次过拟合可能是因为样本数量过少导致的,解决过拟合的方法很多,本人采用了图像增强方法,对图像进行了randomcrop以及randomaffine计算,这样便增加了样本数量,达到了增加样本数量的目的。

self.trans = torchvision.transforms.Compose([
     torchvision.transforms.RandomCrop(256),
     torchvision.transforms.RandomAffine(90, translate=None, scale=(0.5,2), shear=None, resample=0, fillcolor=0)
        ])

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vlan间的通信

vlan之间要通过三层通信实现互访&#xff0c;三层通信需借助三层设备 如果之前配置了 hybrid模式想删除 命令 undo port link-type hybrid vlan all [Huawei-GigabitEthernet0/0/3]dis this interface GigabitEthernet0/0/3 undo port hybrid vlan 1 这里可以理解为多删了一个…

【python】【数据分析】2022年全国大学生数据分析大赛题解-医药电商销售数据分析

文章目录一、前言二、题目三、题解1&#xff0e;对店铺进行分析&#xff0c;一共包含多少家店铺&#xff0c;各店铺的销售额占比如何&#xff1f;给出销售额占比最高的店铺&#xff0c;并分析该店铺的销售情况。2.对所有药品进行分析&#xff0c;一共包含多少个药品&#xff0c…

Promise和async/await

1、回调地狱 多层回调函数的相互嵌套&#xff0c;就形成了回调地狱。示例代码如下&#xff1a; 回调地狱的缺点&#xff1a; 代码耦合性太强&#xff0c;牵一发而动全身&#xff0c;难以维护大量冗余的代码相互嵌套&#xff0c;代码的可读性变差 1.1、如何解决回调地狱的问题…

手把手实现邮件分类 《Getting Started with NLP》chap2:Your first NLP example

《Getting Started with NLP》chap2&#xff1a;Your first NLP example 感觉这本书很适合我这种菜菜,另外下面的笔记还有学习英语的目的&#xff0c;故大多数用英文摘录或总结 文章目录《Getting Started with NLP》chap2&#xff1a;Your first NLP example2.1 Introducing N…

数据结构与算法【树】

二叉树性质 满二叉树 深度为k&#xff0c;有2k−12^{k}-12k−1个结点的二叉树&#xff0c;为满二叉树。 完全二叉树 完全二叉树的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#xff0c;并且最下面…

CSDN第22期周赛(记录一下,不是题解)

希望23年能收获一两本程序员杂志 前言 发现一个问题&#xff0c;codeblocks上编译没问题&#xff0c;在CSDN比赛时&#xff0c;会报错&#xff1a; 1&#xff0c;size()和length()属于unsigned int&#xff0c;所以与之比较大小或者赋值的 i, j 也要用unsigned int&#xf…

巧解 JavaScript 中的嵌套替换

网友 wys 提问&#xff1a;如何仅使用 JavaScript 支持的正则语法&#xff0c;将 <p> <table> <p> <p> </table> <table> <p> <p> </table> <p>中<table>...</table>之间的<p>都替换为<b…

C库函数:stdio.h

stdio.h C 标准库 – <stdio.h> | 菜鸟教程 (runoob.com) 下面是头文件 stdio.h 中定义的变量类型&#xff1a; 序号变量 & 描述1size_t 这是无符号整数类型&#xff0c;它是 sizeof 关键字的结果。2FILE 这是一个适合存储文件流信息的对象类型。3fpos_t 这是一个适…

组件的生命周期

一、组件的生命周期 1、组件的生命周期&#xff1a;至一个组件从 创建——>运行——>销毁的过程 2、声明周期函数&#xff1a;由Vue提供的内置函数&#xff0c;伴随组件生命周期按次序自动运行——>钩子函数 3、生命周期的阶段划分 &#xff08;1&#xff09;创建…

什么是链接?(动态链接库和静态链接库的对比)

什么是链接&#xff1f; 首先我们需要知道&#xff0c;一个源文件&#xff08;以.c为例&#xff09;是经过什么最后形成的一个可执行的文件&#xff08;windows下为.exe文件&#xff09;。 一个.c的源文件&#xff0c;要经历 1.预处理&#xff1a;头文件的展开替换 2.编译&…

skywalking解析-如何在idea中调试skywalking agent

当我从github上下载下来skywalking agent的代码后&#xff0c;面临的第一个问题就是如何调试。因为skywalking agent的运行模式与普通程序运行方式不一样&#xff0c;它是通过java agent方式运行的。本文接下来介绍如何在本地调试skywalking agent源码。 目录一、下载源码二、运…

leetcode_栈与队列

栈与队列栈与队列理论基础232.用栈实现队列225.用队列实现栈20.有效的括号1047.删除字符串中的所有相邻重复项150.逆波兰表达式求值239.滑动窗口最大值347.前k个高频元素栈与队列总结栈与队列理论基础 栈与队列理论基础 232.用栈实现队列 力扣题目链接 class MyQueue { pub…

Cadence PCB仿真使用Allegro PCB SI通过导入工艺文件配置层叠结构的方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,概述2,配置方法3,总结1,概述 本文简单介绍使用Allegro PCB SI通过导入工艺文件配置层叠结构的方法。 2,配置方法 第1步:打开待仿真的PCB文件,并确认软件为Allegro PCB SI 如果,打开软件不是Allegro PCB SI则…

【JavaScript】数组常用方法

冲突数组常用方法&#xff1a; 注&#xff1a; 以下方法都会对原数组进行改变&#xff1a; push&#xff1a;向数组后面追加元素&#xff0c;返回值是追加后的数组长度 pop&#xff1a;从数组后面删除元素&#xff0c;返回值是删除的元素内容 unshift:在数组前面添加元素&am…

CMMI之系统设计

系统设计&#xff08;System Design, SD&#xff09;是指设计软件系统的体系结构、用户界面、数据库、模块等&#xff0c;从而在需求与代码之间建立桥梁&#xff0c;指导开发人员去实现能满足用户需求的软件产品。系统设计过程域是SPP模型的重要组成部分。本规范阐述了系统设计…

第一章 Flink简介

Flink 系列教程传送门 第一章 Flink 简介 第二章 Flink 环境部署 第三章 Flink DataStream API 第四章 Flink 窗口和水位线 第五章 Flink Table API&SQL 第六章 新闻热搜实时分析系统 前言 流计算产品实时性有两个非常重要的实时性设计因素&#xff0c;一个是待计算…

文档智能(一):基于OpenCV的文档图像校正

文档智能(一)&#xff1a;基于OpenCV的文档图像校正 发表时间&#xff1a; 2023年1月7日创作地点&#xff1a;湖北省武汉市作者&#xff1a;ixy_com&[Aneerban Chakraborty]封面图片来源&#xff1a;DocTr 本文关键词&#xff1a;文档智能、文档图像校正、OpenCV、形态…

从零实现Dooring低代码印章组件

上一篇文章和大家分享了低代码平台组件间通信方案的几种实现:低代码平台组件间通信方案复盘今天继续和大家分享一下比较有意思的可视化印章组件的实现.你将收获低代码组件的基本设计模式印章组件的设计原理(canvas相关)如何快速将任意组件集成到低代码平台正文低代码组件的基本…

雷鸟X2:开启可量产全彩MicroLED光波导AR眼镜新起点

从最近的AR眼镜新品来看&#xff0c;采用MicroLED光波导方案已经成为了明显的趋势&#xff0c;可见业内对于光学的大方向还是非常统一的。不仅如此&#xff0c;各个厂商都拿出自己最优的方案来进行探索和验证&#xff0c;比如有的看重“极轻”、有的看重“视觉”、有的看重“价…

使用Jenkins一键打包部署 SpringBoot应用

一般而言&#xff0c;一个项目部署的由&#xff1a;拉取代码->构建->测试->打包->部署等过程组成&#xff0c;如果我们经常需要部署项目&#xff0c;特别是在微服务时代&#xff0c;服务特别多的情况下&#xff0c;不停的测试打包部署&#xff0c;那估计得有个人一…