放射学是一个高度依赖高技能专业人员专业知识的领域。放射科医生分析医学图像来诊断和监测一系列病症,从简单的骨折到癌症等复杂疾病。然而,随着医学成像的激增以及对快速、准确诊断的迫切需求,放射科医生面临着巨大的压力。这就是人工智能 (AI) 介入的地方,它通过增强人类的能力来改变这个领域。在本文结束时,您将制作自己的图像分类器模型来帮助检测医学图像中的肺炎。
在开始编码之前,我们需要确保环境已准备就绪。我们首先安装必要的库:
%pip install --upgrade tensorflow keras numpy pandas sklearn pillow
这些库对于构建和训练我们的模型至关重要:
tensorflow
和keras
用于创建和训练神经网络。numpy
用于数值运算。pandas
进行数据操作。sklearn
用于预处理数据。pillow
。安装库后,让我们导入它们:
import os from tensorflow import keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Flatten from tensorflow.keras.preprocessing.image import ImageDataGenerator import numpy as np
我们首先导入构建和训练用于图像处理任务的神经网络模型所需的几个基本库和模块。我们将使用 TensorFlow 及其子模块来创建和管理我们的深度学习模型。具体来说,我们将导入 Keras 作为我们的高级 API,导入 Sequential 来构建线性层堆栈,导入 Dense、Conv2D、MaxPool2D 和 Flatten 等模块来构建和配置各种神经网络层。此外,ImageDataGenerator 将帮助我们扩充图像数据,增强模型的泛化能力。最后,我们将导入 numpy 以获得其数值运算支持,这对于处理数组和执行数学函数特别有用。
我们的 AI 放射科医生需要数据来学习。我们将使用 ImageDataGenerator 来加载和扩充我们的训练和验证数据:要下载数据,我们将使用我们的开源数据朋友 Kaggle,从此处的链接下载标记的数据集。
在监督学习的背景下,标记的数据集将成为机器学习模型应该预测的基本事实。
trdata = ImageDataGenerator() traindata = trdata.flow_from_directory(directory="data-task1/train", target_size=(224, 224)) tsdata = ImageDataGenerator() testdata = tsdata.flow_from_directory(directory="data-task1/val", target_size=(224, 224))
此代码片段为我们的训练和验证数据集设置了数据生成器。图像大小调整为 224x224 像素,这是 VGG16 模型的标准输入大小。
现在到了最有趣的部分:构建 VGG16 模型。VGG16 是一种流行的卷积神经网络 (CNN) 架构,以其简单性和有效性而闻名,这要归功于其独特的架构,主要建立在 13 个卷积层和 3 个完全连接层上。VGG16 的与众不同之处在于它在深度网络中使用了小型 3x3 卷积滤波器。这种设计可以捕捉图像中的复杂图案,同时确保计算效率。以下是我们的创建方法:
model = Sequential() model.add(Conv2D(input_shape=(224,224,3), filters=64, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=64, kernel_size=(3,3), padding="same", activation="relu")) model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu")) model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu")) model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu")) model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu")) model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu")) model.add(MaxPool2D(pool_size=(2,2), strides=(2,2))) model.add(Flatten()) model.add(Dense(units=4096, activation="relu")) model.add(Dense(units=4096, activation="relu")) model.add(Dense(units=2, activation="softmax")) model.summary()
让我们分解一下:
定义了模型架构后,我们需要对其进行编译:
opt = keras.optimizers.Adam(learning_rate=0.001) model.compile(optimizer=opt, loss=keras.losses.binary_crossentropy, metrics=['accuracy'])
在这里,我们使用学习率为 0.001 的 Adam 优化器和二元交叉熵作为我们的损失函数,适用于二元分类任务。让我们分析一下这些选择的优缺点:
成分 | 优点 | 缺点 |
---|---|---|
Adam 优化器 | 1. 自适应学习率 2. 与默认设置配合良好。 | 复杂模型可能存在过度拟合。 |
二元交叉熵损失 | 非常适合二元分类 | 与我的输出层激活函数不太兼容,为什么?(留在评论中!) |
请随意尝试不同的优化器、学习率和损失函数,因为这是获得经验的好方法。
是时候训练我们的 AI 放射科医生了!我们设置了回调来保存最佳模型,如果验证准确率停止提高,则提前停止:
from keras.callbacks import ModelCheckpoint, EarlyStopping checkpoint = ModelCheckpoint("vgg16_1.h5", monitor='val_accuracy', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1) early = EarlyStopping(monitor='val_accuracy', min_delta=0, patience=20, verbose=1, mode='auto') hist = model.fit_generator(steps_per_epoch=20, generator=traindata, validation_data=testdata, validation_steps=10, epochs=10, callbacks=[checkpoint, early])
为了了解我们的模型的运行情况,我们可以绘制训练和验证损失和准确率:
import matplotlib.pyplot as plt # Training loss plt.plot(hist.history['loss']) plt.legend(['Training']) plt.title('Training loss') plt.ylabel('loss') plt.xlabel('epoch') plt.show() # Validation loss plt.plot(hist.history['val_loss']) plt.legend(['Validation']) plt.title('Validation loss') plt.ylabel('validation loss') plt.xlabel('epoch') plt.show() # Training and validation accuracy plt.plot(hist.history['accuracy']) plt.plot(hist.history['val_accuracy']) plt.legend(['Training', 'Validation']) plt.title('Training & Validation accuracy') plt.xlabel('epoch') plt.show()
这些图将帮助我们了解模型的学习效果以及是否过度拟合或欠拟合。
经过训练后,我们的 AI 放射科医生就可以进行预测了。以下是加载图像并获取模型预测的方法:
from tensorflow.keras.preprocessing import image # Load and preprocess image img_path = 'path_to_your_image.jpg' img = image.load_img(img_path, target_size=(224, 224)) img_array = image.img_to_array(img) img_array = np.expand_dims(img_array, axis=0) # Create batch axis # Make prediction prediction = model.predict(img_array) print('Prediction:', prediction)
打造 AI 放射科医生只是开始。以下是一些微调和改进模型的技巧:
哇,太棒了!🎉 您创建了一个可以分析医学图像并做出预测的模型 — 这是一项伟大的医学成就! :) 通过深入研究神经网络架构的复杂性,您已经看到了经过精细调整的 AI 模型的影响力。继续突破界限,继续尝试,最重要的是,享受与您的 AI 项目合作的每一刻!