MicrosoftDocs/ml-basics项目:使用TensorFlow构建卷积神经网络(CNN)图像分类器

MicrosoftDocs/ml-basics项目:使用TensorFlow构建卷积神经网络(CNN)图像分类器

ml-basics Exercise notebooks for Machine Learning modules on Microsoft Learn ml-basics 项目地址: https://gitcode.com/gh_mirrors/mlb/ml-basics

卷积神经网络简介

卷积神经网络(CNN)是深度学习领域中一种专门用于处理图像数据的神经网络架构。与传统的全连接神经网络不同,CNN通过局部连接和权值共享的方式,能够有效提取图像中的空间特征。

CNN的核心思想是通过卷积运算自动学习图像的特征表示。一个典型的CNN包含以下几层:

  1. 卷积层(Convolutional Layer):使用多个卷积核在图像上滑动,提取局部特征
  2. 池化层(Pooling Layer):降低特征图的空间维度,增强模型对位置变化的鲁棒性
  3. 全连接层(Fully Connected Layer):将学习到的特征映射到最终的分类结果

项目环境准备

在开始构建CNN模型前,我们需要确保TensorFlow环境已正确安装和配置:

import tensorflow
from tensorflow import keras
print('TensorFlow版本:', tensorflow.__version__)
print('Keras版本:', keras.__version__)

建议使用TensorFlow 2.x版本,它提供了更简洁的API和更好的性能。

数据集探索

本项目使用一个简单的几何形状数据集,包含三类图像:圆形(circle)、正方形(square)和三角形(triangle)。让我们先查看数据集中的样本:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import os

data_folder = 'data/shapes'
classes = os.listdir(data_folder)
classes.sort()

# 显示每个类别的第一张图像
fig = plt.figure(figsize=(8, 12))
for i, class_name in enumerate(classes):
    img_file = os.listdir(os.path.join(data_folder, class_name))[0]
    img_path = os.path.join(data_folder, class_name, img_file)
    img = mpimg.imread(img_path)
    ax = fig.add_subplot(1, len(classes), i+1)
    ax.axis('off')
    plt.imshow(img)
    ax.set_title(class_name)
plt.show()

数据预处理

在训练模型前,需要对图像数据进行标准化处理,并划分为训练集和验证集:

from tensorflow.keras.preprocessing.image import ImageDataGenerator

img_size = (128, 128)
batch_size = 30

# 创建数据生成器,进行归一化和数据集划分
datagen = ImageDataGenerator(rescale=1./255, validation_split=0.3)

# 训练集生成器
train_generator = datagen.flow_from_directory(
    data_folder,
    target_size=img_size,
    batch_size=batch_size,
    class_mode='categorical',
    subset='training')

# 验证集生成器
validation_generator = datagen.flow_from_directory(
    data_folder,
    target_size=img_size,
    batch_size=batch_size,
    class_mode='categorical',
    subset='validation')

classnames = list(train_generator.class_indices.keys())

这里我们使用ImageDataGenerator进行数据增强和批处理,将图像像素值归一化到[0,1]区间,并保留30%的数据作为验证集。

CNN模型构建

下面我们构建一个包含多个卷积层和池化层的CNN模型:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense

model = Sequential()

# 第一卷积层
model.add(Conv2D(32, (6, 6), input_shape=train_generator.image_shape, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

# 第二卷积层
model.add(Conv2D(32, (6, 6), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# 第三卷积层
model.add(Conv2D(32, (6, 6), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# Dropout层防止过拟合
model.add(Dropout(0.2))

# 展平层
model.add(Flatten())

# 全连接输出层
model.add(Dense(train_generator.num_classes, activation='softmax'))

# 编译模型
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

print(model.summary())

这个模型结构包含:

  1. 三个卷积层,每层使用32个6×6的卷积核和ReLU激活函数
  2. 每个卷积层后接一个2×2的最大池化层
  3. 一个Dropout层(丢弃率20%)用于防止过拟合
  4. 一个展平层将特征图转换为一维向量
  5. 一个全连接输出层,使用softmax激活函数进行多分类

模型训练

配置好模型后,我们可以开始训练过程:

num_epochs = 5
history = model.fit(
    train_generator,
    steps_per_epoch=train_generator.samples // batch_size,
    validation_data=validation_generator,
    validation_steps=validation_generator.samples // batch_size,
    epochs=num_epochs)

这里我们训练5个epoch,每个epoch使用批量大小为30。训练过程中会同时计算训练集和验证集上的损失和准确率。

训练过程可视化

训练完成后,我们可以绘制损失曲线来评估模型的学习情况:

epoch_nums = range(1, num_epochs+1)
training_loss = history.history["loss"]
validation_loss = history.history["val_loss"]

plt.plot(epoch_nums, training_loss)
plt.plot(epoch_nums, validation_loss)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(['Training', 'Validation'], loc='upper right')
plt.show()

理想情况下,训练损失和验证损失都应该随着训练逐渐下降。如果验证损失开始上升而训练损失继续下降,可能出现了过拟合。

模型评估

为了更详细地了解模型性能,我们可以绘制混淆矩阵:

import numpy as np
from sklearn.metrics import confusion_matrix

# 获取验证集第一批数据
x_test = validation_generator[0][0]
y_test = validation_generator[0][1]

# 预测类别
class_probabilities = model.predict(x_test)
predictions = np.argmax(class_probabilities, axis=1)
true_labels = np.argmax(y_test, axis=1)

# 绘制混淆矩阵
cm = confusion_matrix(true_labels, predictions)
plt.imshow(cm, interpolation="nearest", cmap=plt.cm.Blues)
plt.colorbar()
tick_marks = np.arange(len(classnames))
plt.xticks(tick_marks, classnames, rotation=85)
plt.yticks(tick_marks, classnames)
plt.xlabel("Predicted Shape")
plt.ylabel("Actual Shape")
plt.show()

混淆矩阵可以直观展示模型在各个类别上的分类表现,对角线上的值表示正确分类的样本数。

模型保存与应用

训练好的模型可以保存为HDF5文件,便于后续使用:

modelFileName = 'models/shape_classifier.h5'
model.save(modelFileName)
del model

加载保存的模型进行预测:

from tensorflow.keras import models
import numpy as np

# 加载模型
model = models.load_model(modelFileName)

# 预测函数
def predict_image(classifier, image):
    imgfeatures = image.reshape(1, *image.shape)
    imgfeatures = imgfeatures.astype('float32')
    imgfeatures /= 255
    class_probabilities = classifier.predict(imgfeatures)
    return np.argmax(class_probabilities, axis=1)[0]

# 使用模型预测新图像
new_image = create_image((128,128), 'circle')  # 创建一个圆形图像
predicted_class = predict_image(model, new_image)
print("Predicted class:", classnames[predicted_class])

总结与扩展

本教程展示了使用TensorFlow构建CNN图像分类器的完整流程,包括:

  1. 数据准备与预处理
  2. CNN模型架构设计
  3. 模型训练与验证
  4. 性能评估与模型应用

对于更复杂的图像分类任务,可以考虑以下改进:

  1. 使用更深的网络结构(如ResNet、VGG等)
  2. 增加数据增强手段(旋转、平移、缩放等)
  3. 使用预训练模型进行迁移学习
  4. 调整超参数(学习率、批量大小等)优化性能

通过这个基础示例,读者可以掌握CNN的核心概念和TensorFlow的基本用法,为进一步探索计算机视觉领域打下坚实基础。

ml-basics Exercise notebooks for Machine Learning modules on Microsoft Learn ml-basics 项目地址: https://gitcode.com/gh_mirrors/mlb/ml-basics

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程璞昂Opal

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值