TensorFlow 2.x 深度学习实战指南
1. 常用的 Keras 层
在 TensorFlow 2.x 中,Keras 提供了许多预定义的层,这些层在构建神经网络时非常有用。以下是几种常用的层:
-
tf.keras.layers.Dense
:这是一个全连接层,层中的每个神经元都与相邻层的所有神经元相连,也被称为“常规密集连接神经网络层”。
-
tf.keras.layers.Flatten
:通常用于神经网络的起始位置,当特征数据集不是一维时,该层可以将数据展平为一维,以便后续层能够处理。例如,将一个 (n x n) 像素的图像输入到神经网络时,图像是二维的,插入
Flatten
层可以将训练数据集转换为一维。
-
tf.keras.layers.Normalization
:和
Flatten
层一样,通常作为神经网络的第一层,用于对输入数据进行归一化处理。在机器学习中,归一化是一种常见的做法,可以使数据更易于处理。
构建简单的神经网络
使用 Keras 构建一个简单的神经网络非常容易,只需要定义
tf.keras.Sequential()
并按顺序添加各种预定义的层即可。以下是一个示例:
import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(128, 128)),
tf.keras.layers.Dense(128),
tf.keras.layers.Dense(12)
])
这个模型表示一个两层的神经网络(没有隐藏层),它将二维张量(如 128x128 像素的图像)在第一层转换为一维,然后传递给由 128 个神经元组成的第一层,最后连接到由 12 个神经元组成的另一层,这 12 个神经元可能对应 12 个类别。
2. 模型编译
定义好模型后,需要对其进行编译。编译模型需要选择损失函数、优化器和评估指标:
-
损失函数(Loss function)
:用于衡量模型在训练阶段的准确性。
-
优化器(Optimizer)
:负责在训练阶段更新模型的参数。
-
评估指标(Metrics)
:用于监控模型训练(和测试)的进度。
这些元素在 Keras 模块中都已经提供,可以直接使用。编译模型可以使用
compile()
函数,示例如下:
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
在 TensorFlow 2.x 中,模型的构建和编译是高级操作,比以前的版本更加快速和便捷。
3. 模型训练和测试
模型编译完成后,就可以进行训练和测试了。训练和测试需要使用包含特征(描述研究对象的一系列变量)和标签(如所属类别)的数据集。数据集通常分为训练数据集和测试数据集,其中训练数据集要大得多。
具体步骤如下:
1. 将数据集划分为训练集和测试集。
2. 将每个特征细分为两个张量,最终得到四个张量:
-
train_features
-
train_labels
-
test_features
-
test_labels
3. 使用
fit()
函数进行模型训练:
model.fit(train_features, train_labels, epochs=100)
epochs
参数表示学习阶段的执行次数,在每个阶段,准确性指标应该有所提高,表明模型学习成功。
4. 使用
evaluate()
函数进行模型测试:
test_loss, test_acc = model.evaluate(test_features, test_labels, verbose=2)
该函数返回模型的损失和准确性。
以下是一个 mermaid 格式的流程图,展示了模型训练和测试的流程:
graph LR
A[数据集] --> B[划分训练集和测试集]
B --> C[转换为张量]
C --> D[train_features & train_labels]
C --> E[test_features & test_labels]
D --> F[模型训练 fit()]
E --> G[模型测试 evaluate()]
4. 预测阶段
最后一个阶段是让模型完成其设计目的,对未知解决方案的输入数据进行预测(例如,所属类别)。在这个阶段,通常会在模型末尾添加一个
Softmax
层,用于将最后一层的输出(logits)转换为概率值。不需要重新编译训练好的模型,可以直接在末尾添加该层来扩展模型。示例如下:
probability_model = tf.keras.Sequential([
model,
tf.keras.layers.Softmax()
])
predictions = probability_model.predict(samples_features)
predict()
函数返回一个包含所有预测结果的数组,可以使用
np.argmax()
函数获取预测的类别。
5. 实战示例 - 单层感知机(Single Layer Perceptron, SLP)
5.1 准备工作
在开始之前,需要打开一个新的 Jupyter Notebook 或重启内核,并导入必要的模块:
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
5.2 分析数据
使用一组分布在笛卡尔坐标轴上的 11 个点作为数据集,将其分为两个类别。坐标信息存储在
inputX
数组中,所属类别信息存储在
inputY
列表中。示例代码如下:
# Training set
inputX = np.array([[1., 3.], [1., 2.], [1., 1.5],
[1.5, 2.], [2., 3.], [2.5, 1.5],
[2., 1.], [3., 1.], [3., 2.],
[3.5, 1.], [3.5, 3.]])
inputY = [[1., 0.]] * 6 + [[0., 1.]] * 5
print(inputX)
print(inputY)
为了更直观地查看这些点的空间分布和所属类别,可以使用
matplotlib
进行绘图:
yc = [0] * 5 + [1] * 6
print(yc)
plt.scatter(inputX[:, 0], inputX[:, 1], c=yc, s=50, alpha=0.9)
plt.show()
5.3 构建和训练模型
将训练数组的值转换为张量,然后构建单层感知机模型:
train_features = tf.convert_to_tensor(inputX)
train_labels = tf.convert_to_tensor(inputY)
model = tf.keras.Sequential([
tf.keras.layers.Dense(2),
tf.keras.layers.Dense(2)
])
model.compile(optimizer='SGD',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
h = model.fit(train_features, train_labels, epochs=2000)
提取训练历史并绘制损失变化图:
acc_set = h.history['loss']
epoch_set = h.epoch
plt.plot(epoch_set[0::100], acc_set[0::100], 'o', label='Training phase')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend()
plt.show()
5.4 测试模型
定义测试数据并转换为张量,然后评估模型的准确性:
testX = np.array([[1., 2.25], [1.25, 3.],
[2, 2.5], [2.25, 2.75],
[2.5, 3.], [2., 0.9],
[2.5, 1.2], [3., 1.25],
[3., 1.5], [3.5, 2.],
[3.5, 2.5]])
testY = [[1., 0.]] * 5 + [[0., 1.]] * 6
test_features = tf.convert_to_tensor(testX)
test_labels = tf.convert_to_tensor(testY)
test_loss, test_acc = model.evaluate(test_features, test_labels, verbose=2)
5.5 进行预测
扩展模型并添加
Softmax
层,然后对大量未知类别的数据进行预测:
probability_model = tf.keras.Sequential([
model,
tf.keras.layers.Softmax()
])
exp_features = 3 * np.random.random((1000, 2))
predictions = probability_model.predict(exp_features)
# 查看单个点属于两个类别的概率
print(predictions[0])
# 查看单个点所属的类别
print(np.argmax(predictions[0]))
# 可视化预测结果
yc = predictions[:, 1]
plt.scatter(exp_features[:, 0], exp_features[:, 1], c=yc, s=50, alpha=1)
plt.show()
# 根据概率确定每个点所属的类别
yc = np.round(predictions[:, 1])
plt.scatter(exp_features[:, 0], exp_features[:, 1], c=yc, s=50, alpha=1)
plt.show()
6. 多层感知机(Multilayer Perceptron, MLP) - 单隐藏层
6.1 构建模型
多层感知机与单层感知机的区别在于它可以有一个或多个隐藏层。构建一个具有一个隐藏层(包含两个神经元)的 MLP 模型:
model = tf.keras.Sequential([
tf.keras.layers.Dense(2),
tf.keras.layers.Dense(2),
tf.keras.layers.Dense(2)
])
6.2 编译模型
对于 MLP 神经网络,选择
Adam
优化方法,损失函数和评估指标保持不变:
model.compile(optimizer='Adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
6.3 训练模型
使用与 SLP 模型相同的训练数据集进行训练:
h = model.fit(train_features, train_labels, epochs=2000)
6.4 可视化训练过程
提取训练历史并绘制损失变化图:
acc_set = h.history['loss']
epoch_set = h.epoch
plt.plot(epoch_set[0::50], acc_set[0::50], 'o', label='Training phase')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend()
plt.show()
以下是一个表格,对比 SLP 和 MLP 模型的相关信息:
| 模型类型 | 层数 | 优化器 | 训练数据集 | 损失函数 | 评估指标 |
| ---- | ---- | ---- | ---- | ---- | ---- |
| SLP | 2 | SGD | 相同 | BinaryCrossentropy | accuracy |
| MLP(单隐藏层) | 3 | Adam | 相同 | BinaryCrossentropy | accuracy |
7. 多层感知机(Multilayer Perceptron, MLP) - 双隐藏层
7.1 构建模型
构建一个具有两个隐藏层的 MLP 模型,每个隐藏层都包含一定数量的神经元。这里我们继续使用前面的示例,每个隐藏层设置为 2 个神经元:
model = tf.keras.Sequential([
tf.keras.layers.Dense(2),
tf.keras.layers.Dense(2),
tf.keras.layers.Dense(2),
tf.keras.layers.Dense(2)
])
7.2 编译模型
同样选择
Adam
优化方法,损失函数和评估指标保持不变:
model.compile(optimizer='Adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
7.3 训练模型
使用与前面相同的训练数据集进行训练:
h = model.fit(train_features, train_labels, epochs=2000)
7.4 可视化训练过程
提取训练历史并绘制损失变化图:
acc_set = h.history['loss']
epoch_set = h.epoch
plt.plot(epoch_set[0::50], acc_set[0::50], 'o', label='Training phase')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend()
plt.show()
以下是一个 mermaid 格式的流程图,展示了双隐藏层 MLP 模型的构建、编译、训练和可视化流程:
graph LR
A[构建模型] --> B[编译模型]
B --> C[训练模型]
C --> D[可视化训练过程]
以下是一个表格,对比 SLP、单隐藏层 MLP 和双隐藏层 MLP 模型的相关信息:
| 模型类型 | 层数 | 优化器 | 训练数据集 | 损失函数 | 评估指标 |
| ---- | ---- | ---- | ---- | ---- | ---- |
| SLP | 2 | SGD | 相同 | BinaryCrossentropy | accuracy |
| MLP(单隐藏层) | 3 | Adam | 相同 | BinaryCrossentropy | accuracy |
| MLP(双隐藏层) | 4 | Adam | 相同 | BinaryCrossentropy | accuracy |
8. 不同模型的总结与分析
8.1 模型复杂度与性能
从上述示例可以看出,随着模型层数的增加,模型的复杂度也在增加。SLP 模型结构最简单,只有两层;单隐藏层 MLP 模型增加了一个隐藏层,复杂度有所提升;双隐藏层 MLP 模型则更加复杂。
一般来说,更复杂的模型具有更强的表达能力,能够学习到更复杂的模式。但这也带来了一些问题,例如过拟合的风险增加。在实际应用中,需要根据数据集的特点和问题的复杂度来选择合适的模型。
8.2 训练时间与收敛速度
随着模型复杂度的增加,训练时间通常也会增加。因为更复杂的模型需要更多的参数来学习,训练过程中需要进行更多的计算。
同时,不同的优化器也会影响模型的收敛速度。在上述示例中,SLP 模型使用
SGD
优化器,MLP 模型使用
Adam
优化器。
Adam
优化器通常具有更快的收敛速度,能够在更短的时间内达到较好的性能。
8.3 预测准确性
在测试阶段,我们可以通过评估指标(如准确率)来比较不同模型的预测准确性。从示例结果来看,不同模型的准确率可能会有所不同。需要注意的是,准确率并不是衡量模型性能的唯一指标,还需要考虑其他因素,如召回率、F1 值等。
以下是一个列表,总结了不同模型的特点:
-
SLP 模型
:结构简单,训练速度快,但表达能力有限,适用于简单的分类问题。
-
单隐藏层 MLP 模型
:增加了一定的复杂度,能够学习到更复杂的模式,性能有所提升,但仍有一定的局限性。
-
双隐藏层 MLP 模型
:复杂度较高,表达能力强,但训练时间长,过拟合风险增加,需要谨慎使用。
9. 实际应用中的注意事项
9.1 数据预处理
在实际应用中,数据预处理非常重要。例如,使用
Flatten
层将多维数据转换为一维数据,使用
Normalization
层对数据进行归一化处理。这些操作可以提高模型的训练效率和性能。
9.2 模型选择
根据问题的复杂度和数据集的特点选择合适的模型。如果问题比较简单,可以选择 SLP 模型;如果问题比较复杂,可以考虑使用 MLP 模型,并根据需要调整隐藏层的数量和神经元的数量。
9.3 超参数调整
超参数(如学习率、批次大小、训练轮数等)的选择会影响模型的性能。需要通过实验来选择合适的超参数,以达到最佳的训练效果。
9.4 防止过拟合
过拟合是深度学习中常见的问题。可以通过增加训练数据、使用正则化方法(如 L1、L2 正则化)、早停策略等方法来防止过拟合。
以下是一个 mermaid 格式的流程图,展示了实际应用中构建和训练模型的注意事项流程:
graph LR
A[数据预处理] --> B[模型选择]
B --> C[超参数调整]
C --> D[防止过拟合]
10. 总结
本文详细介绍了使用 TensorFlow 2.x 进行深度学习的基本流程,包括常用的 Keras 层、模型编译、训练、测试和预测等步骤。通过实际示例,展示了如何构建和训练 SLP、单隐藏层 MLP 和双隐藏层 MLP 模型,并对不同模型的特点进行了分析。
在实际应用中,需要根据问题的复杂度和数据集的特点选择合适的模型,并注意数据预处理、超参数调整和防止过拟合等问题。希望本文能够帮助读者更好地理解和应用 TensorFlow 2.x 进行深度学习。
超级会员免费看
827

被折叠的 条评论
为什么被折叠?



