基于LeNet网络的细胞识别
作者:陈玥
背景
目前,全球疫情仍处于严峻时刻,许多计算机相关领域工作者也都参与到研究病毒、疫情等工作中。足量的高质量的COVID-19 图像数据集能用有效地帮助医院加快筛选和检测新冠肺炎,但由于隐私保护,目前难以获得足量的数据集。因可以先通过疟疾数据集训练细胞检测模型,后面可以利用迁移学习来训练COVID-19。本文使用深度学习框架Keras 在疟疾数据集上训练感染病毒检测器,可以根据细胞图像有效地识别出是否受到感染,是一篇使用深度学习框架Keras 进行疾病诊断的完整入门教程,也可以为日后新冠肺炎图像检测提供参考。
数据集
Malaria Datasets来自疟疾筛查研究活动的血液涂片图像存储库,收集了150 名受疟疾感染的患者和50 名健康人员的细胞涂片,数据具有真实性和应用价值。图像由医学研究人员手动标注,使得分类具有可靠性和专业性,数据集总共包含27,558 个细胞图像,包含感染细胞图像细胞和未被感染的图像集。
数据集下载地址:https://lhncbc.nlm.nih.gov/publication/pub9932
图像预处理
为了增加网络识别的图像数量,本次实验执行了数据增强操作。使用ImageDataGenerator
类的.flow_from_directory(directory)
的方法在训练期间,执行随机裁剪、缩放和旋转图像等变换,以便在每个时期,通过实时数据增强生成张量图像数据批次,数据将按批次不断循环,网络会看到同一图像的不同变化,提高实验的准确性,增强模型泛化能力。
官方文档:https://keras.io/zh/preprocessing/image/
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
validation_split=0.1)
train_generator = train_datagen.flow_from_directory(
path,target_size = (128, 128),
batch_size = BATCH_SIZE,
class_mode = 'categorical',
subset = 'training',seed = 0)
test_datagen = ImageDataGenerator(
rescale = 1./255,
validation_split = 0.1)
val_generator = test_datagen.flow_from_directory(
path,target_size = (128, 128),
batch_size = BATCH_SIZE,
class_mode = 'categorical',
subset='validation', seed=0)
CNN 模型
构建LeNet 网络
应用深度学习做图像分类通常会采用卷积神经网络CNN ,但在实验之前也很难确定哪一类CNN 网络会在自己的分类任务表现最好,因此这里搭建的是最经典的LeNet 网络,首先观察一下分类效果。图1 描述了LeNet 的网络结构,其包含了卷积层、池化层和全连接层
图1 LeNet网络
model = Sequential()
# 输入层
model.add(Conv2D(8, kernel_size=(3, 3),
padding="same",
input_shape=input_shape,
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# 隐藏层
model.add(Conv2D(16, kernel_size=(3, 3),
padding="same",
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# 展平
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dropout(0.5)) # 添加丢弃层
model.add(Dense(units=2, activation='softmax'))
网络的搭建从输入->卷积->池化->卷积->池化->卷积->池化->Dense(relu)>Dense(softmax),其中Con2D 表示执行卷积操作,MaxPooling2D 是最大池化,展平层Flatten 将输入“展开”为一层,用于卷积层到全连接层的过渡,Dense 表示全连接层,添加丢弃层Dropout 防止过拟合。
模型编译
这个实验室是二分类问题,因此选择 binary_crossentrop
作为损失函数,若是多类别分类问题,损失函数可以选择 categorical_crossentropy
,Adagrad
为优化器。
model.compile(loss=keras.losses.binary_crossentropy,
optimizer=keras.optimizers.Adagrad(),
metrics=['accuracy'])
模型训练
_history = model.fit_generator(
train_generator,
validation_data=val_generator,
steps_per_epoch=2750//BATCH_SIZE,
validation_steps=200//BATCH_SIZE,
epochs = EPOCHS)
可视化训练结果
模型训练过程中的数据会存放在_history
中,为了更好地观察迭代过程,将其可视化输出。
N = EPOCHS
plt.style.use("ggplot")#matplotlib的美化样式
plt.figure()
plt.plot(np.arange(0,N),_history.history["loss"],label ="train_loss")
plt.plot(np.arange(0,N),_history.history["val_loss"],label="val_loss")
plt.plot(np.arange(0,N),_history.history["accuracy"],label="train_acc")
plt.plot(np.arange(0,N),_history.history['val_accuracy'],label="val_acc")
plt.title("loss and accuracy")
plt.xlabel("epoch")
plt.ylabel("loss/acc")
plt.legend(loc="best")
plt.savefig("./results/result.png")
plt.show()
图2 损失和精度曲线
从图中的训练结果可以看到,随着迭数的增加,准确率逐渐增加,当迭代次数超过15次后,趋向于稳定,证明模型的收敛性良好,在验证集上的精度可以达到90%以上,且与训练集精度差别不大,说明分类效果良好,模型的泛化能力不错。
val_loss曲线震荡不平滑的原因可能是因为Batch_size太小或样本分布不均匀等其他原因,至于val_loss比train_loss小的原因很可能是样本数量不足够或者是random variables,若想模型要达到更好的效果,还要下功夫在超参的设置上。
分类结果
图3 分类结果(部分)
图3的分类结果,pred是预测的分类,truth是图像实际的分类,整体来看,对于一个简单的CNN网络来看,分类效果还是不错的。
总结与展望
在本实验中,使用了CNN经典网络LeNet网络结构,为细胞分类检测提供了一套完整的处理过程,可以用作其他类别图像分类的通用框架。若未来要将模型运用到COVID-19检测中并将探测器部署在实地中,可以采用迁移学习的方法将模型应用到其他数据集上去。
项目地址:https://momodel.cn/explore/5ef8135a2d3fa37593d47b3b?blob=master%252Fcoding_here.ipynb&type=app