这是我的第275篇原创文章。
一、引言
基于CNN卷积神经网络在图像识别领域的应用:猫狗图像识别。主要内容包含:
-
数据创建和预处理
-
神经网络模型搭建
-
神经网络模型的训练和拟合
文中使用的深度学习框架是Keras。部分数据展示:
猫:
狗:
二、实现过程
2.1 数据预处理
# 数据预处理
train_datagen = ImageDataGenerator(rescale=1./255) # 进行缩放
test_datagen = ImageDataGenerator(rescale=1./255) # 进行缩放
train_generator = train_datagen.flow_from_directory(
train_dir, # 待处理的目录
target_size=(150,150), # 图像大小设置
batch_size=20,
class_mode="binary" # 损失函数是binary_crossentropy 所以使用二进制标签
)
validation_generator = test_datagen.flow_from_directory(
validation_dir, # 待处理的目录
target_size=(150,150), # 图像大小设置
batch_size=20,
class_mode="binary" # 损失函数是binary_crossentropy 所以使用二进制标签
)
for data_batch, labels_batch in train_generator:
print(data_batch.shape)
print(labels_batch.shape)
break
数据输入到神经网络之前必须先转成浮点数张量。ImageDataGenerator类,可以快速创建Python生成器,将图形文件处理成张量批量,生成器的输出是150-150的RGB图像和二进制标签,形状为(20,)组成的批量。生成器会不断地生成这些批量,不断地循环目标文件夹中的图像。
2.2 模型构建
# 构建模型
model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation="relu",
input_shape=(150,150,3)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2))) #
model.add(layers.Flatten())
model.add(layers.Dense(512, activation="relu"))
model.add(layers.Dense(1, activation="sigmoid"))
model.summary()
model.compile(loss="binary_crossentropy",
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=["acc"])
模型结构:
2.3 模型拟合
history = model.fit_generator(
train_generator, # 第一个参数必须是Python生成器
steps_per_epoch=100, # 2000 / 20
epochs=30, # 迭代次数
validation_data=validation_generator, # 待验证的数据集
validation_steps=50
)
model.save("cats_and_dogs_small.h5")
keras模型使用fit_generator方法来拟合生成器的效果。模型有个参数steps_per_epoch参数:从生成器中抽取steps_per_epoch个批量后,拟合进入下一轮。模型文件:
2.4 模型评价
# 绘制训练过程中的损失和准确率
history_dict = history.history # 字典形式
acc = history_dict["acc"]
val_acc = history_dict["val_acc"]
loss = history_dict["loss"]
val_loss = history_dict["val_loss"]
epochs = range(1, len(acc)+1)
# acc
plt.plot(epochs, acc, "bo", label="Training acc")
plt.plot(epochs, val_acc, "b", label="Validation acc")
plt.title("Training and Validation acc")
plt.legend()
plt.show()
# loss
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and Validation loss")
plt.legend()
plt.show()
acc曲线:
loss曲线:
三、小结
得到过拟合的结论:
-
随着时间的增加,训练精度在不断增加,接近100%,而验证精度则停留在70%
-
验证的损失差不多在第6轮后达到最小值,后面一定轮数内保持不变,训练的损失一直下降,直接接近0
作者简介:
读研期间发表6篇SCI数据挖掘相关论文,现在某研究院从事数据算法相关科研工作,结合自身科研实践经历不定期分享关于Python、机器学习、深度学习、人工智能系列基础知识与应用案例。致力于只做原创,以最简单的方式理解和学习,关注我一起交流成长。需要数据集和源码的小伙伴可以关注底部公众号添加作者微信。