VGG16模型实现新冠肺炎图片多分类

news2024/9/22 4:55:59

1. 项目简介

本项目的目标是通过深度学习模型VGG16,实现对新冠肺炎图像的多分类任务,以帮助医疗人员对患者的影像进行快速、准确的诊断。新冠肺炎自爆发以来,利用医学影像如X光和CT扫描进行疾病诊断已成为重要手段之一。随着数据量的增加,基于人工智能的图像分析方法逐渐显现出其优势,能够有效提高检测效率并减少误诊率。该项目基于预训练的VGG16模型,通过对肺部CT或X光影像进行分类,实现对不同类型的肺部病变的分类识别。VGG16模型是深度卷积神经网络中的经典网络,具有16层网络结构,能够捕捉图像中的细微特征,适用于医学图像分析。本项目通过迁移学习,将VGG16的卷积层权重应用于新冠肺炎图片分类任务,并通过微调模型,使其适应于具体的医学影像数据集。最终目标是构建一个高效且稳定的深度学习模型,帮助医疗人员对肺炎患者进行辅助诊断,提高诊断的准确性和效率,同时减轻医疗系统的负担。

2.技术创新点摘要

迁移学习的应用:该项目利用VGG16模型进行迁移学习,这是该项目的重要创新之一。VGG16是一个预训练模型,已经在大规模图像数据集ImageNet上进行训练,具有强大的特征提取能力。通过冻结预训练模型的卷积层权重,模型可以专注于当前新冠肺炎图像的分类任务,避免从头开始训练,有效缩短了模型的训练时间,并提升了训练的稳定性和准确性。

3. 数据集与预处理

本项目使用的新冠肺炎医学图像数据集主要由CT或X光图像组成,数据集包含了正常、轻度感染及重度感染的肺部影像。这些医学图像具有高分辨率,能够反映患者肺部的病变情况。数据集中的标签对应不同的病理分类,这些标签用于训练模型进行多分类任务。医学影像的特征在于其复杂的结构和细节,因此需要经过严格的预处理,以确保模型能够从中学习到有效的特征。

在数据预处理阶段,首先对原始图像进行统一的尺寸调整。所有图像被缩放到224x224像素,以匹配VGG16模型的输入尺寸。此外,图像通过 transforms.ToTensor() 函数转换为张量,并将像素值从0-255的范围标准化为0-1之间。接着,使用预训练模型ImageNet的均值和标准差对图像进行归一化处理,将像素值调整到(-1,1)的区间。这一步能够确保输入数据的分布与预训练模型的输入分布相一致,进而提高模型的性能。

在数据增强方面,项目引入了多种增强策略,以增强模型的泛化能力。这些增强操作包括随机裁剪、翻转等,这能够有效增加训练数据的多样性,从而防止模型过拟合。同时,这些增强手段能够模拟不同条件下的医学图像变化,使模型更加稳健。

4. 模型架构

本项目使用了VGG16模型,这是一种深度卷积神经网络,具有16个权重层。其模型结构包括卷积层、池化层、全连接层等,具体如下:

  • 卷积层:VGG16由多个卷积层构成,每一层卷积操作的公式为:

y i , j , k = ∑ m , n w m , n , k ⋅ x i + m , j + n + b k y_{i,j,k} = \sum_{m,n} w_{m,n,k} \cdot x_{i+m,j+n} + b_k yi,j,k=m,nwm,n,kxi+m,j+n+bk

其中,x 是输入图像,w 是卷积核权重,b 是偏置项,y 是输出的特征图。这些卷积操作主要用于提取图像中的局部特征,尤其适合复杂的医学图像。

池化层:卷积后会经过最大池化层(Max Pooling),其公式为:

y i , j , k = max ⁡ { x i + m , j + n , k } ,   ( m , n ) ∈ S y_{i,j,k} = \max \{ x_{i+m,j+n,k} \}, \, (m,n) \in S yi,j,k=max{xi+m,j+n,k},(m,n)S

池化操作减少了特征图的大小,从而降低了模型的计算复杂度,同时保留了重要的特征信息。

全连接层:卷积和池化层的输出最终会通过全连接层,该层将多维的特征映射为一维向量,公式为:

y = W ⋅ x + b y = W \cdot x + b y=Wx+b

其中 W是权重矩阵,x 是输入向量,b是偏置项,y 是输出。这一层用于完成分类任务,将卷积提取到的特征映射到具体的分类结果上。

Softmax层:在最后的输出层,使用Softmax激活函数生成每个类别的概率分布,公式为:

P ( y = k ∣ x ) = e z k ∑ j e z j P(y = k | x) = \frac{e^{z_k}}{\sum_{j} e^{z_j}} P(y=kx)=jezjezk

其中 zk是类别 k的输出,Softmax函数保证输出结果为概率分布,并用于多分类任务。

模型层次概览

输入:224x224x3的医学影像

卷积层1-2(64个3x3卷积核)

最大池化层1

卷积层3-4(128个3x3卷积核)

最大池化层2

卷积层5-7(256个3x3卷积核)

最大池化层3

卷积层8-10(512个3x3卷积核)

最大池化层4

卷积层11-13(512个3x3卷积核)

最大池化层5

3个全连接层

最后通过Softmax层输出分类概率

模型的整体训练流程

训练流程如下:

数据加载:数据集通过自定义 MyDataset 类加载,并应用了标准化和数据增强等预处理步骤。

模型初始化:加载预训练的VGG16模型,并冻结部分卷积层的权重以保留其在ImageNet上的特征提取能力,只对最后几层进行微调。

前向传播:将图像输入到模型中,经过卷积、池化、全连接等层,生成最终的分类结果。

损失计算:使用交叉熵损失函数(CrossEntropyLoss)计算预测结果与真实标签之间的差异: L = − ∑ i y i log ⁡ ( y ^ i ) L = -\sum_{i} y_i \log(\hat{y}_i) L=iyilog(y^i)

其中 yi是真实标签的概率分布,y^i是预测概率分布。

反向传播:通过计算损失函数的梯度,更新可训练的参数,优化目标是最小化损失函数。

优化器:使用Adam优化器进行梯度更新,该优化器结合了动量与自适应学习率的优点: θ t + 1 = θ t − η ⋅ m t v t + ϵ \theta_{t+1} = \theta_t - \eta \cdot \frac{m_t}{\sqrt{v_t} + \epsilon} θt+1=θtηvt +ϵmt其中 mt和 vt分别是一阶和二阶矩估计,η 是学习率。

训练轮次:设定训练轮次(例如20轮),在每一轮中通过前向传播、损失计算、反向传播进行权重更新。

模型评估:在测试集上进行评估,主要使用准确率(Accuracy)、召回率(Recall)等指标:

  1. 准确率 A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy = \frac{TP + TN}{TP + TN + FP + FN} Accuracy=TP+TN+FP+FNTP+TN
  1. 召回率 R e c a l l = T P T P + F N Recall = \frac{TP}{TP + FN} Recall=TP+FNTP

通过这些步骤,模型能够高效完成新冠肺炎图像的多分类任务,并在实际数据集上进行评估与优化。

5. 核心代码详细讲解

数据预处理与特征工程
pic_transform = transforms.Compose([
    transforms.Resize([224,224]),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

解释

  1. transforms.Resize([224,224]):这行代码将输入图像的尺寸缩放到224x224像素,以确保输入图像大小一致,符合VGG16模型的输入要求。
  2. transforms.ToTensor():将PIL图像转换为PyTorch的Tensor类型,并将像素值从0-255的范围归一化为0-1。这是标准的PyTorch数据处理步骤。
  3. transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]):基于ImageNet的均值和标准差进行图像归一化,将像素值调整到(-1,1)的范围。该归一化策略是ImageNet预训练模型的标准配置,有助于提高模型性能。
自定义数据集加载
class MyDataset(Dataset):def init(self, img_path, file_name ,transform=None):
        self.root = img_path
        self.file_name = file_name
        self.csv_root = self.root + '//' + self.file_name
        df = pd.read_csv(self.csv_root)
        rows = df.shape[0]
        imgs = []
        labels = []for row in range(0,rows):
            imgs.append(os.path.join(self.root,df['image_path'][row]))
            labels.append(df['labels'][row])
        self.img = imgs
        self.label = labels
        self.transform = transform
def len(self):return len(self.label)
def getitem(self, item):
        img = self.img[item]
        label = self.label[item]
        img = Image.open(img).convert('RGB')if self.transform is not None:
            img = self.transform(img)
        label = np.array(label).astype(np.int64)
        label = torch.from_numpy(label)return img, label

解释

  1. init(self, img_path, file_name ,transform=None):初始化方法,定义了数据集的路径和图像转换方法,并加载图像路径和标签。transform参数用于指定数据增强和预处理步骤。
  2. df = pd.read_csv(self.csv_root):从指定的CSV文件中读取图像路径和标签,CSV文件包含图像的文件路径及其对应的标签。
  3. self.img = imgsself.label = labels:将图像路径和标签分别存储在两个列表中,以供后续数据加载使用。
  4. len(self):返回数据集中样本的数量,这是PyTorch自定义数据集的标准实现。
  5. getitem(self, item):通过索引获取图像和标签。图像通过PIL库打开并转换为RGB格式,然后应用数据预处理(如果有),最终返回Tensor格式的图像和标签。
模型构建与训练
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = models.vgg16(pretrained=True)
for param in model.parameters():
    param.requires_grad = False
model.classifier[6] = nn.Linear(4096, 3)
model = model.to(device)

解释

  1. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu'):这行代码用于检测当前系统是否有可用的GPU,如果有则将计算设备设为GPU(CUDA),否则使用CPU。
  2. model = models.vgg16(pretrained=True):加载预训练的VGG16模型,这个模型已经在ImageNet上进行过训练,能够有效地提取图像的特征。
  3. for param in model.parameters(): param.requires_grad = False:冻结VGG16模型的所有卷积层权重,使它们在训练过程中不更新。这是典型的迁移学习策略,主要目的是利用预训练模型的特征提取能力,同时减少训练时间和计算资源。
  4. model.classifier[6] = nn.Linear(4096, 3):替换VGG16模型中的最后一层全连接层,将输出从ImageNet的1000类修改为当前任务的3类(例如:正常、轻度感染、重度感染)。
  5. model = model.to(device):将模型移动到GPU或CPU上,以加速训练过程。
模型训练与评估
def vgg_train(model, epochs, train_loader, test_loader, log_step_freq):
    model.train()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
    loss_fn = nn.CrossEntropyLoss()for epoch in range(epochs):for step, (x, y) in enumerate(train_loader):
            x, y = x.to(device), y.to(device)
            optimizer.zero_grad()
            pred = model(x)
            loss = loss_fn(pred, y)
            loss.backward()
            optimizer.step()if step % log_step_freq == 0:print(f"[{epoch+1}/{epochs}] Step: {step}, Loss: {loss.item()}")print('训练成功~')

解释

  1. model.train():将模型设置为训练模式,这会启用诸如Dropout等正则化技术。
  2. optimizer = torch.optim.Adam(model.parameters(), lr=0.001):使用Adam优化器进行模型参数的更新,学习率设置为0.001。Adam优化器结合了动量和自适应学习率,能够加快训练过程并减少震荡。
  3. loss_fn = nn.CrossEntropyLoss():定义交叉熵损失函数,用于计算预测值与真实标签之间的误差,适用于多分类任务。
  4. for epoch in range(epochs):开始模型的训练循环,每个epoch表示模型对整个数据集的完整遍历。
  5. x, y = x.to(device), y.to(device):将输入数据和标签移动到GPU(如果有)或CPU,以确保与模型在同一设备上进行计算。
  6. optimizer.zero_grad():清空优化器中的梯度缓存,避免上一次的梯度对本次计算的影响。
  7. pred = model(x):前向传播,模型对输入数据x进行预测。
  8. loss = loss_fn(pred, y):计算预测结果与真实标签之间的损失。
  9. loss.backward():反向传播计算梯度,更新模型参数。
  10. optimizer.step():根据反向传播计算得到的梯度更新模型参数。
  11. if step % log_step_freq == 0:每隔log_step_freq步打印一次训练日志,包括当前epoch、step和损失值。
  12. print('训练成功~'):训练结束后的提示信息。
评估指标
def line_plotling(df, metric):import seaborn as snsimport matplotlib.pyplot as plt
    sns.set_theme(style='ticks')
    sns.lineplot(x='epoch', y=metric, data=df, color='r')
    sns.lineplot(x='epoch', y='val_'+metric, data=df, color='b')
    plt.legend(['train_'+metric, 'val_'+metric])

解释

  1. sns.set_theme(style='ticks'):使用Seaborn库设置绘图主题,风格为ticks
  2. sns.lineplot(x='epoch', y=metric, data=df, color='r'):绘制训练集的性能指标(例如准确率或损失)的变化曲线,x轴表示epoch,y轴表示指标值,曲线颜色为红色。
  3. sns.lineplot(x='epoch', y='val_'+metric, data=df, color='b'):绘制验证集的性能指标变化曲线,颜色为蓝色。通过对比训练集和验证集的曲线变化,可以观察到模型是否过拟合或欠拟合。
  4. plt.legend(['train_'+metric, 'val_'+metric]):为图形添加图例,区分训练集和验证集的曲线。

6. 模型优缺点评价

模型优点:
  1. 迁移学习的有效应用:通过使用VGG16的预训练权重,模型在图像特征提取方面表现出色,同时减少了对大规模数据集的依赖,加速了训练过程。
  2. 深度网络的特征提取能力强:VGG16的多层卷积结构能够提取复杂的图像特征,尤其适合医学图像中微小病变的检测。
  3. 数据预处理与增强合理:项目采用了图像归一化和标准化,以及图像尺寸调整等预处理措施,有效提高了模型对不同分辨率图像的泛化能力。
  4. 准确性高:通过使用交叉熵损失和Adam优化器,模型在分类任务中的表现稳定,能够较好地完成多分类任务。
模型缺点:
  1. 计算资源需求大:VGG16网络较深,参数较多,尽管特征提取效果好,但其计算复杂度较高,在推理时可能对计算资源要求较高,不适合实时应用场景。
  2. 适应性有限:模型结构未针对医学图像中的特殊结构(如肺部CT的形态学特征)进行专门优化,可能导致在处理非典型病变时表现不佳。
  3. 超参数未优化:项目中未对学习率、批量大小等超参数进行深入优化,可能存在进一步提高模型表现的空间。
改进方向:
  1. 模型结构优化:可以尝试引入轻量化模型(如MobileNet、EfficientNet)或加入注意力机制,增强对医学图像中病变区域的聚焦能力,降低计算成本并提升效率。
  2. 超参数调整:对学习率、优化器、批量大小等超参数进行调优,通过网格搜索或随机搜索等方法找到最佳配置,提高模型性能。
  3. 更多数据增强:可以引入更加丰富的数据增强方法,如随机裁剪、旋转、色彩调整等,以增加训练数据的多样性,提升模型的泛化能力。
  4. 查看更多项目案例/数据集/代码/视频教程:点击进入>>

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

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

相关文章

联想(lenovo) 小新Pro13锐龙版(新机整理、查看硬件配置和系统版本、无线网络问题、windows可选功能)

新机整理 小新pro13win10新机整理 查看硬件配置和系统版本 设置-》系统-》系统信息 无线网络问题 部分热点可以,部分不可以 问题:是因为自己修改了WLAN的IP分配方式为手动分配,导致只能在连接家里无线网的时候可以,连接其他…

51单片机——独立按键

一、独立按键对应单片机P3管脚&#xff0c;如图 二、按键点亮LED灯 #include <STC89C5xRC.H> void main() { while(1) { if(P300) { P200; } else { P201; } } } 当按键为0时&#xff0c;代表按下&#xff0c;所以当P30按下时&#xff0c;让P20&#xff1d;0&#…

Java面试篇基础部分-ReentrantLock详解

ReentrantLock 是继承了Lock接口,并且实现了再接口中定义的方法,属于一个可重入的独占锁。ReentrantLock 通过自定义队列同步器(Abstract Queued Synchroinzed,AQS)来实现锁的获取与释放。   那么什么是独占锁呢?独占锁就是指这个锁在同一时刻只能被一个线程所获取到,…

2024年最新网络协议分析器Wireshark抓包详细教程(更新中)

网络协议分析器 Wireshark 安装 Wireshark 是一个功能强大的网络协议分析器&#xff0c;早期叫作 Ethereal。它主要用于捕获网络数据包&#xff0c;并对这些数据包进行详细的解析和分析&#xff0c;帮助用户深入了解网络通信的细节。它支持多种网络协议&#xff0c;并提供详细…

VM虚拟机下载以及激活

传统的官网已经找不到下载了&#xff0c;这里我将下载好的放在阿里云盘&#xff0c;百度云盘太慢了&#xff0c;懂得都得 阿里云盘分享 下载好了后会是一个exe文件&#xff0c;直接双击运行就可 下载无脑下一步即可&#xff0c;这里不做介绍 下载好了后&#xff0c;需要密钥这里…

如何搭建IP代理池:从零开始的详细指南

在网络应用中&#xff0c;IP代理池是一种非常实用的工具&#xff0c;尤其是在需要大量IP地址进行网络请求时&#xff0c;例如网络爬虫、数据抓取和分布式系统等。通过搭建IP代理池&#xff0c;你可以有效地管理和分配IP地址&#xff0c;避免单一IP地址被封锁&#xff0c;提高网…

高效编程的利器 Jupyter Notebook

目录 前言1. Jupyter Notebook简介1.1 功能特点1.2 使用场景 2. 不同编程工具的对比与效率提升2.1 VS Code&#xff1a;灵活且轻量的代码编辑器2.2 PyCharm&#xff1a;面向专业开发者的集成开发环境2.3 Git&#xff1a;高效协作的版本控制工具2.4 Jupyter Notebook 和 VS Code…

【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物,那么便到不了终点“

【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物&#xff0c;那么便到不了终点“ 1.题目 下方是力扣官方题目的地址 63. 不同路径 II 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下…

【Godot4.x】Mesh相关知识总结

概述 很早之前发布过一篇关于几何体程序生成的文章&#xff0c;当时对于三角面和网格的构造其实还没有特别深入的认识&#xff0c;直到自己脑海里想到用二维数组和点更新的方式构造2D类型的多边形Mesh结构&#xff0c;也意识到在Godot中其实Mesh不仅是3D网格&#xff0c;也可以…

LeetCode 每周算法 6(图论、回溯)

LeetCode 每周算法 6&#xff08;图论、回溯&#xff09; 图论算法&#xff1a; class Solution: def dfs(self, grid: List[List[str]], r: int, c: int) -> None: """ 深度优先搜索函数&#xff0c;用于遍历并标记与当前位置(r, c)相连的所有陆地&…

uni-data-select 使用 localdata 传入数据出现 不回显 | 下拉显示错误的 解决方法

目录 1. 问题所示2. 正确Demo3. 下拉显示错误(Bug复现)4. 下拉不回显(Bug复现)1. 问题所示 uni-app的下拉框uni-data-select 使用 localdata 传入数据 主要总结正确的Demo以及复现一些Bug 数据不回显数据不显示下拉选项2. 正确Demo 详细的基本知识推荐阅读:uni-app中的…

Codeforces Round 974 (Div. 3) A-F

封面原图 画师礼島れいあ 下午的ICPC网络赛的难受一晚上全都给我打没了 手速拉满再加上秒杀线段树 这场简直了啊 唯一可惜的是最后还是掉出了1000名 一把上蓝应该没啥希望了吧 A - Robin Helps 题意 侠盗罗宾因劫富济贫而闻名于世 罗宾遇到的 n n n 人&#xff0c;从 1 s …

springMvc的初始配置

基础文件结构(toWeb插件) 1.导入对应依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"ht…

BLE 设备丢包理解

前言 个人邮箱&#xff1a;zhangyixu02gmail.com在学习 BLE 过程中&#xff0c;总能听到 “丢包” 一词&#xff0c;但是我查阅资料又发现&#xff0c;有大佬说&#xff0c;ATT所有命令都是“必达”的&#xff0c;不存在所谓的“丢包”。而且我发现&#xff0c;在宣传 BLE 产品…

tcp、udp通信调试工具Socket Tool

tcp、udp通信调试工具Socket Tool ]

Rust 运算符快速了解

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 4.1 运 算 符 前面已经学习了变量和常量&#xff0c;本节开始对它们进行操作&am…

java之单链表的基本概念及创建

1.链表的概念: 链表是一种 物理存储结构上非连续 存储结构&#xff0c;数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 组成结构: 由一系列节点组成&#xff0c;每个节点包含数据域和指向下一个节点的指针。 优点: 动态大小&#xff0c;易于插入和删除操作。 缺点…

【网络安全 | 靶机搭建】修改镜像源、更新软件源、安装git、更改python版本等

文章目录 0x00、必要准备0x01、修改镜像源0x02、更新软件源并清除缓存0x03、安装git0x04、更改默认Python版本为python30x05、安装增强功能0x06、vmware虚拟机导出iso0x00、必要准备 安装虚拟机时必须保存用户名、密码,用于后续操作,可以截图保存: 以下内容按个人需要进行配…

如何将生物序列tokenization为token?

原理讲解 tokenization是自然语言处理领域非常成熟的一项技术&#xff0c;tokenization就是把我们研究的语言转换成计算机能够识别的数字——token。 在生物领域&#xff0c;如何把核苷酸或氨基酸序列tokenization成token呢&#xff1f; 我们可以使用k-mer技术&#xff1a; k-m…

GDPU Andriod移动应用 Activity

移动应用开发入门级必看&#xff0c;用活动打造属于你的页面。 重要的更新公告 &#xff01;&#xff01;&#xff01;GDPU的小伙伴&#xff0c;感谢大家的支持&#xff0c;希望到此一游的帅哥美女能有所帮助。本学期的前端框架及移动应用&#xff0c;采用专栏订阅量达到50才开…