矩池雲 | 新冠肺炎防控:肺炎CT檢測

連日來,新型冠狀病毒感染的肺炎疫情,牽動的不單單是全武漢、全湖北,更是全國人民的心,你們紛紛以本身獨特的方式爲武漢加油!咱們相信堅持下去,終會春暖花開。git

今天讓咱們以簡單實用的神經網絡模型,來檢測肺炎的CT影像。github

第一步:導入咱們須要的庫

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);session

每一個訓練數據,測試數據,驗證數據的文件夾中咱們又分紅了正常的病例數據(normal), 肺炎病例數據(pneumonia)。ide

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']lua

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

print("測試病例數據")
print(os.listdir("chest_xray"))
print(os.listdir("chest_xray/test"))
print(os.listdir("chest_xray/test/"))

測試病例數據3d

['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」中嘗試使用。

相關文章
相關標籤/搜索