深度学习中的“Hello World”——MNIST手写数字识别

技术

在深度学习中,“Hello World”通常指的是一个简单的示例,展示了如何使用深度学习框架来解决一个基本的问题,最经典的“Hello World”示例是使用神经网络来识别手写数字,这个问题通常被称为MNIST手写数字识别问题,在这个问题中,目标是训练一个神经网络,使其能够准确地识别手写数字图像中的数字, 当然接下来的代码是通过调用相关库进行实现,如果你需要从底层开始实现该项目推荐以下链接进行学习参考


        
            

          http://neuralnetworksanddeeplearning.com/chap1.html
        
      

这个问题之所以成为“Hello World”,是因为它是深度学习中最简单、最基础的问题之一,很多人在学习深度学习时会从这个问题开始,通过解决这个问题,可以学会如何搭建神经网络、准备数据、进行训练和评估模型的性能等基本技能

python代码实现

1. 数据加载


          
import tensorflow as tf
          

          
# 加载 MNIST 数据集
          
mnist = tf.keras.datasets.mnist 
          
# 加载训练数据和测试数据
          
(x_train, y_train), (x_test, y_test) = mnist.load_data()
          

          
# 打印数据集的维度信息
          
print("训练数据集维度:", x_train.shape)
          
print("训练标签集维度:", y_train.shape)
          
print("测试数据集维度:", x_test.shape)
          
print("测试标签集维度:", y_test.shape)
      

picture.image

MNIST 数据集中的图像已经经过预处理,转换为了数值化的形式,具体来说,每张图像都是一个灰度图,表示为 28x28 的矩阵,其中每个元素代表了对应位置的像素强度值

2. 数据预处理


        
            

          x\_train, x\_test = x\_train / 255.0, x\_test / 255.0
        
      

像素的取值范围是0到255,表示像素的灰度值,其中0表示黑色,255表示白色,对数据进行预处理 加速模型的训练,并且有助于模型更好地收敛

3 . 模型构建


          
# 构建神经网络模型
          
model = tf.keras.models.Sequential([
          
    tf.keras.layers.Flatten(input_shape=(28, 28)),  # 将二维的图像展平为一维向量
          
    tf.keras.layers.Dense(16, activation='relu'),  # 添加一个具有16个神经元的全连接层,激活函数为ReLU
          
    tf.keras.layers.Dense(16, activation='relu'),
          
    tf.keras.layers.Dropout(0.2),  # 添加一个Dropout层,防止过拟合 正则化有20%的神经元被丢弃以减少过拟合
          
    tf.keras.layers.Dense(10, activation='softmax')  # 添加一个具有10个神经元的输出层,激活函数为softmax
          
])
          

          
# 编译模型
          
model.compile(optimizer='adam', # 优化器
          
              loss='sparse_categorical_crossentropy', # 损失函数 
          
              metrics=['accuracy']) # 评价指标
          

          
# 打印模型的结构信息
          
model.summary()
      

picture.image

模型解释:

Flatten 层: 这是输入层,用于将输入的二维图像数据展平成一维向量,输入图像的尺寸为 28x28 像素,所以展平后的向量长度为 784

Dense 层: 这是第一个隐藏层,包含 16 个神经元,该层是全连接层,每个神经元与上一层中的所有神经元相连,参数数量为 784 (输入向量长度) * 16 (神经元数量) + 16 (偏置项) = 12560

Dense 层: 这是第二个隐藏层,同样包含 16 个神经元,参数数量为 16 (上一层神经元数量) * 16 (神经元数量) + 16 (偏置项) = 272

Dropout 层: 这是一个 Dropout 层,用于在训练过程中随机将一部分神经元的输出置为零,以防止过拟合,在本模型中,Dropout 层的输出形状与上一层相同,即 (None, 16)

Dense 层: 这是输出层,包含 10 个神经元,对应着 10 个类别(0 到 9 的数字),参数数量为 16 (上一层神经元数量) * 10 (神经元数量) + 10 (偏置项) = 170

总参数数量为13002,其中所有参数都是可训练的,个模型的训练目标是最小化损失函数,使得模型能够准确地预测输入图像对应的数字类别

4. 训练模型


          
import matplotlib.pyplot as plt
          
# 记录训练过程中的损失值
          
history = model.fit(x_train, y_train, epochs=20, validation_data=(x_test, y_test))
          

          
# 绘制损失曲线
          
plt.plot(history.history['loss'], label='Training Loss')
          
plt.plot(history.history['val_loss'], label='Validation Loss')
          
plt.xlabel('Epoch')
          
plt.ylabel('Loss')
          
plt.legend()
          
plt.show()
      

picture.image

5. 模型评价以及模型保存


          
# 在测试集上评估模型性能
          
test_loss, test_acc = model.evaluate(x_test, y_test)
          
print("测试集损失:", test_loss)
          
print("测试集准确率:", test_acc)
          
# 保存模型
          
model.save('model.keras')
      

picture.image

6. 模型调用识别数字

picture.image

加载一个已经训练好的神经网络模型,该模型用于识别手写数字,然后读取一张包含手写数字的图像(上图),并对图像进行预处理,使其与模型的输入格式相匹配,最后通过该模型对预处理后的图像进行预测,输出预测的手写数字


          
import tensorflow as tf
          
import cv2
          
import numpy as np
          

          
# 加载训练好的模型
          
model = tf.keras.models.load_model('model.keras')
          

          
# 读取现实中的手写数字图像
          
image = cv2.imread('handwritten_digit.jpg', cv2.IMREAD_GRAYSCALE)
          

          
# 调整图像尺寸为模型输入的大小(28x28)
          
image_resized = cv2.resize(image, (28, 28))
          

          
# 对图像进行归一化处理
          
image_normalized = image_resized / 255.0
          

          
# 将图像转换为模型所需的形状 (1, 28, 28, 1)
          
image_input = np.expand_dims(image_normalized, axis=0)
          
image_input = np.expand_dims(image_input, axis=-1)
          
prediction = model.predict(image_input)
          
predicted_digit = np.argmax(prediction)
          
print("预测结果:", predicted_digit)
      

picture.image

往期推荐

常见激活函数详解

基于VMD分解的VMD-CNN-LSTM时间序列预测模型实现

特征工程——数据转换

回归任务常见评价指标解读以及Python实现

分类模型评价指标详解(Python实现)

可解释性机器学习库Shapash——鸢尾花XGBoost分类解释实现

LightGBM模型房价预测实现

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论