深度学习乳腺癌分类 计算机竞赛

文章目录

  • 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 IMGbenign_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 = 3for 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 = 16train_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 modelresnet = 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_matrixdef 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.mzph.cn/news/151339.shtml

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

相关文章

【iOS】——知乎日报第五周总结

文章目录 一、评论区展开与收缩二、FMDB库实现本地持久化FMDB常用类:FMDB的简单使用: 三、点赞和收藏的持久化 一、评论区展开与收缩 有的评论没有被回复评论或者被回复评论过短,这时就不需要展开全文的按钮,所以首先计算被回复评…

Positive Technologies 利用 PT Cloud Application Firewall 保护中小型企业的网络资源

云产品按月订购,无需购买硬件资源 PT Cloud Application Firewall 是 Positive Technologies 推出的首个用于保护网络应用程序的商用云产品。Web 应用层防火墙 (web application firewall, WAF) 现在可以通过 技术合作伙伴——授权服务商和云提供商以订购方式提供1…

Modbus转Profinet网关在污水处理系统中连接PLC和变频器Modbus通信案例

污水处理系统中使用Modbus转Profinet网关可以连接PLC和变频器,实现二者之间的通信。该网关的作用是将PLC与变频器之间的Modbus协议转换为Profinet协议,使两者可以相互沟通。在污水处理系统中,PLC控制污水处理的各个过程,而变频器则…

测试用例的设计方法(全):正交实验设计方法|功能图分析方法|场景设计方发

正交实验设计方法 一.方法简介 利用因果图来设计测试用例时, 作为输入条件的原因与输出结果之间的因果关系,有时很难从软件需求规格说明中得到。往往因果关系非常庞大,以至于据此因果图而得到的测试用例数目多的惊人,给软件测试带来沉重的负担,为了有效…

vue过渡,vue3组合式API详细介绍

7.过渡效果 vue提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画 Transition会在一个元素或组件进入和离开DOM时应用动画TransitionGroup会在一个v-for列表中的元素或组件被插入,移动,或移除时应用动画 7-1过渡效果 过渡模式 <Transition mode"out-in&q…

Linux文件目录以及文件类型

文章目录 Home根目录 //bin/sbin/etc/root/lib/dev/proc/sys/tmp/boot/mnt/media/usr 文件类型 Home 当尝试使用gedit等编辑器保存文件时&#xff0c;系统默认通常会先打开个人用户的“家”&#xff08;home&#xff09;目录&#xff0c; 建议在通常情况下个人相关的内容也是保…

使用 VPN ,一定要知道的几个真相!

你们好&#xff0c;我的网工朋友。 今天想和你聊聊VPN。在VPN出现之前&#xff0c;企业分支之间的数据传输只能依靠现有物理网络&#xff08;例如Internet&#xff09;。 但由于Internet中存在多种不安全因素&#xff0c;报文容易被网络中的黑客窃取或篡改&#xff0c;最终造…

requests爬虫IP连接初始化问题及解决方案

问题背景 在使用HTTPS爬虫IP连接时&#xff0c;如果第一次请求是chunked方式&#xff0c;那么HTTPS爬虫IP连接将不会被初始化。这个问题可能会导致403错误&#xff0c;或者在使用HTTPS爬虫IP时出现SSL错误。 解决方案 为了解决这个问题&#xff0c;我们可以在requests库的ada…

多维时序 | MATLAB实现PSO-BiGRU-Attention粒子群优化双向门控循环单元融合注意力机制的多变量时间序列预测

多维时序 | MATLAB实现PSO-BiGRU-Attention粒子群优化双向门控循环单元融合注意力机制的多变量时间序列预测 目录 多维时序 | MATLAB实现PSO-BiGRU-Attention粒子群优化双向门控循环单元融合注意力机制的多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 …

03-关系和非关系型数据库对比

关系和非关系型数据库对比 关系型数据库(RDBMS)&#xff1a;MySQL、Oracl、DB2、SQLServer 非关系型数据库(NoSql)&#xff1a;Redis、Mongo DB、MemCached 插入数据结构的区别 传统关系型数据库是结构化数据,向表中插入数据时都需要严格的约束信息(如字段名,字段数据类型,字…

Java概述

接触Java后会发现它的体系有一个特点&#xff0c;就是非常喜欢用“J”字母开头的缩写&#xff0c;比如JCP, JSR, JMS, JPA, JSP, JAX-RS......它们有些是规范&#xff0c;有些是组织的名称&#xff0c;表意多样&#xff0c;对第一次接触的人来说很可能会觉得混乱&#xff0c;本…

基于水基湍流算法优化概率神经网络PNN的分类预测 - 附代码

基于水基湍流算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于水基湍流算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于水基湍流优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

Nginx-负载均衡-动静分离-虚拟主机

负载均衡 负载均衡基本使用 1 配置上游服务器 upstream myserver { #是server外层server ip1:8080;server ip1:8080; }2 配置代理 server {location / { proxy_pass http://myserver;#请求转向myserver 定义的服务器列表 注意这个http不能丢 pro…

Git 分支设计规范

开篇 这篇文章分享 Git 分支设计规范&#xff0c;目的是提供给研发人员做参考。 规范是死的&#xff0c;人是活的&#xff0c;希望自己定的规范&#xff0c;不要被打脸。 在说 Git 分支规范之前&#xff0c;先说下在系统开发过程中常用的环境。 DEV 环境&#xff1a;用于开发…

数电实验-----实现74LS153芯片扩展为8选1数据选择器以及应用(Quartus II )

目录 一、74LS153芯片介绍 管脚图 功能表 二、4选1选择器扩展为8选1选择器 1.扩展原理 2.电路图连接&#xff08;Quartus II &#xff09; 3.仿真结果 三、8选1选择器的应用 1.三变量表决器 2.奇偶校验电路 一、74LS153芯片介绍 74ls153芯片是属于四选一选择器的芯片。…

系列五、GC垃圾回收【四大垃圾算法-复制算法】

一、堆的内存组成 二、复制算法 2.1、发生位置 复制算法主要发生在新生代&#xff0c;发生在新生代的垃圾回收也被叫做Minor GC。 2.2、 Minor GC的过程 复制>清空》交换 1、eden、from区中的对象复制到to区&#xff0c;年龄1 首先&#xff0c;当eden区满的时候会触发第一…

【数据结构初阶】双链表

双链表 1.双链表的实现1.1结口实现1.2申请结点1.3初始化双链表1.4打印双链表1.5尾插1.6尾删1.7头插1.8头删1.9计算大小1.10查找1.11pos位置插入1.12删除pos位置1.12删除双链表 全部码源 1.双链表的实现 1.1结口实现 #include<stdio.h> #include<stdlib.h> #inclu…

STM32F4系列单片机GPIO概述和寄存器分析

第2章 STM32-GPIO口 2.1 GPIO口概述 通用输入/输出口 2.1.1 GPIO口作用 GPIO是单片机与外界进行数据交流的窗口。 2.1.2 STM32的GPIO口 在51单片机中&#xff0c;IO口&#xff0c;以数字进行分组&#xff08;P0~P3&#xff09;&#xff0c;每一组里面又有8个IO口。 在ST…

AcWing 717. 简单斐波那契

原题链接 题目 以下数列 0 1 1 2 3 5 8 13 21 … 被称为斐波纳契数列。 这个数列从第 3 项开始&#xff0c;每一项都等于前两项之和。 输入一个整数 N &#xff0c;请你输出这个序列的前 N 项。 输入格式 一个整数 N 。 输出格式 在一行中输出斐波那契数列的前 N 项&…

共享内存和信号量的配合机制

进程之间共享内存的机制&#xff0c;有了这个机制&#xff0c;两个进程可以像访问自己内存中的变量一样&#xff0c;访问共享内存的变量。但是同时问题也来了&#xff0c;当两个进程共享内存了&#xff0c;就会存在同时读写的问题&#xff0c;就需要对于共享的内存进行保护&…