肺炎是一種由感染引起的嚴(yán)重呼吸道疾病,特別是在高危人群中,可能會(huì)出現(xiàn)危及生命的并發(fā)癥。必須盡快診斷和治療肺炎,以最大限度地提高患者康復(fù)的機(jī)會(huì)。
診斷過(guò)程并不容易,需要一些醫(yī)學(xué)實(shí)驗(yàn)室工具和先進(jìn)的醫(yī)療技能,但我們可以使用深度學(xué)習(xí)和計(jì)算機(jī)視覺(jué)來(lái)構(gòu)建一個(gè)快速簡(jiǎn)便的工具,幫助醫(yī)生檢測(cè)肺炎。
我們可以使用稱(chēng)為OpenCV(https://opencv.org/)(開(kāi)源計(jì)算機(jī)視覺(jué))的開(kāi)源計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)軟件庫(kù)創(chuàng)建用于圖像和視頻分析的應(yīng)用程序,例如 X 射線結(jié)果。Open CV 是一個(gè)用于執(zhí)行計(jì)算機(jī)視覺(jué)、機(jī)器學(xué)習(xí)和圖像處理的開(kāi)源庫(kù)。
在本課中,我們將了解如何使用 OpenCV 識(shí)別胸部 X 光圖像中的肺炎。
安裝 OpenCV
安裝 OpenCV 是初始階段。根據(jù)你的操作系統(tǒng),有多種安裝 OpenCV 的方法。以下是一些受歡迎的選擇:
Windows:在OpenCV (https://opencv.org/releases/) 主網(wǎng)站上使用預(yù)構(gòu)建的二進(jìn)制文件。
Linux:可以使用 Linux 發(fā)行版中包含的包管理器安裝 OpenCV。在終端中運(yùn)行以下指令,例如,在 Ubuntu 上:
Install libopencv-dev with sudo apt-get
Mac OS:可以使用 Homebrew 設(shè)置 OpenCV,應(yīng)在終端中輸入以下代碼。
Brew install opencv
加載 OpenCV 后,你可以使用以下 Python 代碼檢查它是否正常工作。
import cv2
print(cv2.__version__)
如果正確安裝了 OpenCV,你應(yīng)該會(huì)在終端中看到版本號(hào)。
下載數(shù)據(jù)集
接下來(lái)可以下載將用于訓(xùn)練我們的肺炎檢測(cè)算法的數(shù)據(jù)集。在本練習(xí)中,我們將使用來(lái)自 Kaggle 的胸部 X 光圖片(肺炎)數(shù)據(jù)集。
數(shù)據(jù)集:https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia
數(shù)據(jù)集中共有 5,856 張胸部 X 光圖像,分為肺炎和正常兩類(lèi)。
你必須注冊(cè) Kaggle 帳戶(hù)并同意數(shù)據(jù)集的條款才能獲取數(shù)據(jù)集。完成后,在終端中鍵入以下命令以獲取數(shù)據(jù)集:
kaggle datasets download -d paultimothymooney/chest-xray-pneumonia
將下載包含信息的 ZIP 文件。在你的本地計(jì)算機(jī)上創(chuàng)建一個(gè)子文件夾并提取 ZIP 文件。
準(zhǔn)備數(shù)據(jù)
然后必須為我們的肺炎識(shí)別模型的訓(xùn)練準(zhǔn)備數(shù)據(jù)。為了從當(dāng)前樣本中創(chuàng)建更多訓(xùn)練樣本,我們將采用一種稱(chēng)為數(shù)據(jù)增強(qiáng)的方法。
這樣做是為了提高模型的性能并更快地構(gòu)建模型。為了創(chuàng)建同一圖片的不同版本,數(shù)據(jù)增強(qiáng)涉及對(duì)圖像應(yīng)用隨機(jī)變換,例如旋轉(zhuǎn)、縮放和翻轉(zhuǎn)。
我們將制作兩個(gè)目錄來(lái)準(zhǔn)備數(shù)據(jù):一個(gè)用于訓(xùn)練圖片,一個(gè)用于驗(yàn)證圖像。80%的圖片將用于訓(xùn)練,20%用于驗(yàn)證。
這是準(zhǔn)備信息的代碼:
import os
import shutil
import random
# Define the paths
input_dir = 'path/to/input/dir'
train_dir = 'path/to/train/dir'
val_dir = 'path/to/val/dir'
# Create the directories
os.makedirs(train_dir, exist_ok=True)
os.makedirs(val_dir, exist_ok=True)
# Get the list of images
image_paths = []
for root, dirs, files in os.walk(input_dir):
for file in files:
if file.endswith('.jpeg'):
image_paths.append(os.path.join(root, file))
# Shuffle the images
random.shuffle(image_paths)
# Split
split_idx = int(0.8 * len(image_paths))
train_image_paths = image_paths[:split_idx]
val_image_paths = image_paths[split_idx:]
現(xiàn)在將圖像復(fù)制到目錄中。將“path/to/input/dir”更改為你在此代碼中提取信息的目錄路徑。要分別保存訓(xùn)練和驗(yàn)證圖像的目錄的路徑應(yīng)替換為“path/to/train/dir”和“path/to/val/dir”。
努力跟蹤和重現(xiàn)復(fù)雜的實(shí)驗(yàn)參數(shù)?工件是 Comet 工具箱中幫助簡(jiǎn)化模型管理的眾多工具之一。
閱讀我們的 PetCam 場(chǎng)景以了解更多信息:https://www.comet.com/site/blog/debugging-your-machine-learning-models-with-comet-artifacts/?utm_source=heartbeat&utm_medium=referral&utm_campaign=AMS_US_EN_AWA_heartbeat_CTA
訓(xùn)練模型
使用我們?cè)谇耙浑A段創(chuàng)建的訓(xùn)練圖像,我們現(xiàn)在必須訓(xùn)練肺炎檢測(cè)模型。我們模型的核心將是一個(gè)名為 VGG16 的預(yù)訓(xùn)練卷積神經(jīng)網(wǎng)絡(luò) (CNN) 。
流行的 CNN 架構(gòu) VGG16 在經(jīng)過(guò)大量圖像數(shù)據(jù)集的訓(xùn)練后,在眾多圖像識(shí)別任務(wù)上取得了最先進(jìn)的成功。
下面是訓(xùn)練模型的代碼:
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.applications import VGG16
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Define the input shape of the images
input_shape = (224, 224, 3)
# Load the VGG16 model
base_model = VGG16(weights='imagenet', include_top=False, input_shape=input_shape)
# Add a global average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# Add a fully connected layer
x = Dense(128, activation='relu')(x)
# Add the output layer
output = Dense(1, activation='sigmoid')(x)
# Define the model
model = Model(inputs=base_model.input, outputs=output)
# Freeze the layers of the VGG16 model
for layer in base_model.layers:
layer.trainable = False
# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Define the data generators for training and validation
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range=10,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.1,
zoom_range=0.1,
horizontal_flip=True,
fill_mode='nearest')
val_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir,
target_size=input_shape[:2],
batch_size=32,
class_mode='binary')
val_generator = val_datagen.flow_from_directory(val_dir,
target_size=input_shape[:2],
batch_size=32,
class_mode='binary')
# Train the model
model.fit(train_generator,
steps_per_epoch=len(train_generator),
epochs=10,
validation_data=val_generator,
validation_steps=len(val_generator))
首先,我們將 ImageNet 數(shù)據(jù)集中的預(yù)訓(xùn)練權(quán)重加載到 VGG16 模型中。我們還包括一個(gè)具有 sigmoid 激活函數(shù)的輸出層、一個(gè)具有 128 個(gè)神經(jīng)元的完全連接層和一個(gè)全局平均池化層。VGG16 模型的層被凍結(jié),使用 Adam 算法和二元交叉熵?fù)p失來(lái)構(gòu)建模型。之后,我們指定用于訓(xùn)練和驗(yàn)證的數(shù)據(jù)生成器,以擴(kuò)充數(shù)據(jù)并將像素值重新縮放到 [0, 1] 范圍。
使用擬合方法以及訓(xùn)練和驗(yàn)證數(shù)據(jù)生成器,我們訓(xùn)練模型 10 個(gè)時(shí)期。
評(píng)估模型
為了確定模型在訓(xùn)練后對(duì)新數(shù)據(jù)的泛化能力如何,我們必須評(píng)估其在測(cè)試集上的表現(xiàn)。為了評(píng)估模型,我們將使用數(shù)據(jù)集的測(cè)試集。此外,我們將顯示一些正確和錯(cuò)誤分類(lèi)圖像的插圖。
使用下面的代碼評(píng)估模型并顯示一些實(shí)例。
import numpy as np
import matplotlib.pyplot as plt
# Define the path to the test directory
test_dir = 'path/to/input/dir/chest_xray/test'
# Define the data generator for test
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(test_dir,
target_size=input_shape[:2],
batch_size=32,
class_mode='binary',
shuffle=False)
# Evaluate the model on the test set
loss, accuracy = model.evaluate(test_generator, steps=len(test_generator))
print(f'Test accuracy: {accuracy:.2f}')
# Get the predictions and true labels
predictions = model.predict(test_generator, steps=len(test_generator))
predictions = np.squeeze(predictions)
true_labels = test_generator.labels
# Get the image filenames
filenames = test_generator.filenames
# Find the indices of the correctly and incorrectly classified images
correct_indices = np.where((predictions >= 0.5) == true_labels)[0]
incorrect_indices = np.where((predictions >= 0.5) != true_labels)[0]
# Plot some correctly classified images
plt.figure(figsize=(10, 10))
for i, idx in enumerate(correct_indices[:9]):
plt.subplot(3, 3, i+1)
img = plt.imread(os.path.join(test_dir, filenames[idx]))
plt.imshow(img, cmap='gray')
plt.title('PNEUMONIA' if predictions[idx] >= 0.5 else 'NORMAL')
plt.axis('off')
# Plot some incorrectly classified images
plt.figure(figsize=(10, 10))
for i, idx in enumerate(incorrect_indices[:9]):
plt.subplot(3, 3, i+1)
img = plt.imread(os.path.join(test_dir, filenames[idx]))
plt.imshow(img, cmap='gray')
plt.title('PNEUMONIA' if predictions[idx] >= 0.5 else 'NORMAL')
plt.axis('off')
plt.show()
在這段代碼中,我們創(chuàng)建了一個(gè)測(cè)試和評(píng)估集數(shù)據(jù)生成器來(lái)評(píng)估模型。我們還獲得了測(cè)試集的預(yù)測(cè)和真實(shí)標(biāo)簽,并找到了正確和錯(cuò)誤分類(lèi)圖像的索引。然后,使用 Matplotlib,我們繪制了一些正確和錯(cuò)誤分類(lèi)圖像的實(shí)例。
結(jié)論
在本教程中,我們使用 OpenCV 和 TensorFlow 構(gòu)建了一個(gè)肺炎檢測(cè)模型。我們使用 OpenCV 讀取、處理和可視化圖像,并使用 TensorFlow 訓(xùn)練和測(cè)試模型。該模型成功地以高精度對(duì)大多數(shù)測(cè)試集的圖像進(jìn)行了分類(lèi)。