前言:
MNIST数字分类项目:
MNIST数字分类项目旨在使用机器学习技术来构建一个模型,能够自动识别手写数字的图像。这个项目是一个经典的图像分类任务,常用于入门级机器学习和深度学习示例。我们会使用MNIST数据集,这个数据集包含了一系列28x28像素的手写数字图像,从0到9。项目的目标是训练一个模型,能够准确地将这些手写数字图像分类到正确的数字标签。
MNIST数据集:
包含了60000张训练图像和10000张测试图像,每张图像都是28x28像素的灰度图像。每个图像都与一个0到9的数字标签相关联,表示图像中包含的手写数字。
这个数据集是一个非常适合用于图像分类任务的基准数据集。
卷积神经网络(CNN):
最适合图像分类任务的算法之一。CNN通过学习图像中的局部模式(如边缘和纹理)逐渐构建出更复杂的图像特征,使其在图像识别任务中表现出色。
模型训练:
1.数据加载:
加载MNIST数据集,将其分为训练集和测试集
2.数据预处理:
对图像数据进行必要的预处理,包括标准化像素值、降低维度、或者进行特征提取。
3.模型训练:
使用训练数据集来训练不同的机器学习算法或深度学习模型。调整模型的超参数以获得最佳性能。
4.性能评估:
使用测试数据集对模型的性能进行评估,包括准确度、精确度、召回率等指标。
代码:
1.导包
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
2.加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
3.数据预处理
# 数据预处理
# reshape()函数用于改变数组的形状,将原始数据重新组织成指定形状的数组
# astype()函数用于改变数组的数据类型,将数组中的元素转换为指定的数据类型
train_images = train_images.reshape((60000, 28, 28, 1)) # 将原始数据重新组织成60000个28*28*1的数组
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255 # astype('float32')将图像数据转换为32位浮点数类型
4.转码
# to_categorical:将标签转换为 one-hot 编码形式
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
5.构建神经网络模型
model = Sequential() # 初始化一个序贯模型
# 向模型中添加一个2维卷积层,32:卷积核数量,(3, 3):卷积核大小
# input_shape=(28, 28, 1)表示输入图像的大小为28x28像素,且是单通道的图像
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
# 添加一个2维最大池化层,用于对卷积层的输出进行下采样,以减少模型复杂度和计算量
model.add(MaxPooling2D((2, 2)))
# 添加一个展平层,用于将池化层的输出展平为一维向量,以便连接全连接层
model.add(Flatten())
# 添加一个全连接层,包含128个神经元,使用ReLU激活函数
model.add(Dense(128, activation='relu'))
# 添加一个全连接层,包含10个神经元,使用softmax激活函数,用于输出分类结果的概率分布
model.add(Dense(10, activation='softmax'))
6.编译模型
model.compile(optimizer='adam', # 优化器
loss='categorical_crossentropy', # 损失函数
metrics=['accuracy']) # 模型性能指标
7.训练模型
history=model.fit(train_images, train_labels, epochs=20, batch_size=64, validation_split=0.1)
8.保存模型
model.save('mnist_model.h5')
9.评估模型
# evaluate:评估函数
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print(f'Test accuracy: {test_accuracy}')
plt.plot(history.epoch, history.history['loss'], 'r', label='loss')
plt.plot(history.epoch, history.history['val_loss'], 'b--', label='val_loss')
plt.legend()
plt.plot(history.epoch, history.history['accuracy'], 'r',label = 'accuracy')
plt.plot(history.epoch, history.history['val_accuracy'], 'b--',label = 'val_accuracy')
plt.legend()
模型应用:
1.导包
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.datasets import mnist
from tensorflow.keras.preprocessing.image import load_img, img_to_array
import cv2
2.加载训练好的模型
# 加载训练好的模型
model = keras.models.load_model('mnist_model.h5')
3.加载数据集
# 加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
使用测试集上的数字进行验证
# 加载并显示一个手写数字图像(可以自己手写一个数字图像,或从测试集中选取)
image_index = 256 # 随机选择一个测试图像
image = test_images[image_index] # 从测试集中获取图像
# 使用模型进行预测
predictions = model.predict(np.array([image]))
predicted_label = np.argmax(predictions)
# 显示图像和预测结果
plt.imshow(image.reshape(28, 28), cmap='gray')
plt.title(f'Predicted Label: {predicted_label}')
plt.show()
# 选择要显示的测试图像数量
num_images_to_display = 10
# 随机选择10个测试图像的索引
image_indices = np.random.choice(len(test_images), num_images_to_display, replace=False)
# 创建一个2行5列的图像显示窗口
plt.figure(figsize=(10, 4))
# 遍历选择的图像索引
for i, image_index in enumerate(image_indices, 1):
image = test_images[image_index] # 从测试集中获取图像
predictions = model.predict(np.array([image]))
predicted_label = np.argmax(predictions)
plt.subplot(2, 5, i)
plt.imshow(image.reshape(28, 28), cmap='gray')
plt.title(f'Predicted: {predicted_label}')
plt.axis('off')
plt.show()
验证手写数字:
image = cv2.imread('8.jpg') # 读取图片
image.shape #查看图片形状---->(1085, 1091, 3)要将这个变为(28,28,1)
# 图像显示
def plt_img_show(image):
if (len(image.shape)==3):
result = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 需要将bgr图片转换程rgb
plt.imshow(result)
else:
result = image
plt.imshow(result,cmap='gray')
plt.show()
# 将图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_image.shape # ----->(1085,1091)
调整图像形状:
# 调整图像形状
resized_image = cv2.resize(gray_image, (28, 28))
reshaped_image = np.expand_dims(resized_image, axis=0)
reshaped_image = np.expand_dims(reshaped_image, axis=-1)
reshaped_image.shape # ---->(1, 28, 28, 1)
预测:
predictions = model.predict(reshaped_image)
# 显示图像和预测结果
plt.imshow(reshaped_image.reshape(28, 28), cmap='gray')
predicted_label = np.argmax(predictions)
plt.title(f'Predicted Label: {predicted_label}')
plt.show()
完整代码:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
# 加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1)) # 将原始数据重新组织成60000个28*28*1的数组
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255 # astype('float32')将图像数据转换为32位浮点数类型
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# 构建卷积神经网络模型
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))
# 编译模型
model.compile(optimizer='adam', # 优化器
loss='categorical_crossentropy', # 损失函数
metrics=['accuracy']) # 模型性能指标
# 训练模型
history=model.fit(train_images, train_labels, epochs=20, batch_size=64, validation_split=0.1)
# 保存模型
model.save('mnist_model.h5')
# 评估模型
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print(f'Test accuracy: {test_accuracy}')
plt.plot(history.epoch, history.history['loss'], 'r', label='loss')
plt.plot(history.epoch, history.history['val_loss'], 'b--', label='val_loss')
plt.legend()
plt.plot(history.epoch, history.history['accuracy'], 'r',label = 'accuracy')
plt.plot(history.epoch, history.history['val_accuracy'], 'b--',label = 'val_accuracy')
plt.legend()
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.datasets import mnist
from tensorflow.keras.preprocessing.image import load_img, img_to_array
import cv2
# 加载训练好的模型
model = keras.models.load_model('mnist_model.h5')
# 加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 加载并显示一个手写数字图像(可以自己手写一个数字图像,或从测试集中选取)
image_index = 256 # 随机选择一个测试图像
image = test_images[image_index] # 从测试集中获取图像
# 使用模型进行预测
predictions = model.predict(np.array([image]))
predicted_label = np.argmax(predictions)
# 显示图像和预测结果
plt.imshow(image.reshape(28, 28), cmap='gray')
plt.title(f'Predicted Label: {predicted_label}')
plt.show()
# 选择要显示的测试图像数量
num_images_to_display = 10
# 随机选择10个测试图像的索引
image_indices = np.random.choice(len(test_images), num_images_to_display, replace=False)
# 创建一个2行5列的图像显示窗口
plt.figure(figsize=(10, 4))
# 遍历选择的图像索引
for i, image_index in enumerate(image_indices, 1):
image = test_images[image_index] # 从测试集中获取图像
predictions = model.predict(np.array([image]))
predicted_label = np.argmax(predictions)
plt.subplot(2, 5, i)
plt.imshow(image.reshape(28, 28), cmap='gray')
plt.title(f'Predicted: {predicted_label}')
plt.axis('off')
plt.show()
def plt_img_show(image):
if (len(image.shape)==3):
result = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 需要将bgr图片转换程rgb
plt.imshow(result)
else:
result = image
plt.imshow(result,cmap='gray')
plt.show()
image = cv2.imread('8.jpg')
plt_img_show(image)
# 将图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 调整图像大小
resized_image = cv2.resize(gray_image, (28, 28))
reshaped_image = np.expand_dims(resized_image, axis=0)
reshaped_image = np.expand_dims(reshaped_image, axis=-1)
reshaped_image.shape
# 进行预测
predictions = model.predict(reshaped_image)
# 显示图像和预测结果
plt.imshow(reshaped_image.reshape(28, 28), cmap='gray')
predicted_label = np.argmax(predictions)
plt.title(f'Predicted Label: {predicted_label}')
plt.show()