参考文章:https://mtyjkh.blog.csdn.net/article/details/116920825
数据集
mnist手写数据集:
- 总共有70000张图片,其中60000张图片用于训练,10000张图片用于测试,图片的宽高分别为28、28
- 28x28的图片,转换成28x28个像素点,每个像素点的值介于0和1之间
卷积神经网络结构图
注:
卷积层计算公式 :
H 2 = H 1 − F H + 2 P S + 1 H_2=\frac{H_1-F_H+2P}{S}+1 H2=SH1−FH+2P+1
W 2 = W 1 − F W + 2 P S + 1 W_2=\frac{W_1-F_W+2P}{S}+1 W2=SW1−FW+2P+1
1、H是指图片的高,W是图片的宽,F指的是卷积核(H和W对应卷积核的高度和宽度)
2、P是padding填充,padding=1时候,矩阵外围加上一圈0,加强对边缘特征的提取,且0不会对特征提取产生影响
代码实现(TensorFlow框架)
设置GPU
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
gpus = tf.config.list_physical_devices("GPU")
if gpus:
print("可以使用GPU")
gpu0 = gpus[0]
tf.config.experimental.set_memory_growth(gpu0, True)
tf.config.set_visible_devices([gpu0], "GPU")
数据的读取
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
归一化(将像素的值标准化到0-1的区间内)
train_images, test_images = train_images / 255.0, test_images/ 255.0
train_images.shape, train_labels.shape, test_images.shape, test_labels.shape
可视化图片
plt.figure(figsize=(20, 10))
for i in range(20):
plt.subplot(5, 10, i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i], cmap=plt.cm.binary)
plt.xlabel(train_labels[i])
plt.show()
调整图片形状(添加一个通道)
train_images = train_images.reshape((60000, 28, 28, 1))
test_images = test_images.reshape((10000, 28, 28, 1))
train_images.shape, train_labels.shape, test_images.shape, test_labels.shape
构建CNN网络模型
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)), #卷积层1,32个3x3的卷积核
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(), # Flatten层,连接卷积层和全连接层
layers.Dense(64, activation='relu'), # 全连接层,特征进一步提取
layers.Dense(10) # 输出层,输出预期结果
])
# 打印网络结构
model.summary()
编辑模型
"""
设置优化器、损失函数以及metrics
"""
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy']
)
optimizer:预定义优化器名称
1、sgd: tf.optimizers.SGD(lr = 学习率, decay = 学习率衰减率,momentum = 动量参数)
2、adagrad:tf.keras.optimizers.Adagrad(lr = 学习率, decay = 学习率衰减率)
3、adadelta:tf.keras.optimizers.Adadelta(lr = 学习率,decay = 学习率衰减率)
4、adam:tf.keras.optimizers.Adam(lr = 学习率, decay = 学习率衰减率)
loss:预定义损失函数名称
1、“mse”、“mean squared error”、tf.keras.losses.MeanSquaredError()
2、“sparse_categorical_crossentropy” 、tf.keras.losses.SparseCatagoricalCrossentropy(from_logits = False)
metrics:评估模型在训练和测试时的性能的指标
1、 “accuracy”
2、“sparse_accuracy”
3、“sparse_categorical_accuracy”
训练模型
"""
设置输入训练数据集(图片和标签)、验证数据集(图片和标签)以及迭代次数epochs
"""
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels)
)
train_images:输入数据,如果模型只有一个输入,那么x的类型是numpy,如果模型有多个输入,那么x的类型应当为list,list的元素是对应于各个输入的numpy
array
train_labels:标签,numpy array
epochs:整数,训练终止时的epoch值,训练将在达到该epoch值时停止,当没有设置initial_epoch时,它就是训练的总轮数,否则训练的总轮数为epochs - inital_epoch
validation_data:形式为(x,y)的tuple,是指定的验证集。
预测
import numpy as np
# 预测
pre = model.predict(test_images) # 对所有测试图片进行预测
test_result = []
for i in range(20):
test_result.append(np.argmax(pre[i]))
print("预测的结果:",test_result)
# 可视化测试图片和测试的标签,与结果进行比较
plt.figure(figsize=(20, 10))
for i in range(20):
plt.subplot(5, 10, i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(test_images[i], cmap=plt.cm.binary)
plt.xlabel(test_labels[i])
plt.show()