数据集
我们所使用的数据集是胸部 X 光图像,它包含 2 个类别:肺炎和正常。该数据集由 Paulo Breviglieri 发布,是 Paul Mooney 最受欢迎数据集的修订版,此更新版本的数据集在验证集和测试集中的图像分布更加均衡。数据集分为 3 个文件夹(训练、测试、验证),包含肺炎和正常的子文件夹。
总数(图像):5,856例
训练观察:4,192(1,082 个正常病例,3,110 个肺部不透明病例)
验证观察:1,040(267 个正常病例,773 个肺部不透明病例)
测试观察:624(234 个正常病例,390 个肺部不透明病例)
首先,我们使用 Kaggle API 直接从 Kaggle 中提取数据集。为此,我们需要创建一个 API 令牌,该令牌位于 Kaggle API 选项卡下。单击“创建新 API 令牌”,将下载一个 json 文件,运行以下几行代码来安装所需的库并上传 json 文件。
! pip install -q kaggle
from google.colab import files
files.upload()
! mkdir ~/.kaggle
! cp kaggle.json ~/.kaggle/
! chmod 600 ~/.kaggle/kaggle.json
当提示“选择文件”时,上传下载好的 json 文件,运行下一行代码即可下载数据集。如果想获取数据集 API 命令来下载数据集,单击 Kaggle 数据集页面数据部分中的 3 个点,然后单击“复制 API 命令”。
! kaggle datasets download -d pcbreviglieri/pneumonia-xray-images
由于我使用 Google Colab 来运行此项目,因此数据集 zip 文件会下载到示例数据文件夹。现在,通过运行下一行代码,我们使用 zipfile 库将文件夹和文件解压缩到所需的目标文件夹。
import zipfile
zf = "/content/pneumonia-xray-images.zip"
target_dir = "/content/dataset/cnn/pneumonia_revamped"
zfile = zipfile.ZipFile(zf)
zfile.extractall(target_dir)
初始化
下载好的数据目录如下图所示:
content
└───dataset
└───cnn
└───pneumonia_revamped
├───test
│ ├───Normal
│ │ ├───image1.jpg
│ │ └───image2.jpg
│ └───Opacity
│ ├───image1.jpg
│ └───image2.jpg
├───train
│ ├───Normal
│ │ ├───image1.jpg
│ │ └───image2.jpg
│ └───Opacity
│ ├───image1.jpg
│ └───image2.jpg
└───val
├───Normal
│ ├───image1.jpg
│ └───image2.jpg
└───Opacity
├───image1.jpg
└───image2.jpg
在这部分代码中,我们定义目录路径,导入一些必要的库,并定义一些后面会用到的常用常量参数:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
train_path = '/content/dataset/cnn/pneumonia_revamped/train'
test_path = '/content/dataset/cnn/pneumonia_revamped/test'
valid_path = '/content/dataset/cnn/pneumonia_revamped/val'
#小图像更大的batch_size是理想选择
batch_size = 16
img_width = 500
准备数据
数据增强
图像增强通过创建现有训练集图像的修改版本来扩展数据集的大小,这有助于增加数据集的变化并最终提高模型预测新图像的能力。
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Create Image Data Generator for Train Set
image_gen = ImageDataGenerator(
rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
)
# Create Image Data Generator for Test/Validation Set
test_data_gen = ImageDataGenerator(rescale = 1./255)
使用 tensorflow.keras.preprocessing.image 库,对于训练集,我们创建了一个生成器,它将定义的参数随机应用于训练集;对于测试集和验证集,我们只需重新进行缩放。
如下方法,参考上述代码定义一些图像数据生成器参数:
rescale: 每个数字图像由一个值在 0 到 255 之间的像素创建。0 表示黑色,255 表示白色,因此,将原始图像像素值的比例数组重新缩放到 [0,1] 之间,这使图像对整体损失的贡献更均衡。否则,像素范围越高的图像损失越大,应使用较低的学习率,像素范围越低的图像需要更高的学习率。
shear_range : 固定一个轴并以一定的角度(称为剪切角度)拉伸图像
zoom_range : 图像放大小于 1.0,图像缩小1.0 倍以上
horizontal_flip : 随机水平翻转
vertical_flip : 随机垂直翻转
rotaion_range : 随机旋转一定角度,范围为 0 到 180
width_shift_range : 水平移动
height_shift_range:垂直移动
brightness_range : 亮度 0.0 对应完全没有亮度,1.0 对应最大亮度
fill_mode :将图像的缺失值填充为最接近的值
将这些转换技术随机应用于图像(除了缩放以外)。
另外请参考:
https://github.com/aleju/imgaug
https://github.com/Fafa-DL/Image-Augmentation
https://github.com/albumentations-team/albumentations
https://github.com/z-bingo/awesome-image-denoising-state-of-the-art
加载数据
图像数据生成器有一个称为“目录迭代器”的类,用于从包含图像的文件夹中读取图像,返回 DirectoryIterator 类型 tensorflow.python.keras.preprocessing.image.DirectoryIterator。
train = image_gen.flow_from_directory(
train_path,
target_size=(img_height, img_width),
color_mode='grayscale',
class_mode='binary',
batch_size=batch_size
)
test = test_data_gen.flow_from_directory(
test_path,
target_size=(img_height, img_width),
color_mode='grayscale',
shuffle=False, #注意这里的数据顺序
class_mode='binary',
batch_size=batch_size
)
valid = test_data_gen.flow_from_directory(
valid_path,
target_size=(img_height, img_width),
color_mode='grayscale',
class_mode='binary',
batch_size=batch_size
)
Found 4192 images belonging to 2 classes.
Found 624 images belonging to 2 classes.
Found 1040 images belonging to 2 classes.
一些参数定义如下:
directory:
使用的第一个参数是定义的训练、测试和验证文件夹的路径;
target_size : 目标大小是输入图像的大小,每个图像都将调整为此大小(500 x 500);
color_mode:
如果图像是黑白或灰度,则设置为“灰度”,或者图像有三个颜色通道设置为“rgb”。这里使用灰度,因为它是 X 射线图像;
batch_size:
生成器按批次生成的图像数量。我们之前将批次大小定义为 16。我们选择 16 是因为图像太大,RAM无法进行处理,如果你所使用的显卡是3090/4090 24G;
class_mode :
如果只有两个类别需要预测,则设置为“binary”,如果没有设置为“categorical”,如果是一个自动编码器系统,输入和输出都可能是相同的图像,这种情况下设置为“input”。我们这里将其设置binary;
数据增强后读取一些训练集看看:
plt.figure(figsize=(12, 12))
for i in range(0, 10):
plt.subplot(2, 5, i+1)
for X_batch, Y_batch