深度学习中的多层感知器与模型优化

深度学习的高级模型中,多层感知器(MLP)通常用于简单的回归问题。然而,MLP在处理具有序列和多维数据的模式时并不是理想的选择。MLP试图记住序列数据中的模式,因此需要大量的参数来处理多维数据。对于序列数据,递归神经网络(RNN)因其能够发现历史数据上的依赖关系而备受青睐,这对于预测非常有用。对于图像和视频等数据,卷积神经网络(CNN)在提取特征图进行分类、分割等任务上表现出色。在某些情况下,一维卷积(Conv1D/1D)的CNN也用于具有序列输入数据的网络。但在大多数深度学习模型中,MLP、CNN和RNN被结合起来以充分利用各自的优势。

MLP、CNN和RNN并不万能……其成功很大程度上来自于明确目标和正确选择一些参数,如损失函数、优化器和正则化器。还拥有来自训练环境之外的数据。正则化器的作用是确保训练出的模型能够泛化到新数据上。

目录

  • MNIST数据集
  • 构建模型
  • 正则化
  • 激活函数
  • 模型可视化优化
  • 评估
  • 常见问题解答

MNIST数据集

假设目标是创建一个网络来识别基于手写数字的数字。例如,当网络输入的是数字8的图像时,相应的预测也必须是8。这是神经网络的基本分类任务。MNIST数据集被认为是深度学习数据集的“Hello World”。在剖析MLP模型之前,了解MNIST数据集至关重要。它被用来解释和验证许多深度学习理论,因为它包含的70000张图像虽小但信息量足够丰富;MNIST包含从0到9的数字。它有一个包含60000张图像的训练集和10000张测试图像,被分类为类别。

import numpy as np from tensorflow.keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data()

mnist.load_data()方法非常方便,无需加载全部70000张图像及其标签。在进入多层感知器分类器之前,必须记住,尽管MNIST数据由二维张量组成,但它们必须根据输入层的类型进行重塑。一个3×3的灰度图像被重塑为MLP、CNN和RNN输入层:

num_labels = len(np.unique(y_train)) print("总标签数: {}".format(num_labels)) print("标签: {}".format(np.unique(y_train)))

这种表示方式不适合用于生成概率的预测层。最合适的格式是独热编码(one-hot),一个10维向量,除了类别索引外,所有值都是0。例如,如果标签是4,等效向量是[0,0,0,0, 1, 0,0,0,0,0]。在深度学习中,数据存储在张量中。张量一词适用于标量张量(0D张量)、向量(1D张量)、矩阵(二维张量)和多维张量。

from tensorflow.keras.utils import to_categorical y_train = to_categorical(y_train) y_test = to_categorical(y_test)

模型是一个MLP,因此输入必须是1D张量。因此,x_train和x_test必须被转换为[60,000, 2828]和[10,000, 2828],在numpy中,-1的大小意味着允许库计算正确的维度。在x_train的情况下,它是60,000。

image_size = x_train.shape[1] input_size = image_size * image_size print("x_train: {}".format(x_train.shape)) print("x_test: {}".format(x_test.shape)) x_train = np.reshape(x_train, [-1, input_size]) x_train = x_train.astype('float32') / 255 x_test = np.reshape(x_test, [-1, input_size]) x_test = x_test.astype('float32') / 255 print("x_train: {}".format(x_train.shape)) print("x_test: {}".format(x_test.shape))

输出:

x_train: (60000, 28, 28)

x_test: (10000, 28, 28)

x_train: (60000, 784)

x_test: (10000, 784)

构建模型

模型由三个多层感知器层组成,位于密集层中。第一层和第二层是相同的,后面跟着一个ReLU和Dropout激活函数。

from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Activation, Dropout # 参数 batch_size = 128 hidden_units = 256 dropout = 0.45 # MLP模型,带有ReLU和Dropout model = Sequential() model.add(Dense(hidden_units, input_dim=input_size)) model.add(Activation('relu')) model.add(Dropout(dropout)) model.add(Dense(hidden_units)) model.add(Activation('relu')) model.add(Dropout(dropout)) model.add(Dense(num_labels))

正则化

神经网络倾向于记住其训练数据,特别是如果它包含足够的容量。在这种情况下,当网络受到测试数据的挑战时,会灾难性地失败。这是网络无法泛化的经典案例(过拟合/欠拟合)。为了避免这种趋势,模型使用了Dropout这样的调节层。Dropout的理念很简单。给定一个丢弃率(在模型中,设置为0.45),该层随机移除这个比例的单元。例如,如果第一层有256个单元,在应用Dropout(0.45)之后,只有(1 - 0.45) * 255 = 140个单元将参与下一层。Dropout使神经网络对不可预见的输入数据更加健壮,因为网络被训练即使在某些单元缺失的情况下也能正确预测。Dropout只在训练期间参与。

激活函数

输出层有10个单元,后面跟着一个softmax激活函数。这10个单元对应于10个可能的标签、类别或类别。softmax激活的输出可以按照以下数学方程表达:

model.add(Activation('softmax')) model.summary()

输出:

模型:“sequential”

Layer (type) Output Shape Param #

================================================================

dense (Dense) (None, 256) 200960

________________________________________________________________

activation (Activation) (None, 256) 0

________________________________________________________________

dropout (Dropout) (None, 256) 0

________________________________________________________________

dense_1 (Dense) (None, 256) 65792

________________________________________________________________

activation_1 (Activation) (None, 256) 0

________________________________________________________________

dropout_1 (Dropout) (None, 256) 0

________________________________________________________________

dense_2 (Dense) (None, 10) 2570

________________________________________________________________

activation_2 (Activation) (None, 10) 0

================================================================

Total params: 269,322

Trainable params: 269,322

Non-trainable params: 0

________________________________________________________________

模型可视化优化

优化的目的是最小化损失函数。如果损失降低到可接受的水平,模型间接地学会了将输入映射到输出的函数。性能指标用于确定模型是否已经学会了。

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

Categorical_crossentropy用于独热编码。准确度是分类任务的好指标。Adam是一个优化算法,可以用作经典的随机梯度下降过程的替代品。

鉴于训练集,选择了损失函数、优化器和正则化器,可以开始训练模型。

model.fit(x_train, y_train, epochs=20, batch_size=batch_size)

输出:

Epoch 1/20

469/469 [==============================] - 1s 3ms/step - loss: 0.4230 - accuracy: 0.8690

...

Epoch 20/20

469/469 [==============================] - 2s 4ms/step - loss: 0.0515 - accuracy: 0.9835

此时,MNIST数字分类模型已经完成。性能评估将是确定训练出的模型是否会呈现次优解决方案的下一步。

_, acc = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=0) print("准确度: %.1f%%" % (100.0 * acc))

输出:

准确度:98.4%

Q1. 简单术语中MLP是什么?

A. 简单术语中,MLP或多层感知器是一种旨在学习复杂模式和关系的人工神经网络,模仿人脑功能。

Q2. 多层感知器的理论是什么?

A.多层感知器的理论涉及相互连接的人工神经元层,每一层处理信息并有助于网络理解数据中的复杂模式。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485