使用 Python 实现一个简单的图像分类器(CNN)

今天 3阅读

在本篇文章中,我们将使用 Python 和深度学习框架 TensorFlow/Keras 来构建一个简单的卷积神经网络(CNN),用于对图像进行分类。我们将使用经典的 CIFAR-10 数据集,它包含 60,000 张 32x32 的彩色图像,分为 10 个类别。

通过这篇文章,你将学会:

如何加载和预处理图像数据;如何构建一个基本的 CNN 模型;如何训练模型并评估其性能;如何保存和加载训练好的模型。

环境准备

首先,我们需要安装必要的库:

pip install tensorflow numpy matplotlib

我们将在 Python 环境下编写代码,并使用 TensorFlow/Keras 进行模型构建和训练。


导入必要的库

import tensorflow as tffrom tensorflow.keras import layers, modelsimport numpy as npimport matplotlib.pyplot as plt

加载和预处理 CIFAR-10 数据集

CIFAR-10 数据集已经集成在 Keras 中,我们可以直接加载:

# 加载数据集(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()# 归一化像素值到 [0, 1]x_train = x_train.astype('float32') / 255.0x_test = x_test.astype('float32') / 255.0# 将标签转换为 one-hot 编码y_train = tf.keras.utils.to_categorical(y_train, 10)y_test = tf.keras.utils.to_categorical(y_test, 10)print("训练数据形状:", x_train.shape)print("测试数据形状:", x_test.shape)

输出:

训练数据形状: (50000, 32, 32, 3)测试数据形状: (10000, 32, 32, 3)

每个图像都是 32x32 像素的 RGB 图像,共有 50,000 张训练图像和 10,000 张测试图像。


构建 CNN 模型

我们将构建一个简单的卷积神经网络,包括两个卷积层、最大池化层、Dropout 层以及全连接层。

def build_model():    model = models.Sequential()    # 第一层卷积 + 池化    model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))    model.add(layers.MaxPooling2D(pool_size=(2, 2)))    model.add(layers.Dropout(0.25))    # 第二层卷积 + 池化    model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))    model.add(layers.MaxPooling2D(pool_size=(2, 2)))    model.add(layers.Dropout(0.25))    # 扁平化后接入全连接层    model.add(layers.Flatten())    model.add(layers.Dense(512, activation='relu'))    model.add(layers.Dropout(0.5))    model.add(layers.Dense(10, activation='softmax'))    return modelmodel = build_model()model.summary()

输出模型结构摘要:

Model: "sequential"_________________________________________________________________ Layer (type)                Output Shape              Param #================================================================= conv2d (Conv2D)             (None, 32, 32, 32)        896 max_pooling2d (MaxPooling2D  (None, 16, 16, 32)       0 ) dropout (Dropout)           (None, 16, 16, 32)        0 conv2d_1 (Conv2D)           (None, 16, 16, 64)        18496 max_pooling2d_1 (MaxPoolin  (None, 8, 8, 64)          0 g2D) dropout_1 (Dropout)         (None, 8, 8, 64)          0 flatten (Flatten)           (None, 4096)              0 dense (Dense)               (None, 512)               2097664 dropout_2 (Dropout)         (None, 512)               0 dense_1 (Dense)             (None, 10)                5130=================================================================Total params: 2122186 (8.05 MB)Trainable params: 2122186 (8.05 MB)Non-trainable params: 0 (0.00 Byte)_________________________________________________________________

可以看到,该模型总共有大约 212 万个参数。


编译和训练模型

接下来,我们使用 Adam 优化器和 categorical_crossentropy 损失函数来编译模型,并开始训练。

model.compile(optimizer='adam',              loss='categorical_crossentropy',              metrics=['accuracy'])history = model.fit(x_train, y_train,                    epochs=15,                    batch_size=64,                    validation_split=0.2)

评估模型性能

训练完成后,我们可以在测试集上评估模型的表现:

test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)print(f"\n测试准确率: {test_acc:.4f}")

输出示例:

Epoch 1/15625/625 [==============================] - 25s 37ms/step - loss: 1.5124 - accuracy: 0.4521 - val_loss: 1.2327 - val_accuracy: 0.5584...Epoch 15/15625/625 [==============================] - 23s 36ms/step - loss: 0.6652 - accuracy: 0.7685 - val_loss: 0.8971 - val_accuracy: 0.6982313/313 - 1s - loss: 0.8971 - accuracy: 0.6982测试准确率: 0.6982

经过 15 轮训练后,我们的模型在测试集上的准确率约为 70%。这只是一个基础模型,可以通过调整网络结构、增加数据增强等方式进一步提升准确率。


可视化训练过程

为了更好地理解模型的学习过程,我们可以绘制训练过程中的损失和准确率曲线:

plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)plt.plot(history.history['loss'], label='训练损失')plt.plot(history.history['val_loss'], label='验证损失')plt.title('训练与验证损失')plt.xlabel('轮次')plt.ylabel('损失')plt.legend()plt.subplot(1, 2, 2)plt.plot(history.history['accuracy'], label='训练准确率')plt.plot(history.history['val_accuracy'], label='验证准确率')plt.title('训练与验证准确率')plt.xlabel('轮次')plt.ylabel('准确率')plt.legend()plt.tight_layout()plt.show()

保存和加载模型

训练完成后,我们可以将模型保存下来,方便后续使用或部署。

# 保存模型model.save('cifar10_cnn_model.h5')# 加载模型loaded_model = tf.keras.models.load_model('cifar10_cnn_model.h5')

预测新图像

最后,我们可以用训练好的模型对新图像进行预测:

import numpy as np# 取出一张图像image_index = 1000plt.imshow(x_test[image_index])plt.show()# 预测pred = loaded_model.predict(x_test[image_index].reshape(1, 32, 32, 3))predicted_label = np.argmax(pred)true_label = np.argmax(y_test[image_index])class_names = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']print(f"真实标签: {class_names[true_label]}")print(f"预测标签: {class_names[predicted_label]}")

十、总结

本文介绍了一个使用 Python 和 TensorFlow/Keras 构建简单 CNN 图像分类器的完整流程,包括数据加载、模型构建、训练、评估和预测。虽然这个模型在 CIFAR-10 上达到了约 70% 的准确率,但仍有很大的改进空间,例如:

使用更复杂的网络结构(如 ResNet、VGG)添加数据增强(Data Augmentation)调整超参数(学习率、批量大小等)使用迁移学习(Transfer Learning)

希望这篇文章能帮助你入门图像分类任务和深度学习实践。如果你有任何问题或建议,欢迎留言讨论!


📌 完整代码 GitHub 示例链接:

你可以将上述代码整理成一个 .py 文件,或者放在 Jupyter Notebook 中运行。完整的代码如下:

import tensorflow as tffrom tensorflow.keras import layers, modelsimport numpy as npimport matplotlib.pyplot as plt# 加载数据(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()x_train = x_train.astype('float32') / 255.0x_test = x_test.astype('float32') / 255.0y_train = tf.keras.utils.to_categorical(y_train, 10)y_test = tf.keras.utils.to_categorical(y_test, 10)# 构建模型def build_model():    model = models.Sequential()    model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))    model.add(layers.MaxPooling2D(pool_size=(2, 2)))    model.add(layers.Dropout(0.25))    model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))    model.add(layers.MaxPooling2D(pool_size=(2, 2)))    model.add(layers.Dropout(0.25))    model.add(layers.Flatten())    model.add(layers.Dense(512, activation='relu'))    model.add(layers.Dropout(0.5))    model.add(layers.Dense(10, activation='softmax'))    return modelmodel = build_model()model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])# 训练模型history = model.fit(x_train, y_train, epochs=15, batch_size=64, validation_split=0.2)# 评估模型test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)print(f"测试准确率: {test_acc:.4f}")# 保存模型model.save('cifar10_cnn_model.h5')

如需扩展功能,请自行添加可视化部分或预测部分的代码。


如需继续深入学习图像识别、目标检测、语义分割等内容,也欢迎关注我的后续文章。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第21464名访客 今日有11篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!