在这篇文章中,将介绍如何使用Python的TensorFlow库在Jupyter Notebook中从头开始构建并训练一个神经网络,用于诊断胸部X光图像中的COVID-19。将使用TensorFlow 2.0、Keras、NumPy、Matplotlib和CV2等库。假设已经熟悉使用Python进行深度学习以及Jupyter Notebook。如果是Python新手,可以从相关教程开始学习。
将仅使用TensorFlow、Keras和OS,以及一些基本的附加库来构建网络,用于诊断COVID-19。首先,让加载将用于训练和测试网络的数据。在这种情况下,将使用与之前用于基于迁移学习的网络不同的加载技术。尽管如此,仍然使用相同的数据集。
import tensorflow as tf
from keras import optimizers
import os, shutil
import matplotlib.pyplot as plt
接下来,将设置数据集的路径,并计算训练和测试集中COVID-19和正常图像的数量。
base_dir = r'C:\Users\abdul\Desktop\ContentLab\P1\archive\COVID-19 Radiography Database'
train_dir = os.path.join(base_dir, 'train')
test_dir = os.path.join(base_dir, 'test')
train_COV19_dir = os.path.join(train_dir, 'COV19')
train_Normal_dir = os.path.join(train_dir, 'Normal')
test_VOV19_dir = os.path.join(test_dir, 'COV19')
test_Normal_dir = os.path.join(test_dir, 'Normal')
print('total training COV19 images:', len(os.listdir(train_COV19_dir)))
print('total training Normal images:', len(os.listdir(train_Normal_dir)))
print('total test COV19 images:', len(os.listdir(test_VOV19_dir)))
print('total test Normal images:', len(os.listdir(test_Normal_dir)))
在将数据输入网络之前,必须对图像进行预处理。对于即将构建的网络,将选择128x128x3的输入格式。所有图像都将被重新缩放到这个相对较小的大小,这将减少计算成本。现在需要设置批量大小和类别模式,以便ImageDataGenerator使用。
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir, target_size=(128, 128), batch_size=5, class_mode='categorical')
test_generator = test_datagen.flow_from_directory(test_dir, target_size=(128, 128), batch_size=5, class_mode='categorical')
为了检查数据和标签批量的形状,将使用以下代码:
for data_batch, labels_batch in train_generator:
print('data batch shape:', data_batch.shape)
print('labels batch shape:', labels_batch.shape)
break
请注意,顺序模型期望输入是4维的(批量大小,X,Y,通道)。这就是为什么在构建网络之前需要设置批量大小的原因;否则,会出现错误。
Keras模型使用Sequential类来创建层。这是一个功能模型类,代表一层的堆叠。它可以轻松地从Keras导入。对于模型,将使用两层卷积,两层最大池化,三个ReLU,一个Flatten和两个Dense层(全连接)。需要从Keras模型导入所有所需的层,如Conv2D、MaxPooling和Dense。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras import backend as k
input_shape = (128, 128, 3)
model = Sequential()
model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(2, activation='softmax'))
model.summary()
如上所见,卷积层是通过Conv2D函数调用的,它有三个主要参数:Filters(设置卷积层生成的滤波器数量)、Kernel size(卷积中使用的滤波器或核的大小,必须是奇数)和Strides(定义卷积将如何沿输入图像的X和Y轴进行的2元组整数)。池化层还定义了stride(遍历所有图像)和pool_size(应用于输入图像的池化滤波器或核的大小)。
最后,可以可视化网络:
model.summary()
为了训练新构建的网络,需要指定损失函数和优化器。对于这个网络,将使用二元交叉熵,因为目标是将胸部X光图像分类为Covid-19和正常两类。将使用随机梯度下降作为优化器。在优化函数中,需要设置学习率。这是一个重要参数。如果设置得太低,学习过程可能会更长,因为权重将遇到小的更新。相反,如果设置得太高,网络可能会过拟合。最好在开始训练网络时设置一个低的学习率值,然后在监控网络性能的同时逐渐增加它。在这里,选择学习率为0.001。
from keras import optimizers
model.compile(loss='categorical_crossentropy', optimizer=optimizers.adam(lr=1e-4), metrics=['acc'])
然后,可以开始训练,训练10个周期:
history = model.fit_generator(train_generator, steps_per_epoch=100, epochs=10)
训练过程中的网络准确性和损失随后可以使用以下代码绘制:
acc = history.history['acc']
loss = history.history['loss']
plt.figure()
plt.plot(acc, label='Training Accuracy')
plt.ylabel('Accuracy')
plt.title('Training Accuracy')
plt.figure()
plt.plot(loss, label='Training Loss')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.xlabel('epoch')
plt.show()
如前一篇文章中讨论的,模型可以在新的、未见过的COVID-19和正常类别的图像上测试准确性。在本节中,网络在895张COVID-19和正常胸部X光图像上进行了测试。使用了与之前预训练网络测试相同的测试命令"model.evaluate"。如图13所示,网络在测试中达到了98.8%的准确性。
Testresults = model.evaluate(test_generator)
print("test loss, test acc:", Testresults)