软件杯 深度学习乳腺癌分类

文章目录

  • 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 前言

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

🚩 深度学习乳腺癌分类

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

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 更多资料, 项目分享:

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

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

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

相关文章

【正点原子探索者STM32F4】TFTLCD实验学习记录:FSMC控制 TFTLCD的寄存器配置

FSMC控制 TFTLCD的寄存器配置 异步模式 A控制 TFTLCDFSMC寄存器配置ILI9341电平持续时间要求 参考 异步模式 A控制 TFTLCD LCD以ILI9341为例 FSMC寄存器配置 对于异步突发访问方式, FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、 数据 建立时间…

docker的安装及入门指令

目录 一、将docker安装到云服务器步骤 1.更新系统yum版本 2.安装所需依赖 3.添加docker仓库设置(使用的是阿里云) 4.安装docker引擎 5.启动docker并开启自动启动 6. 检查是否安装成功,成功会显示相应版本,否则安装失败 二、docker常用命令 1.从…

使用LIO-SAM进行点云赋色 与 激光雷达和相机的精细化标定(防止自己忘记的博客)----- 激光雷达和相机的精细化标定

目录 1 标定相机 2 激光雷达、相机粗标定 3 精细化标定激光雷达和相机 1 标定相机 使用Kaliber标定D435i相机,本次标定的分辨率为1920*1080,相机的内参如下: FX:1439.96402547 FY:1442.82612329 CX:979.0…

Hadoop-MapReduce

一、MapReduce 概述 1.1 MapReduce 定义 MapReduce 是一个分布式运算程序的编程框架,是用户开发“基于 Hadoop 的数据分析应用”的核心框架。 MapReduce 核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在…

需求分析及设计定义

背景 经过不断的折腾,一切过程都是为了呈现输出,这个阶段就是要交付需求和方案的环节了,很多失败的项目就是上来就到这个环节,倒着捣鼓,先写个文档,做个原型,甚至提出方案,然后再和…

KeyguardClockSwitch的父类

KeyguardClockSwitch 定义在KeyguardStatusView中, mClockView findViewById(R.id.keyguard_clock_container);KeyguardClockSwitch的父类为: Class Name: LinearLayout Class Name: KeyguardStatusView Class Name: NotificationPanelView Class Name: Notificat…

设计模式总结-简单工厂模式

简单工厂模式 创建型模式创建型模式概述创建型模式种类 简单工厂模式模式定义模式动机模式结构模式分析模式实例与解析实例一:简单电视机工厂实例二:权限管理 模式优缺点简单工厂模式的优点简单工厂模式的缺点 模式适用环境模式扩展 小结 创建型模式 创…

redis进阶入门主从复制与哨兵集群

一、主从复制 1.1背景 一般来说,要将 Redis用于工程项目中,只使用一台 Redist是万万不能的,原因如下: 从结构上,单个 Redist服务器会发生单点故障,井且一台服务器需要处理所有的请求负載,压力…

ABBYY FineReader15免费电脑OCR图片文字识别软件

产品介绍:ABBYY FineReader 15 OCR图片文字识别软件 ABBYY FineReader 15是一款光学字符识别(OCR)软件,专门设计用于将扫描的文档、图像和照片中的文本转换成可编辑和可搜索的格式。这款软件利用先进的OCR技术,能够识别…

使用 LLMLingua-2 压缩 GPT-4 和 Claude 提示

原文地址:Compress GPT-4 and Claude prompts with LLMLingua-2 2024 年 4 月 1 日 向大型语言模型(LLM)发送的提示长度越短,推理速度就会越快,成本也会越低。因此,提示压缩已经成为LLM研究的热门领域。 …

【opencv】教程代码 —ml (主成分分析、支持向量机、非线性支持向量机)

1. introduction_to_pca.cpp 主成分分析 /*** file introduction_to_pca.cpp* brief 这个程序演示了如何使用OpenCV PCA 提取物体的方向* author OpenCV团队*/// 包含OpenCV函数库所需要的头文件 #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp&q…

人工智能数据分析Python常用库 04 matplotlib库

文章目录 一、matplotlib库的作用与环境配置1、环境配置示例2、改变绘图风格3、保存图片 二、绘制二维图形1、折线图(1)示例(2)调整线条颜色:(3)调整线条风格(4)调整线宽…

深入浅出 -- 系统架构之分布式CAP理论和BASE理论

科技进步离不开理论支撑,而当下大行其道的分布式架构,透过繁荣昌盛表象,底层同样离不开诸多分布式理论撑持。当然,相信诸位在学习分布式相关技术时,必然学到过两个分布式领域中的基础理论,即:CA…

设置Chrome打开链接在新标签页显示

Chrome版本 版本 123.0.6312.106(正式版本) (64 位) 下面这两个页面都有设置按钮: https://www.google.com/?pli1或者https://www.google.com/?hlzh-CN 要先退出账号,要不然看不到右下角的 “设置” 。…

SpamSieve mac垃圾邮件过滤器 直装激活版

SpamSieve通过强大的垃圾邮件过滤技术,帮助用户有效管理和消除不想要的电子邮件。它能与多种电子邮件客户端无缝集成,如Apple Mail、Microsoft Outlook、Airmail等。 软件下载:SpamSieve mac直装激活版下载 该软件利用先进的算法和机器学习技…

Vue知识点(学习笔记)

Vue知识点学习 一、Vue快速上手1. 脚本引用 二、Vue小知识1. 简写v-bindv-modelel和data的两种写法:eldata 2. MVVM模型3. Object.defineproperty方法4. Vue的数据代理5. 事件处理6. 阻止默认事件7. Vue中事件修饰符:8. 引入Element-Ui 一、Vue快速上手 …

虚幻UE5数字孪生蓝图开发教程

一、背景 这几年,智慧城市/智慧交通/智慧水利等飞速发展,骑士特意为大家做了一个这块的学习路线。 二、这是学习大纲 1.给虚幻UE5初学者准备的智慧城市/数字孪生蓝图开发教程 https://www.bilibili.com/video/BV1894y1u78G 2.UE5数字孪生蓝图开发教学…

BPMNJS 在原生HTML中的引入与使用

BPMNJS 在HTML中的引入与使用 在网上看到的大多是基于vue使用BPMN的示例或者教程,竟然没有在HTML使用的示例,有也是很简单的介绍核心库的引入和使用,并没有涉及到扩展库。于是简单看了下,真的是一波三折,坎坎坷坷。不…

FreeRtos入门-5 任务通知

在FreeRTOS中,任务通知、队列、信号量和事件组都是用于任务间通信和同步的机制,但它们各自具有不同的特性和适用场景。 任务通知的主要优势在于其高效性和明确性。使用任务通知发送事件或数据给某个任务时,效率更高,且可以明确指定…

Tuxera2023 NTFS for Mac下载,安装和序列号激活

对于必须在Windows电脑和Mac电脑之间来回切换的Mac朋友来说,跨平台不兼容一直是一个巨大的障碍,尤其是当我们需要使用NTFS格式的硬盘在Windows和macOS之间共享文件时。因为Mac默认不支持写入NTFS磁盘。 为了解决这一问题,很多朋友会选择很便捷…