矩池云 | 新冠肺炎防控:肺炎 CT 检测

本贴最后更新于 1205 天前,其中的信息可能已经水流花落

连日来,新型冠状病毒感染的肺炎疫情,牵动的不仅仅是全武汉、全湖北,更是全国人民的心,大家纷纷以自己独特的方式为武汉加油!我们相信坚持下去,终会春暖花开。

今天让我们以简单实用的神经网络模型,来检测肺炎的 CT 影像。

第一步:导入我们需要的库

from keras.preprocessing.image import ImageDataGenerator, load_img
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, ZeroPadding2D, Conv2D, MaxPooling2D, Activation
from keras.optimizers import Adam, SGD, RMSprop
from keras.callbacks import EarlyStopping
from keras import backend as K

import tensorflow as tf
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.9
K.tensorflow_backend.set_session(tf.Session(config=config))

import os
import numpy as np
import pandas as np
import cv2

from glob import glob

import matplotlib.pyplot as plt
%matplotlib inline

第二步:数据查看

2.1 先确认下我们数据的目录结构:

在 chest_xray 文件夹中,我们将数据分成了训练病例数据(train), 测试病例数据(test), 验证病例数据(val);

每个训练数据,测试数据,验证数据的文件夹中我们又分成了正常的病例数据(normal), 肺炎病例数据(pneumonia)。

print("训练病例数据")
print(os.listdir("chest_xray"))
print(os.listdir("chest_xray/train"))
print(os.listdir("chest_xray/train/"))

训练病例数据

['test', 'train', 'val', '.DS_Store']

['NORMAL', '.DS_Store', 'PNEUMONIA']

['NORMAL', '.DS_Store', 'PNEUMONIA']

print("测试病例数据")
print(os.listdir("chest_xray"))
print(os.listdir("chest_xray/test"))
print(os.listdir("chest_xray/test/"))

测试病例数据

['test', 'train', 'val', '.DS_Store']

['NORMAL', '.DS_Store', 'PNEUMONIA']

['NORMAL', '.DS_Store', 'PNEUMONIA']

print("验证病例数据")
print(os.listdir("chest_xray"))
print(os.listdir("chest_xray/val"))
print(os.listdir("chest_xray/val/"))

验证病例数据

['test', 'train', 'val', '.DS_Store']

['NORMAL', '.DS_Store', 'PNEUMONIA']

['NORMAL', '.DS_Store', 'PNEUMONIA']

2.2 用 matpolt 来可视化我们的病例数据:

2.2.1 没有肺炎的 20 个病例的 CT 图片:

multipleImages = glob('chest_xray/train/NORMAL/**')
i_ = 0
plt.rcParams['figure.figsize'] = (10.0, 10.0)
plt.subplots_adjust(wspace=0, hspace=0)
for l in multipleImages[:25]:
    im = cv2.imread(l)
    im = cv2.resize(im, (128, 128)) 
    plt.subplot(5, 5, i_+1) #.set_title(l)
    plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB)); plt.axis('off')
    i_ += 1

2.2.2 有肺炎的 20 个病例的 CT 图片:

multipleImages = glob('chest_xray/train/PNEUMONIA/**')
i_ = 0
plt.rcParams['figure.figsize'] = (10.0, 10.0)
plt.subplots_adjust(wspace=0, hspace=0)
for l in multipleImages[:25]:
    im = cv2.imread(l)
    im = cv2.resize(im, (128, 128)) 
    plt.subplot(5, 5, i_+1) #.set_title(l)
    plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB)); plt.axis('off')
    i_ += 1

第三步:数据预处理

3.1 首先先定义一些我们需要使用到的变量

# 图片尺寸
image_width = 226
image_height = 226

3.2 处理下图片的通道数在输入数据中的格式问题

if K.image_data_format() == 'channels_first':
    input_shape = (3, image_width, image_height)
else:
    input_shape = (image_width, image_height, 3)

3.3 数据加载和增强

这个案例,我们使用 Keras 的

ImageDataGenerator 来加载我们的数据,并且做数据增强跟处理。

ImageDataGenerator

是 keras.preprocessing.image 模块中的图片生成器,同时也可以在 batch 中对数据进行增强,扩充数据集大小,增强模型的泛化能力。比如进行旋转,变形,归一化等。

3.3.1 定义训练数据的 ImageDataGenerator

  • 训练数据的 ImageDataGenerator 我们做了如下几个处理:
  • 将像素值归一化 (rescale)
  • 剪切强度(逆时针方向的剪切变换角度),强度为 0.2
  • 随机缩放的幅度, 当前为 0.2
  • 水平翻转
train_data_gen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

3.3.2 定义测试数据的 ImageDataGenerator

测试数据我们只做了归一化处理

test_data_gen = ImageDataGenerator(rescale=1. / 255)

3.4 使用我们定义好的 ImageDataGenerator 从文件夹中读取数据, 其中 target_size 参数会把我们读入的原始数据缩放到我们想要的尺寸

3.4.1 训练数据读取

train_generator = train_data_gen.flow_from_directory(
    'chest_xray/train',
    target_size=(image_width, image_height),
    batch_size=16,
    class_mode='categorical')

Found 5216 images belonging to 2 classes.

3.4.2 验证数据读取

validation_generator = test_data_gen.flow_from_directory(
    'chest_xray/val',
    target_size=(image_width, image_height),
    batch_size=16,
    class_mode='categorical')

Found 16 images belonging to 2 classes.

3.4.3 测试数据读取

test_generator = test_data_gen.flow_from_directory(
    'chest_xray/test',
    target_size=(image_width, image_height),
    batch_size=16,
    class_mode='categorical')

Found 624 images belonging to 2 classes.

第四步:模型构建

4.1 定义我们的模型

我们的模型层次采用 VGG16 网络模型,

原模型链接:

https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3

4.1.1 VGG

VGG 是由 Simonyan 和 Zisserman 在文献《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷积神经网络模型,其名称来源于作者所在的牛津大学视觉几何组(Visual Geometry Group)的缩写。
该模型参加 2014 年的 ImageNet 图像分类与定位挑战赛,取得了优异成绩:在分类任务上排名第二,在定位任务上排名第一。

VGG 结构图:

4.1.2 VGG16

VGG 模型有一些变种,其中最受欢迎的当然是 VGG-16,这是一个拥有 16 层的模型。你可以看到它需要维度是 224x224x3 的输入数据。

VGG16 输入 224x224x3 的图片,经过的卷积核大小为 3x3x3,stride=1,padding=1,pooling 为采用 2x2 的 Max Pooling 方式:

  • 输入 224x224x3 的图片,经过 64 个卷积核的两次卷积后,采用一次 Max Pooling
  • 再经过两次 128 的卷积核卷积之后,采用一次 Max Pooling
  • 再经过三次 256 的卷积核的卷积之后,采用 Max Pooling
  • 重复两次三个 512 的卷积核卷积之后再 Max Pooling
  • 三次 FC

VGG 16 结构图

下面我们使用 Keras 建立 VGG 16 模型

model = Sequential()
model.add(ZeroPadding2D((1,1),input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3), activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(Flatten())
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

4.2 查看下模型概况

model.summary()

4.3 编译模型

我们使用 Adam 优化器,并且设置 learning rate 为 0.0001,对验证集的精确度添加 early stopping monitor,并且 patinece 设置成 3,这个参数的意思,当我们有 3 个连续的 epochs 没有提升精度,我们就停止训练,防止过拟合。

optimizer = Adam(lr = 0.0001)
early_stopping_monitor = EarlyStopping(patience = 3, monitor = "val_accuracy", mode="max", verbose = 2)
model.compile(loss="categorical_crossentropy", metrics=["accuracy"], optimizer=optimizer)

第五步:肺炎 CT 模型训练

5.1 训练模型

history = model.fit_generator(epochs=5, callbacks=[early_stopping_monitor], shuffle=True, 
                              validation_data=validation_generator, generator=train_generator, 
                              steps_per_epoch=500, validation_steps=10,verbose=2)

5.2 模型在训练过程中,训练数据集的精度和损失值会发生变化。

有次可见,我们的模型在训练的时候,精度不断提高,因此看到我们的模型在逐渐收敛到最佳的状态。

plt.plot(history.history['accuracy'])
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['train'], loc='upper left')
plt.show()
plt.plot(history.history['loss'])
plt.title('Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['train'], loc='best')
plt.show()

第六步: 模型在测试集数据上的使用

scores = model.evaluate_generator(test_generator)
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

具体的数据结果,欢迎各自进行尝试实验

当前 “新冠肺炎防控-肺炎 CT 检测” 案例镜像已经在矩池云 GPU 云共享平台正式上线。

感兴趣的小伙伴可以通过官网“机器租赁” — “我要租赁” — “选择镜像” — “Jupyter 教程 Demo”中尝试使用。

  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    66 引用 • 124 回帖
  • GPU
    9 引用 • 11 回帖
  • 新冠肺炎

    新型冠状病毒肺炎是一种急性感染性肺炎,其病原体是一种先前未在人类中发现的新型冠状病毒,即 2019 新型冠状病毒。2020 年 2 月 7 日,国家卫健委决定将“新型冠状病毒感染的肺炎”暂命名为“新型冠状病毒肺炎”,简称“新冠肺炎”。英文名称为“Novel Coronavirus Pneumonia”,简称“NCP”。2 月 11 日,世界卫生组织(WHO)将其命名为 2019 冠状病毒病,英文名称为 Corona Virus Disease 2019(COVID-19)。

    18 引用 • 110 回帖 • 1 关注
  • 矩池云
    21 引用 • 2 回帖
1 操作
matpool 在 2020-12-10 09:44:13 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...