在深度学习中,“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)
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()
模型解释:
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()
5. 模型评价以及模型保存
# 在测试集上评估模型性能
test_loss, test_acc = model.evaluate(x_test, y_test)
print("测试集损失:", test_loss)
print("测试集准确率:", test_acc)
# 保存模型
model.save('model.keras')
6. 模型调用识别数字
加载一个已经训练好的神经网络模型,该模型用于识别手写数字,然后读取一张包含手写数字的图像(上图),并对图像进行预处理,使其与模型的输入格式相匹配,最后通过该模型对预处理后的图像进行预测,输出预测的手写数字
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)
往期推荐
基于VMD分解的VMD-CNN-LSTM时间序列预测模型实现
可解释性机器学习库Shapash——鸢尾花XGBoost分类解释实现
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~