当前位置: 首页 > article >正文

【机器学习实战入门】基于深度学习的乳腺癌分类

在这里插入图片描述
什么是深度学习?
作为对机器学习的一种深入方法,深度学习受到了人类大脑和其生物神经网络的启发。它包括深层神经网络、递归神经网络、卷积神经网络和深度信念网络等架构,这些架构由多层组成,数据必须通过这些层才能最终产生输出。深度学习旨在改进人工智能并使许多应用成为可能;它被应用于计算机视觉、语音识别、自然语言处理、音频识别和药物设计等多个领域。

什么是 Keras?
Keras 是一个用 Python 编写的开源神经网络库。它是一个高级 API,并可以在 TensorFlow、CNTK 和 Theano 上运行。Keras 专注于支持快速实验和原型设计,同时在 CPU 和 GPU 上无缝运行。它用户友好、模块化且可扩展。

乳腺癌分类 – 目标
我们将在一个 IDC 数据集上构建一个乳腺癌分类器,可以准确地将组织学图像分类为良性或恶性。

关于 Python 项目 – 乳腺癌分类
在这个 Python 项目中,我们将构建一个分类器,以 80% 的乳腺癌组织学图像数据集进行训练。其中,我们将保留 10% 的数据用于验证。使用 Keras,我们将定义一个 CNN(卷积神经网络),并将其命名为 CancerNet,然后在我们的图像上进行训练。最后,我们将构建一个混淆矩阵来分析模型的性能。

IDC 是浸润性导管癌;这是一种在乳管中开始并在管外侵犯乳腺纤维或脂肪组织的癌症;它是最常见的乳腺癌形式,占所有乳腺癌诊断的 80%。而组织学是研究组织微观结构的学科。

数据集
我们将使用来自 Kaggle 的 IDC_regular 数据集(乳腺癌组织学图像数据集)。这个数据集包含从 162 份乳腺癌整体装片扫描图像中提取的 277524 个 50x50 尺寸的图像块。其中有 198738 个测试结果为 IDC 阴性,78786 个测试结果为 IDC 阳性。数据集公开发布,你可以在这里下载。为此,你需要至少 3.02GB 的磁盘空间。

此数据集中的文件名如下:

8863_idx5_x451_y1451_class0

这里,8863_idx5 是患者编号,451 和 1451 是裁剪图像的 x 和 y 坐标,0 是类别标签(0 表示 IDC 缺失)。

链接: 基于深度学习的乳腺癌分类 源代码与数据集

前提条件
你需要安装一些 Python 包才能运行这个高级 Python 项目。你可以使用 pip 安装:

pip install numpy opencv-python pillow tensorflow keras imutils scikit-learn matplotlib

高级 Python 项目 – 乳腺癌分类的步骤

  1. 下载压缩包。在你选择的位置解压缩它,并进入该位置。
    在这里插入图片描述

乳腺癌检测 Python 项目

  1. 现在,在内部的 breast-cancer-classification 目录中,创建目录 datasets- 在此目录下,创建目录 original:
mkdir datasets
mkdir datasets\original
  1. 下载数据集。

  2. 在 original 目录中解压缩数据集。为了观察该目录的结构,我们将使用 tree 命令:
    在这里插入图片描述

cd breast-cancer-classification\breast-cancer-classification\datasets\original
tree

项目中的原始结构

我们为每个患者编号有一个目录。在每个这样的目录中,我们有存放良性和恶性图像的 0 和 1 目录。

config.py:
这里包含了一些我们构建数据集和训练模型时所需的配置。你可以在 cancernet 目录中找到它。

import os
INPUT_DATASET = "datasets/original"
BASE_PATH = "datasets/idc"
TRAIN_PATH = os.path.sep.join([BASE_PATH, "training"])
VAL_PATH = os.path.sep.join([BASE_PATH, "validation"])
TEST_PATH = os.path.sep.join([BASE_PATH, "testing"])
TRAIN_SPLIT = 0.8
VAL_SPLIT = 0.1

在这里插入图片描述

在这里,我们声明了原始数据集的路径(datasets/original),新目录的路径(datasets/idc),以及使用基本路径声明的训练、验证和测试目录的路径。我们还声明 80% 的整个数据集将用于训练,而其中的 10% 将用于验证。

build_dataset.py:
此脚本将根据上述比例将数据集分割为训练集、验证集和测试集- 80% 用于训练(其中 10% 用于验证),20% 用于测试。使用 Keras 的 ImageDataGenerator,我们将提取图像批处理,以避免一次性将整个数据集加载到内存中。

from cancernet import config
from imutils import paths
import random, shutil, os
originalPaths=list(paths.list_images(config.INPUT_DATASET))
random.seed(7)
random.shuffle(originalPaths)
index=int(len(originalPaths)*config.TRAIN_SPLIT)
trainPaths=originalPaths[:index]
testPaths=originalPaths[index:]
index=int(len(trainPaths)*config.VAL_SPLIT)
valPaths=trainPaths[:index]
trainPaths=trainPaths[index:]
datasets=[("training", trainPaths, config.TRAIN_PATH),
          ("validation", valPaths, config.VAL_PATH),
          ("testing", testPaths, config.TEST_PATH)
]
for (setType, originalPaths, basePath) in datasets:
        print(f'Building {setType} set')
        if not os.path.exists(basePath):
                print(f'Building directory {basePath}')
                os.makedirs(basePath)
        for path in originalPaths:
                file=path.split(os.path.sep)[-1]
                label=file[-5:-4]
                labelPath=os.path.sep.join([basePath,label])
                if not os.path.exists(labelPath):
                        print(f'Building directory {labelPath}')
                        os.makedirs(labelPath)
                newPath=os.path.sep.join([labelPath, file])
                shutil.copy2(path, newPath)

在这里插入图片描述

机器学习 Python 项目

在此脚本中,我们将从 config、imutils、random、shutil 和 os 导入。我们构建一个原始图像路径的列表,然后将列表打乱。接着,我们通过将列表长度乘以 0.8 来计算索引,以便可以截取该列表以创建训练和测试数据集的子列表。然后,我们进一步计算索引,将训练数据集的 10% 用于验证,剩下的用于训练自己。

现在,datasets 是一个包含训练集、验证集和测试集信息的列表。这些信息包括路径和基本路径。对于此列表中的每个 set 类型、路径和基本路径,我们将打印如‘构建测试集’。如果基本路径不存在,我们将创建目录。对于 originalPaths 中的每个路径,我们将提取文件名和类别标签。然后,我们将构建标签目录(0 或 1)的路径-如果它还不存在,我们将明确创建该目录。现在,我们将构建目标图像的路径并将其复制到这里-它所属的位置。

  1. 运行脚本 build_dataset.py:
py build_dataset.py

在这里插入图片描述

构建数据集

cancernet.py:
我们将构建的网络是一个 CNN(卷积神经网络),并命名为 CancerNet。该网络执行以下操作:

  • 使用 3x3 CONV 滤波器
  • 将这些滤波器堆叠在一起
  • 执行最大池化
  • 使用深度分离卷积(更高效,占用较少内存)
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import SeparableConv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras import backend as K
class CancerNet:
  @staticmethod
  def build(width,height,depth,classes):
    model=Sequential()
    shape=(height,width,depth)
    channelDim=-1
    if K.image_data_format()=="channels_first":
      shape=(depth,height,width)
      channelDim=1
    model.add(SeparableConv2D(32, (3,3), padding="same",input_shape=shape))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=channelDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))
    model.add(SeparableConv2D(64, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=channelDim))
    model.add(SeparableConv2D(64, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=channelDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))
    model.add(SeparableConv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=channelDim))
    model.add(SeparableConv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=channelDim))
    model.add(SeparableConv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=channelDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(256))
    model.add(Activation("relu"))
    model.add(BatchNormalization())
    model.add(Dropout(0.5))
    model.add(Dense(classes))
    model.add(Activation("softmax"))
    return model

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

在本脚本中,我们使用 Sequential API 构建 CancerNet,并使用 SeparableConv2D 实现深度卷积。CancerNet 类有一个静态方法 build,它接受四个参数- 图像的宽度和高度、深度(每个图像的颜色通道数)以及网络将在其间预测的类别数,对于我们来说,这一数字为 2(0 和 1)。

在此方法中,我们初始化 model 和 shape。使用 channels_first 时,我们更新 shape 和通道维度。

现在,我们将定义三个 DEPTHWISE_CONV => RELU => POOL 层;每一层都有更高的堆叠和更多的滤波器。softmax 分类器输出每个类别的预测百分比。最后,我们返回模型。

train_model.py:
此脚本用于训练和评估我们的模型。在这里,我们将从 keras、sklearn、cancernet、config、imutils、matplotlib、numpy 和 os 导入。

import matplotlib
matplotlib.use("Agg")
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import LearningRateScheduler
from keras.optimizers import Adagrad
from keras.utils import np_utils
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from cancernet.cancernet import CancerNet
from cancernet import config
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import os
NUM_EPOCHS=40; INIT_LR=1e-2; BS=32
trainPaths=list(paths.list_images(config.TRAIN_PATH))
lenTrain=len(trainPaths)
lenVal=len(list(paths.list_images(config.VAL_PATH)))
lenTest=len(list(paths.list_images(config.TEST_PATH)))
trainLabels=[int(p.split(os.path.sep)[-2]) for p in trainPaths]
trainLabels=np_utils.to_categorical(trainLabels)
classTotals=trainLabels.sum(axis=0)
classWeight=classTotals.max()/classTotals
trainAug = ImageDataGenerator(
  rescale=1/255.0,
  rotation_range=20,
  zoom_range=0.05,
  width_shift_range=0.1,
  height_shift_range=0.1,
  shear_range=0.05,
  horizontal_flip=True,
  vertical_flip=True,
  fill_mode="nearest")
valAug=ImageDataGenerator(rescale=1 / 255.0)
trainGen = trainAug.flow_from_directory(
  config.TRAIN_PATH,
  class_mode="categorical",
  target_size=(48,48),
  color_mode="rgb",
  shuffle=True,
  batch_size=BS)
valGen = valAug.flow_from_directory(
  config.VAL_PATH,
  class_mode="categorical",
  target_size=(48,48),
  color_mode="rgb",
  shuffle=False,
  batch_size=BS)
testGen = valAug.flow_from_directory(
  config.TEST_PATH,
  class_mode="categorical",
  target_size=(48,48),
  color_mode="rgb",
  shuffle=False,
  batch_size=BS)
model=CancerNet.build(width=48,height=48,depth=3,classes=2)
opt=Adagrad(lr=INIT_LR,decay=INIT_LR/NUM_EPOCHS)
model.compile(loss="binary_crossentropy",optimizer=opt,metrics=["accuracy"])
M=model.fit_generator(
  trainGen,
  steps_per_epoch=lenTrain//BS,
  validation_data=valGen,
  validation_steps=lenVal//BS,
  class_weight=classWeight,
  epochs=NUM_EPOCHS)
print("Now evaluating the model")
testGen.reset()
pred_indices=model.predict_generator(testGen,steps=(lenTest//BS)+1)
pred_indices=np.argmax(pred_indices,axis=1)
print(classification_report(testGen.classes, pred_indices, target_names=testGen.class_indices.keys()))
cm=confusion_matrix(testGen.classes,pred_indices)
total=sum(sum(cm))
accuracy=(cm[0,0]+cm[1,1])/total
specificity=cm[1,1]/(cm[1,0]+cm[1,1])
sensitivity=cm[0,0]/(cm[0,0]+cm[0,1])
print(cm)
print(f'Accuracy: {accuracy}')
print(f'Specificity: {specificity}')
print(f'Sensitivity: {sensitivity}')
N = NUM_EPOCHS
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0,N), M.history["loss"], label="train_loss")
plt.plot(np.arange(0,N), M.history["val_loss"], label="val_loss")
plt.plot(np.arange(0,N), M.history["acc"], label="train_acc")
plt.plot(np.arange(0,N), M.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy on the IDC Dataset")
plt.xlabel("Epoch No.")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig('plot.png')

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

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

总结
在这个 Python 项目中,我们学习了如何使用 IDC 数据集(浸润性导管癌的组织学图像)构建一个乳腺癌分类器,并为此创建了 CancerNet 网络。我们使用 Keras 实现了这一点。希望你喜欢这个 Python 项目。

参考资料

资料名称链接
Kaggle IDC 数据集链接
Keras 文档链接
TensorFlow 官方文档链接
Python for Data Science Handbook链接
PyImageSearch 深度学习教程链接
《深度学习》 - Ian Goodfellow链接
Medium 深度学习文章链接
DataFlair Python 项目链接
《利用深度学习对抗癌症》 -.scalatest链接
维基百科 - 乳腺癌链接
中国深度学习社区链接
深度学习读书会链接
Deep Learning Book by Yoshua Bengio链接

关于数据集

背景
浸润性导管癌(IDC)是所有乳腺癌中最常见的亚型。为了对整个组织样本进行侵袭性分级,病理学家通常专注于包含 IDC 的区域。因此,自动侵袭性分级的常见预处理步骤之一是划定整个组织切片中 IDC 的确切区域。

内容
原始数据集包含 162 张乳腺癌(BCa)标本的整个组织切片图像,扫描倍率为 40 倍。从中提取了 277,524 个大小为 50 x 50 的 patches(198,738 个 IDC 阴性,78,786 个 IDC 阳性)。每个 patch 的文件名格式为:u_xX_yY_classC.png —— 例如 10253_idx5_x1351_y1101_class0.png。其中,u 是患者 ID(10253_idx5),X 是该 patch 裁剪位置的 x 坐标,Y 是该 patch 裁剪位置的 y 坐标,C 表示类别,0 为非 IDC,1 为 IDC。

致谢
原始文件位于:http://gleason.case.edu/webdata/jpi-dl-tutorial/IDC_regular_ps50_idx5.zip
引用文献:https://www.ncbi.nlm.nih.gov/pubmed/27563488 和 http://spie.org/Publications/Proceedings/Paper/10.1117/12.2043872

启发
乳腺癌是女性中最常见的癌症形式,而浸润性导管癌(IDC)是乳腺癌中最常见的类型。准确识别和分类乳腺癌亚型是一项重要的临床任务,自动化方法可用于节省时间并减少错误。


http://www.kler.cn/a/509864.html

相关文章:

  • ScratchLLMStepByStep:训练自己的Tokenizer
  • Oracle数据库传统审计怎么用
  • Python操作Excel——openpyxl使用笔记(2)
  • CV 图像处理基础笔记大全(超全版哦~)!!!
  • FastADMIN实现网站启动时执行程序的方法
  • Vue前端框架概述
  • SpringBoot的Bean-中级-作用域
  • 恒比鉴相器(CFD)初探
  • [免费]SpringBoot+Vue小区物业管理系统(高级版)【论文+源码+SQL脚本】
  • Mysql--实战篇--mybatis cache(一级缓存,二级缓存,子查询主键主查询全部,查询条件加索引,覆盖索引等)
  • 技术晋升读书笔记—华为研发
  • 搭建一个基于Spring Boot的书籍学习平台
  • 机器学习经典无监督算法——聚类K-Means算法
  • LabVIEW桥接传感器数据采集与校准程序
  • vue项目创建与运行(idea)
  • 网络安全技术之网络安全
  • 三维扫描赋能文化:蔡司3D扫描仪让木质文化遗产焕发新生-沪敖3D
  • leetcode76-最小覆盖子串
  • 在 Web 应用中集成多种地图 API 的实现与管理
  • WinForm实现无边框拖动的两种方式
  • 三台 Centos7.9 中 Docker 部署 Redis 哨兵模式
  • 每日十题八股-2025年1月18日
  • VScode侧边栏左下角,没有NPM脚本,如何打开???
  • 代码随想录刷题day11|(链表篇)206.翻转链表
  • 20250118在excel中使用公式的时候如何直接拖拽全部到最后
  • ubuntu安全配置基线