猫狗图像分类模型训练与评估 - 使用 TensorFlow 和 Keras
# 导入所需的库和模块
import os # 对文件和目录进行操作
import numpy as np # 处理数组和矩阵
import matplotlib.pyplot as plt # 绘图库
import tensorflow as tf # 深度学习框架
from tensorflow import keras # TensorFlow中的高级API
from tensorflow.keras import layers # TensorFlow中的各种层
# 定义训练集和测试集路径
train_dir = 'C:/Users/28938/Desktop/image/image/train'
test_dir = 'C:/Users/28938/Desktop/image/image/test'
# 定义类别标签
class_names = ['cats', 'dogs']
# 定义图像尺寸和批次大小
img_height = 224
img_width = 224
batch_size = 32
# 从目录中读取训练集和测试集
train_ds = keras.preprocessing.image_dataset_from_directory(
train_dir,
validation_split=0.2, # 划分验证集的比例
subset='training', # 使用训练集的一部分作为训练集
seed=42, # 随机种子,保证每次运行时划分的数据集相同
image_size=(img_height, img_width), # 设置图像的大小
batch_size=batch_size # 设置批次大小
)
val_ds = keras.preprocessing.image_dataset_from_directory(
train_dir,
validation_split=0.2, # 划分验证集的比例
subset='validation', # 使用训练集的一部分作为验证集
seed=42, # 随机种子,保证每次运行时划分的数据集相同
image_size=(img_height, img_width), # 设置图像的大小
batch_size=batch_size # 设置批次大小
)
test_ds = keras.preprocessing.image_dataset_from_directory(
test_dir,
seed=42, # 随机种子,保证每次运行时划分的数据集相同
image_size=(img_height, img_width), # 设置图像的大小
batch_size=batch_size # 设置批次大小
)
# 定义数据增强器
data_augmentation = keras.Sequential(
[
layers.experimental.preprocessing.RandomFlip('horizontal', input_shape=(img_height, img_width, 3)), # 随机水平翻转
layers.experimental.preprocessing.RandomRotation(0.1), # 随机旋转
layers.experimental.preprocessing.RandomZoom(0.1), # 随机缩放
layers.experimental.preprocessing.RandomCrop(img_height, img_width), # 随机裁剪
layers.experimental.preprocessing.Rescaling(1./255), # 像素值缩放到[0,1]之间
layers.experimental.preprocessing.RandomContrast(0.1), # 随机对比度
layers.experimental.preprocessing.RandomSaturation(0.1), # 随机饱和度
]
)
# 定义模型输入
input_shape = (img_height, img_width, 3)
model = keras.Sequential([
data_augmentation, # 数据增强
layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape), # 卷积层
layers.MaxPooling2D(pool_size=(2, 2)), # 最大池化层
layers.Dropout(0.2), # Dropout层,防止过拟合
layers.Conv2D(64, (3, 3), activation='relu'), # 卷积层
layers.MaxPooling2D(pool_size=(2, 2)), # 最大池化层
layers.Dropout(0.2), # Dropout层,防止过拟合
layers.Conv2D(128, (3, 3), activation='relu'), # 卷积层
layers.MaxPooling2D(pool_size=(2, 2)), # 最大池化层
layers.Dropout(0.2), # Dropout层,防止过拟合
layers.Flatten(), # 展平层,将多维输入一维化
layers.Dense(128, activation='relu'), # 全连接层
layers.Dense(len(class_names), activation='softmax') # 输出层,使用softmax激活函数进行多分类
])
# 编译模型
model.compile(optimizer='adam', # 优化器,使用Adam算法
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), # 损失函数,使用交叉熵损失
metrics=['accuracy']) # 评估指标,使用准确率
# 设定训练参数
epochs = 30 # 训练迭代次数
# 定义模型checkpoint
checkpoint_path = 'model_checkpoint/cp.ckpt' # 模型权重保存路径
checkpoint_dir = os.path.dirname(checkpoint_path) # 模型权重保存目录
checkpoint = tf.keras.callbacks.ModelCheckpoint(checkpoint_path, # 模型保存路径
save_weights_only=True, # 只保存权重
save_best_only=True, # 只保存最好的模型
monitor='val_accuracy', # 监控指标为验证集准确率
mode='max', # 监控模式为最大值
verbose=1) # 显示保存信息
# 定义学习率衰减策略
lr_decay = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', # 监控指标为验证集损失
factor=0.1, # 学习率衰减因子
patience=5, # 没有改善时的停止轮数
verbose=1, # 显示学习率衰减信息
mode='auto', # 模式自动选择
min_delta=0.0001, # 最小变化量
cooldown=0, # 冷却时间
min_lr=0) # 最小学习率
# 开始训练模型
history = model.fit(train_ds, # 训练集
validation_data=val_ds, # 验证集
epochs=epochs, # 训练迭代次数
callbacks=[checkpoint, lr_decay]) # 回调函数
# 加载最佳模型权重
model.load_weights(checkpoint_path)
# 对模型进行评估
test_loss, test_acc = model.evaluate(test_ds) # 使用测试集评估模型
print('Test accuracy:', test_acc)
# 对模型进行预测
predictions = model.predict(test_ds) # 使用测试集进行预测
# 混淆矩阵和分类报告
from sklearn.metrics import confusion_matrix, classification_report # 导入混淆矩阵和分类报告函数
# 获取测试集真实标签
test_labels = []
for images, labels in test_ds:
test_labels.append(labels.numpy())
test_labels = np.concatenate(test_labels)
# 获取预测标签
predicted_labels = np.argmax(predictions, axis=1)
# 计算混淆矩阵和分类报告
cm = confusion_matrix(test_labels, predicted_labels) # 计算混淆矩阵
report = classification_report(test_labels, predicted_labels, target_names=class_names) # 计算分类报告
# 打印混淆矩阵和分类报告
print('Confusion Matrix:')
print(cm)
print('
Classification Report:')
print(report)
# 绘制模型准确度和损失随时间变化的曲线
acc = history.history['accuracy'] # 获取训练集准确度随时间变化的曲线
val_acc = history.history['val_accuracy'] # 获取验证集准确度随时间变化的曲线
loss = history.history['loss'] # 获取训练集损失随时间变化的曲线
val_loss = history.history['val_loss'] # 获取验证集损失随时间变化的曲线
epochs_range = range(epochs) # 定义迭代次数的范围
plt.figure(figsize=(8, 8)) # 创建一个图像窗口
plt.subplot(2, 1, 1) # 创建子图,绘制训练集和验证集准确度随时间变化的曲线
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(2, 1, 2) # 创建子图,绘制训练集和验证集损失随时间变化的曲线
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
# 选择一张测试图片
test_image_path = 'C:/Users/28938/Desktop/image/image/test/cats/cat.4004.jpg'
# 读取并预处理图片
img = keras.preprocessing.image.load_img(
test_image_path, target_size=(img_height, img_width)
)
img_array = keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # 创建一个批次维度
# 预测图片类别
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
# 显示图片和预测结果
plt.imshow(img)
plt.axis('off')
plt.show()
print('预测结果: {}, 置信度: {:.2f}%'.format(class_names[np.argmax(score)], 100 * np.max(score)))
# 打印数据集分类类别
print('数据集分类类别:', train_ds.class_names)
原文地址: https://www.cveoy.top/t/topic/pidw 著作权归作者所有。请勿转载和采集!