竞赛保研 基于卷积神经网络的乳腺癌分类 深度学习 医学图像

news2025/1/21 15:28:17

文章目录

  • 1 前言
  • 2 前言
  • 3 数据集
    • 3.1 良性样本
    • 3.2 病变样本
  • 4 开发环境
  • 5 代码实现
    • 5.1 实现流程
    • 5.2 部分代码实现
      • 5.2.1 导入库
      • 5.2.2 图像加载
      • 5.2.3 标记
      • 5.2.4 分组
      • 5.2.5 构建模型训练
  • 6 分析指标
    • 6.1 精度,召回率和F1度量
    • 6.2 混淆矩阵
  • 7 结果和结论
  • 8 最后

1 前言

🔥 优质竞赛项目系列,今天要分享的是

基于卷积神经网络的乳腺癌分类

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

2 前言

乳腺癌是全球第二常见的女性癌症。2012年,它占所有新癌症病例的12%,占所有女性癌症病例的25%。

当乳腺细胞生长失控时,乳腺癌就开始了。这些细胞通常形成一个肿瘤,通常可以在x光片上直接看到或感觉到有一个肿块。如果癌细胞能生长到周围组织或扩散到身体的其他地方,那么这个肿瘤就是恶性的。

以下是报告:

  • 大约八分之一的美国女性(约12%)将在其一生中患上浸润性乳腺癌。
  • 2019年,美国预计将有268,600例新的侵袭性乳腺癌病例,以及62,930例新的非侵袭性乳腺癌。
  • 大约85%的乳腺癌发生在没有乳腺癌家族史的女性身上。这些发生是由于基因突变,而不是遗传突变
  • 如果一名女性的一级亲属(母亲、姐妹、女儿)被诊断出患有乳腺癌,那么她患乳腺癌的风险几乎会增加一倍。在患乳腺癌的女性中,只有不到15%的人的家人被诊断出患有乳腺癌。

3 数据集

该数据集为学长实验室数据集。

搜先这是图像二分类问题。我把数据拆分如图所示

    dataset train
      benign
       b1.jpg
       b2.jpg
       //
      malignant
       m1.jpg
       m2.jpg
       //  validation
       benign
        b1.jpg
        b2.jpg
        //
       malignant
        m1.jpg
        m2.jpg
        //...

训练文件夹在每个类别中有1000个图像,而验证文件夹在每个类别中有250个图像。

3.1 良性样本

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

3.2 病变样本

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

4 开发环境

  • scikit-learn
  • keras
  • numpy
  • pandas
  • matplotlib
  • tensorflow

5 代码实现

5.1 实现流程

完整的图像分类流程可以形式化如下:

我们的输入是一个由N个图像组成的训练数据集,每个图像都有相应的标签。

然后,我们使用这个训练集来训练分类器,来学习每个类。

最后,我们通过让分类器预测一组从未见过的新图像的标签来评估分类器的质量。然后我们将这些图像的真实标签与分类器预测的标签进行比较。

5.2 部分代码实现

5.2.1 导入库

  
    import json
    import math
    import os
    import cv2
    from PIL import Image
    import numpy as np
    from keras import layers
    from keras.applications import DenseNet201
    from keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau, TensorBoard
    from keras.preprocessing.image import ImageDataGenerator
    from keras.utils.np_utils import to_categorical
    from keras.models import Sequential
    from keras.optimizers import Adam
    import matplotlib.pyplot as plt
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import cohen_kappa_score, accuracy_score
    import scipy
    from tqdm import tqdm
    import tensorflow as tf
    from keras import backend as K
    import gc
    from functools import partial
    from sklearn import metrics
    from collections import Counter
    import json
    import itertools

5.2.2 图像加载

接下来,我将图像加载到相应的文件夹中。


    def Dataset_loader(DIR, RESIZE, sigmaX=10):
        IMG = []
        read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))
        for IMAGE_NAME in tqdm(os.listdir(DIR)):
            PATH = os.path.join(DIR,IMAGE_NAME)
            _, ftype = os.path.splitext(PATH)
            if ftype == ".png":
                img = read(PATH)
               

                img = cv2.resize(img, (RESIZE,RESIZE))
               
                IMG.append(np.array(img))
        return IMG
    
    benign_train = np.array(Dataset_loader('data/train/benign',224))
    malign_train = np.array(Dataset_loader('data/train/malignant',224))
    benign_test = np.array(Dataset_loader('data/validation/benign',224))
    malign_test = np.array(Dataset_loader('data/validation/malignant',224))

5.2.3 标记

之后,我创建了一个全0的numpy数组,用于标记良性图像,以及全1的numpy数组,用于标记恶性图像。我还重新整理了数据集,并将标签转换为分类格式。


    benign_train_label = np.zeros(len(benign_train))
    malign_train_label = np.ones(len(malign_train))
    benign_test_label = np.zeros(len(benign_test))
    malign_test_label = np.ones(len(malign_test))
    

    X_train = np.concatenate((benign_train, malign_train), axis = 0)
    Y_train = np.concatenate((benign_train_label, malign_train_label), axis = 0)
    X_test = np.concatenate((benign_test, malign_test), axis = 0)
    Y_test = np.concatenate((benign_test_label, malign_test_label), axis = 0)
    
    s = np.arange(X_train.shape[0])
    np.random.shuffle(s)
    X_train = X_train[s]
    Y_train = Y_train[s]
    
    s = np.arange(X_test.shape[0])
    np.random.shuffle(s)
    X_test = X_test[s]
    Y_test = Y_test[s]
    
    Y_train = to_categorical(Y_train, num_classes= 2)
    Y_test = to_categorical(Y_test, num_classes= 2)

5.2.4 分组

然后我将数据集分成两组,分别具有80%和20%图像的训练集和测试集。让我们看一些样本良性和恶性图像


    x_train, x_val, y_train, y_val = train_test_split(
        X_train, Y_train, 
        test_size=0.2, 
        random_state=11
    )
    

    w=60
    h=40
    fig=plt.figure(figsize=(15, 15))
    columns = 4
    rows = 3
    
    for i in range(1, columns*rows +1):
        ax = fig.add_subplot(rows, columns, i)
        if np.argmax(Y_train[i]) == 0:
            ax.title.set_text('Benign')
        else:
            ax.title.set_text('Malignant')
        plt.imshow(x_train[i], interpolation='nearest')
    plt.show()

在这里插入图片描述

5.2.5 构建模型训练

我使用的batch值为16。batch是深度学习中最重要的超参数之一。我更喜欢使用更大的batch来训练我的模型,因为它允许从gpu的并行性中提高计算速度。但是,众所周知,batch太大会导致泛化效果不好。在一个极端下,使用一个等于整个数据集的batch将保证收敛到目标函数的全局最优。但是这是以收敛到最优值较慢为代价的。另一方面,使用更小的batch已被证明能够更快的收敛到好的结果。这可以直观地解释为,较小的batch允许模型在必须查看所有数据之前就开始学习。使用较小的batch的缺点是不能保证模型收敛到全局最优。因此,通常建议从小batch开始,通过训练慢慢增加batch大小来加快收敛速度。

我还做了一些数据扩充。数据扩充的实践是增加训练集规模的一种有效方式。训练实例的扩充使网络在训练过程中可以看到更加多样化,仍然具有代表性的数据点。

然后,我创建了一个数据生成器,自动从文件夹中获取数据。Keras为此提供了方便的python生成器函数。


    BATCH_SIZE = 16

    train_generator = ImageDataGenerator(
            zoom_range=2,  # 设置范围为随机缩放
            rotation_range = 90,
            horizontal_flip=True,  # 随机翻转图片
            vertical_flip=True,  # 随机翻转图片
        )

下一步是构建模型。这可以通过以下3个步骤来描述:

  • 我使用DenseNet201作为训练前的权重,它已经在Imagenet比赛中训练过了。设置学习率为0.0001。

  • 在此基础上,我使用了globalaveragepooling层和50%的dropout来减少过拟合。

  • 我使用batch标准化和一个以softmax为激活函数的含有2个神经元的全连接层,用于2个输出类的良恶性。

  • 我使用Adam作为优化器,使用二元交叉熵作为损失函数。

    
    
    def build_model(backbone, lr=1e-4):
        model = Sequential()
        model.add(backbone)
        model.add(layers.GlobalAveragePooling2D())
        model.add(layers.Dropout(0.5))
        model.add(layers.BatchNormalization())
        model.add(layers.Dense(2, activation='softmax'))
        
    
        model.compile(
            loss='binary_crossentropy',
            optimizer=Adam(lr=lr),
            metrics=['accuracy']
        )
        return model
    
    resnet = DenseNet201(
        weights='imagenet',
        include_top=False,
        input_shape=(224,224,3)
    )
    
    model = build_model(resnet ,lr = 1e-4)
    model.summary()
    

让我们看看每个层中的输出形状和参数。

在这里插入图片描述
在训练模型之前,定义一个或多个回调函数很有用。非常方便的是:ModelCheckpoint和ReduceLROnPlateau。

  • ModelCheckpoint:当训练通常需要多次迭代并且需要大量的时间来达到一个好的结果时,在这种情况下,ModelCheckpoint保存训练过程中的最佳模型。

  • ReduceLROnPlateau:当度量停止改进时,降低学习率。一旦学习停滞不前,模型通常会从将学习率降低2-10倍。这个回调函数会进行监视,如果在’patience’(耐心)次数下,模型没有任何优化的话,学习率就会降低。

在这里插入图片描述

该模型我训练了60个epoch。


    learn_control = ReduceLROnPlateau(monitor='val_acc', patience=5,
                                      verbose=1,factor=0.2, min_lr=1e-7)
    

    filepath="weights.best.hdf5"
    checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
    
    history = model.fit_generator(
        train_generator.flow(x_train, y_train, batch_size=BATCH_SIZE),
        steps_per_epoch=x_train.shape[0] / BATCH_SIZE,
        epochs=20,
        validation_data=(x_val, y_val),
        callbacks=[learn_control, checkpoint]
    )

6 分析指标

评价模型性能最常用的指标是精度。然而,当您的数据集中只有2%属于一个类(恶性),98%属于其他类(良性)时,错误分类的分数就没有意义了。你可以有98%的准确率,但仍然没有发现恶性病例,即预测的时候全部打上良性的标签,这是一个不好的分类器。


    history_df = pd.DataFrame(history.history)
    history_df[['loss', 'val_loss']].plot()
    

    history_df = pd.DataFrame(history.history)
    history_df[['acc', 'val_acc']].plot()

在这里插入图片描述

6.1 精度,召回率和F1度量

为了更好地理解错误分类,我们经常使用以下度量来更好地理解真正例(TP)、真负例(TN)、假正例(FP)和假负例(FN)。

精度反映了被分类器判定的正例中真正的正例样本的比重。

召回率反映了所有真正为正例的样本中被分类器判定出来为正例的比例。

F1度量是准确率和召回率的调和平均值。

在这里插入图片描述

6.2 混淆矩阵

混淆矩阵是分析误分类的一个重要指标。矩阵的每一行表示预测类中的实例,而每一列表示实际类中的实例。对角线表示已正确分类的类。这很有帮助,因为我们不仅知道哪些类被错误分类,还知道它们为什么被错误分类。


    from sklearn.metrics import classification_report
    classification_report( np.argmax(Y_test, axis=1), np.argmax(Y_pred_tta, axis=1))
    

    from sklearn.metrics import confusion_matrix
    
    def plot_confusion_matrix(cm, classes,
                              normalize=False,
                              title='Confusion matrix',
                              cmap=plt.cm.Blues):
        if normalize:
            cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
            print("Normalized confusion matrix")
        else:
            print('Confusion matrix, without normalization')
    
        print(cm)
    
        plt.imshow(cm, interpolation='nearest', cmap=cmap)
        plt.title(title)
        plt.colorbar()
        tick_marks = np.arange(len(classes))
        plt.xticks(tick_marks, classes, rotation=55)
        plt.yticks(tick_marks, classes)
        fmt = '.2f' if normalize else 'd'
        thresh = cm.max() / 2.
        for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
            plt.text(j, i, format(cm[i, j], fmt),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")
    
        plt.ylabel('True label')
        plt.xlabel('Predicted label')
        plt.tight_layout()
    
    cm = confusion_matrix(np.argmax(Y_test, axis=1), np.argmax(Y_pred, axis=1))
    
    cm_plot_label =['benign', 'malignant']
    plot_confusion_matrix(cm, cm_plot_label, title ='Confusion Metrix for Skin Cancer')


在这里插入图片描述

7 结果和结论

在这里插入图片描述
在这个博客中,学长我演示了如何使用卷积神经网络和迁移学习从一组显微图像中对良性和恶性乳腺癌进行分类,希望对大家有所帮助。

8 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

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

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

相关文章

数据库——创建存储过程、函数和触发器安装phpmyadmin

1.实验内容及原理 1. 在 Windows 系统中安装 VMWare 虚拟机,在 VMWare 中安装 Ubuntu 系统,并在 Ubuntu 中搭建 LAMP 实验环境。 2. 使用 MySQL 进行一些基本操作: (1)登录 MySQL,在 MySQL 中创建用户,…

基于ssm的二手商品交易平台+vue论文

摘 要 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古…

NFC物联网智慧校园解决方案

近场通信(Near Field Communication,NFC)又称近距离无线通信,是一种短距离的高频无线通信技术,允许电子设备之间进行非接触式点对点数据传输交换数据。这个技术由免接触式射频识别(RFID)发展而来,并兼容 RFID,主要用于…

vue实力挂载的过程中都发生了什么?今天来聊聊Vue实例挂载的过程

一、思考 我们都听过知其然知其所以然这句话 那么不知道大家是否思考过new Vue()这个过程中究竟做了些什么?过程中是如何完成数据的绑定,又是如何将数据渲染到视图的等等 一、分析 首先找到vue的构造函数 源码位置:src\core\instance\in…

SAP CO系统配置-与PS集成相关配置(机器人制造项目实例)

维护分配结构 配置路径 IMG菜单路径:控制>内部订单>实际过帐>结算>维护分配结构 事务代码 OKO6 维护结算参数文件 定义利润分析码

C# 通过SharpCompress.Archives.Rar解压RaR文件

/// <summary>/// 解压一个Rar文件/// </summary>/// <param name"RarFile">需要解压的Rar文件&#xff08;绝对路径&#xff09;</param>/// <param name"TargetDirectory">解压到的目录</param>/// <param name&…

4.26 构建onnx结构模型-Suqeeze

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Suqeeze 结点进行分析 方式 方法一…

普中STM32-PZ6806L开发板(HAL库函数实现-USART1 printf+scanf/gets)

简介 实现printfscanf/gets通过USART1 的发送接收。 电路原理图 板载USB CH340串口电路原理图主芯片串口引脚图 我的板子板子自带串口坏掉了, 所以使用USB转TTL线, 连接如下 电路原理图 实物图 其他知识 scanf是以空白符(空格、制表符、换行等等)为结束标志的,当遇到空白符…

antv/x6_2.0学习使用(三、内置节点和自定义节点)

内置节点和自定义节点 一、节点渲染方式 X6 是基于 SVG 的渲染引擎&#xff0c;可以使用不同的 SVG 元素渲染节点和边&#xff0c;非常适合节点内容比较简单的场景。面对复杂的节点&#xff0c; SVG 中有一个特殊的 foreignObject 元素&#xff0c;在该元素中可以内嵌任何 XH…

MybatisPlus关于${ew.customSqlSegment},${ew.sqlSegment},${ew.sqlSelect},${ew.sqlSet}

Wrapper中 ${ew.customSqlSegment} 是where 条件 ${ew.sqlSegment} 只有条件 ${ew.sqlSelect}是指查询的字段,如果需要使用 ${ew.sqlSet}是在更新时候使用,使用方式 了解即可,不建议使用 毕竟${}有sql注入风险

基于ssm的教师办公管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本教师办公管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

算法刷题:最大异或对(Trie树扩展)、食物链(并查集扩展)

目录 引言一、最大异或对&#xff08;Trie树扩展&#xff09;1.题目描述2.解题思路3.代码实现4.测试 二、食物链&#xff08;并查集扩展&#xff09;1.题目描述2.解题思路3.代码实现4.测试 引言 这两个扩展题能够让我们更加的熟悉Trie树和并查集的使用&#xff0c;这两道题可以…

AI人工智能大模型讲师叶梓《基于人工智能的内容生成(AIGC)理论与实践》培训提纲

【课程简介】 本课程介绍了chatGPT相关模型的具体案例实践&#xff0c;通过实操更好的掌握chatGPT的概念与应用场景&#xff0c;可以作为chatGPT领域学习者的入门到进阶级课程。 【课程时长】 1天&#xff08;6小时/天&#xff09; 【课程对象】 理工科本科及以上&#xff0…

用通俗易懂的方式讲解大模型:HugggingFace 推理 API、推理端点和推理空间使用详解

接触 AI 的同学肯定对HuggingFace[1]有所耳闻&#xff0c;它凭借一个开源的 Transformers 库迅速在机器学习社区大火&#xff0c;为研究者和开发者提供了大量的预训练模型&#xff0c;成为机器学习界的 GitHub。 在 HuggingFace 上我们不仅可以托管模型&#xff0c;还可以方便…

C#上位机与欧姆龙PLC的通信08----开发自己的通讯库读写数据

1、介绍 前面已经完成了7项工作&#xff1a; C#上位机与欧姆龙PLC的通信01----项目背景-CSDN博客 C#上位机与欧姆龙PLC的通信02----搭建仿真环境-CSDN博客 C#上位机与欧姆龙PLC的通信03----创建项目工程-CSDN博客 C#上位机与欧姆龙PLC的通信04---- 欧姆龙plc的存储区 C#上…

平台无关性和语言无关性的记录

目录 背景 平台无关性 语言无关性 背景 最近在学习Java虚拟机&#xff08;JVM: Java Virtual Machine&#xff09;,在学习过程中&#xff0c;再一次学习了JVM的平台无关性这一特性&#xff0c;此外也了解到了虚拟机的另外一种中立特性 --- 语言无关性&#xff0c;下面进行简单…

挂载与解挂载

一. 挂载 1.什么是挂载 将系统中的文件夹和磁盘做上关联&#xff0c;使用文件夹等于使用磁盘 2.mount 2.1 格式 mount [ -t 类型 ] 存储设备 挂载点目录 mount -o loop ISO镜像文件 挂载点目录 注意&#xff1a;指明要挂载的设备 设备文件&#xff1a;例如:/dev/sda5 卷…

leetcode链表小练(1.反转链表2.链表的中间节点3.合并两个有序链表4.环形链表①5.环形链表②)详解 (୨୧• ᴗ •͈)◞︎ᶫᵒᵛᵉ ♡

目录 一.反转链表 思路一反转指针反向&#xff1a; 思路二头插法&#xff1a; 二.链表的中间节点&#xff1a; 三.合并两个有序数组: 思路一&#xff1a;从头开始&#xff0c;取两个链表中小的那个尾插到新链表。定义指针head,tail指向空&#xff0c;代表新链表的头结点。…

软件开发生命周期的四种模型

1、大爆炸模型 大爆炸模型计划、进度安排和正规开发过程几乎没有&#xff0c;所有精力都花在开发软件和编写代码上。假如产品需求无须很好理解&#xff0c;而且最终发布日期可以随便更改&#xff0c;这样的开发过程当然很理想。此外&#xff0c;还要有聪慧过人的客户&#xff0…

专业PDF编辑和管理软件Acrobat Pro DC mac功能特点

Acrobat Pro DC mac是一款专业级PDF编辑和管理软件。作为PDF行业的标准工具&#xff0c;它提供了广泛的功能和工具&#xff0c;适用于个人用户、企业和专业人士。 Acrobat Pro DC具备丰富的编辑功能&#xff0c;可以对PDF文件进行文本编辑、图像编辑和页面重排等操作。用户可以…