深度学习:多层感知机
1 概述
(1)基础环境
- python3.8.12
- tensorflow2.7.0
(2)多层感知机概述
- 多层感知器(Multilayer Perceptron,缩写MLP)是一种前向结构的人工神经网络,映射一组输入向量到一组输出向量。
- MLP可以被看作是一个有向图,由多个的节点层所组成,每一层都全连接到下一层。
- 除了输入节点,每个节点都是一个带有非线性激活函数的神经元(或称处理单元)。
- 它首先学习,然后使用权重存储数据,并使用算法来调整权重并减少训练过程中的偏差,即实际值和预测值之间的误差。
- 基本结构:输入层 -> 中间隐藏层 -> 输出层。
2 数字识别(mnist)基础步骤
- 使用
tf.keras.datasets
获得数据集并预处理
- 使用
tf.keras.Model
和 tf.keras.layers
构建模型
- 构建模型训练流程,使用
tf.keras.losses
计算损失函数,并使用 tf.keras.optimizer
优化模型
- 构建模型评估流程,使用
tf.keras.metrics
计算评估指标
3 模型训练与导出模型
import tensorflow as tf
import numpy as np
# 数据加载类
class MNISTLoader():
def __init__(self):
# 下载训练数据和测试数据
mnist = tf.keras.datasets.mnist
(self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()
# MNIST中的图像默认为uint8(0-255的数字)。以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道
# [60000, 28, 28, mnist]
self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0, axis=-1)
# [10000, 28, 28, mnist]
self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1)
# [60000]
self.train_label = self.train_label.astype(np.int32)
# [10000]
self.test_label = self.test_label.astype(np.int32)
self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]
def get_batch(self, batch_size):
# 从数据集中随机取出batch_size个元素并返回
index = np.random.randint(0, self.num_train_data, batch_size)
return self.train_data[index, :], self.train_label[index]
num_epochs = 5 # 迭代次数
batch_size = 50 # 批量大小
learning_rate = 0.001 # 学习率
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(), # 28 * 28 * 1 --打平--> 784
tf.keras.layers.Dense(100, activation=tf.nn.relu), # 784 -f(AW+b)线性变换 + Relu激活函数-> 100
tf.keras.layers.Dense(10), # 100 --f(AW+b)线性变换--> 10
tf.keras.layers.Softmax() # softmax函数凸显原始向量中最大的值并抑制远低于最大值的其他分量
])
data_loader = MNISTLoader()
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), # 优化器:Adam优化器
loss=tf.keras.losses.sparse_categorical_crossentropy, # 损失函数:交叉熵
metrics=[tf.keras.metrics.sparse_categorical_accuracy] # 评估指标
)
# 训练模型
model.fit(data_loader.train_data, data_loader.train_label, epochs=num_epochs, batch_size=batch_size)
# 导出模型
tf.saved_model.save(model, "saved/mnist")
4 模型导入与预测
(1)导入模型并测试性能
# 导入模型并测试性能
batch_size = 50
model = tf.saved_model.load("saved/mnist")
data_loader = MNISTLoader()
sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
num_batches = int(data_loader.num_test_data // batch_size)
for batch_index in range(num_batches):
start_index, end_index = batch_index * batch_size, (batch_index + 1) * batch_size
y_pred = model(data_loader.test_data[start_index: end_index])
sparse_categorical_accuracy.update_state(y_true=data_loader.test_label[start_index: end_index], y_pred=y_pred)
print("test accuracy: %f" % sparse_categorical_accuracy.result())
(2)导入模型并使用真实图像预测
import tensorflow as tf
import numpy as np
from PIL import Image
from PIL import ImageEnhance
import PIL.ImageOps as ImageOps
model = tf.saved_model.load("saved/mnist")
img = Image.open("./image2.jpeg") # 读取图片
img = ImageEnhance.Contrast(img).enhance(factor=10) # 铅笔书写和光线问题:需进行图片增强,调整对比度,不调整会预测为3。
img = img.convert("L") # 灰度处理
img = img.resize((28, 28)) # 调整图片大小
img = ImageOps.invert(img) # 反转颜色,需要黑底白字的图片
img = np.expand_dims(np.asarray(img) / 255.0, axis=-1) # 归一化
model = tf.saved_model.load("saved/mnist") # 加载模型
predict_y = model([img]) # 预测结果
print(np.argmax(predict_y[0])) # 获取最大值作为预测结果值
5 参考资料