TensorFlow 2 入门指南
1. TensorFlow 2 中的张量运算
在 TensorFlow 2 中,我们可以定义不同形状的常量张量并进行运算。例如,有两个常量张量 m1 和 m2 ,代码如下:
import tensorflow as tf
m1 = tf.constant([[3., 3.]])
m2 = tf.constant([[2.], [2.]])
p1 = tf.matmul(m1, m2)
print("m1:", m1)
print("m2:", m2)
print("p1:", p1)
这里, m1 的形状是 1x2 , m2 的形状是 2x1 ,它们的乘积 p1 的形状是 (1, 1) 。输出结果如下:
m1: tf.Tensor([[3. 3.]], shape=(1, 2), dtype=float32)
m2: tf.Tensor(
[[2.]
[2.]], shape=(2, 1), dtype=float32)
p1: tf.Tensor([[12.]], shape=(1, 1), dtype=float32)
2. 将 Python 数组转换为 TF 张量
我们可以使用 tf.convert_to_tensor 函数将 Python 数组(使用 NumPy 数组表示)转换为 TF 张量,示例代码如下:
import tensorflow as tf
import numpy as np
x1 = np.array([[1., 2.], [3., 4.]])
x2 = tf.convert_to_tensor(value=x1, dtype=tf.float32)
print('x1:', x1)
print('x2:', x2)
输出结果为:
x1: [[1. 2.]
[3. 4.]]
x2: tf.Tensor(
[[1. 2.]
[3. 4.]], shape=(2, 2), dtype=float32)
3. TF 2 中的类型冲突问题
当我们尝试组合不兼容的张量时,会出现类型冲突问题。以下代码展示了这种情况:
import tensorflow as tf
try:
tf.constant(1) + tf.constant(1.0)
except tf.errors.InvalidArgumentError as ex:
print(ex)
try:
tf.constant(1.0, dtype=tf.float64) + tf.constant(1.0)
except tf.errors.InvalidArgumentError as ex:
print(ex)
输出结果显示了类型不匹配的错误信息:
cannot compute Add as input #1(zero-based) was expected to be
a int32 tensor but is a float tensor [Op:Add] name: add/
cannot compute Add as input #1(zero-based) was expected to be
a double tensor but is a float tensor [Op:Add] name: add/
4. TF 2 中的微分和 tf.GradientTape
自动微分(即计算导数)对于实现机器学习算法(如训练各种神经网络的反向传播算法)非常有用。在即时执行模式下,TF 2 的上下文管理器 tf.GradientTape 用于跟踪计算梯度的操作。
tf.GradientTape 会在“磁带”上记录所有前向传播操作,然后通过“回放”磁带计算梯度,并在单次梯度计算后丢弃磁带。因此,一个 tf.GradientTape 只能计算一次梯度,后续调用会抛出运行时错误。需要注意的是, tf.GradientTape 上下文管理器仅在即时模式下存在。
4.1 简单的 tf.GradientTape 示例
import tensorflow as tf
w = tf.Variable([[1.0]])
with tf.GradientTape() as tape:
loss = w * w
grad = tape.gradient(loss, w)
print("grad:", grad)
这里,如果定义函数 z = w*w ,其导数为 2*w ,当 w 为 1.0 时,结果为 2.0 。输出结果如下:
grad: tf.Tensor([[2.]], shape=(1, 1), dtype=float32)
4.2 使用 watch() 方法的 tf.GradientTape 示例
import tensorflow as tf
x = tf.constant(3.0)
with tf.GradientTape() as g:
g.watch(x)
y = 4 * x * x
dy_dx = g.gradient(y, x)
print("dy_dx:", dy_dx)
对于函数 y = 4*x*x ,其导数为 8*x ,当 x 为 3.0 时,结果为 24.0 。输出结果如下:
dy_dx: tf.Tensor(24.0, shape=(), dtype=float32)
4.3 使用嵌套循环的 tf.GradientTape 示例
import tensorflow as tf
x = tf.constant(4.0)
with tf.GradientTape() as t1:
with tf.GradientTape() as t2:
t1.watch(x)
t2.watch(x)
z = x * x * x
dz_dx = t2.gradient(z, x)
d2z_dx2 = t1.gradient(dz_dx, x)
print("First dz_dx: ", dz_dx)
print("Second d2z_dx2:", d2z_dx2)
x = tf.Variable(4.0)
with tf.GradientTape() as t1:
with tf.GradientTape() as t2:
z = x * x * x
dz_dx = t2.gradient(z, x)
d2z_dx2 = t1.gradient(dz_dx, x)
print("First dz_dx: ", dz_dx)
print("Second d2z_dx2:", d2z_dx2)
对于函数 z = x*x*x ,其一阶导数 z' = 3*x*x ,二阶导数 z'' = 6*x 。当 x 为 4.0 时, z 为 64.0 , z' 为 48.0 , z'' 为 24.0 。输出结果如下:
First dz_dx: tf.Tensor(48.0, shape=(), dtype=float32)
Second d2z_dx2: tf.Tensor(24.0, shape=(), dtype=float32)
First dz_dx: tf.Tensor(48.0, shape=(), dtype=float32)
Second d2z_dx2: tf.Tensor(24.0, shape=(), dtype=float32)
4.4 其他张量的 tf.GradientTape 示例
import tensorflow as tf
x = tf.ones((3, 3))
with tf.GradientTape() as t:
t.watch(x)
y = tf.reduce_sum(x)
print("y:", y)
z = tf.multiply(y, y)
print("z:", z)
z = tf.multiply(z, y)
print("z:", z)
dz_dy = t.gradient(z, y)
print("dz_dy:", dz_dy)
这里, y 是 3x3 张量 x 所有元素的和,即 9 。 z = y*y*y ,其导数 z' = 3*y*y ,当 y 为 9 时, z' 为 243 。输出结果如下:
y: tf.Tensor(9.0, shape=(), dtype=float32)
z: tf.Tensor(81.0, shape=(), dtype=float32)
z: tf.Tensor(729.0, shape=(), dtype=float32)
dz_dy: tf.Tensor(243.0, shape=(), dtype=float32)
4.5 持久梯度磁带示例
import tensorflow as tf
x = tf.ones((3, 3))
with tf.GradientTape(persistent=True) as t:
t.watch(x)
y = tf.reduce_sum(x)
print("y:", y)
w = tf.multiply(y, y)
print("w:", w)
z = tf.multiply(y, y)
print("z:", z)
z = tf.multiply(z, y)
print("z:", z)
dz_dy = t.gradient(z, y)
print("dz_dy:", dz_dy)
dw_dy = t.gradient(w, y)
print("dw_dy:", dw_dy)
w = y*y ,其导数 w' = 2*y ,当 y 为 9.0 时, w 为 81 , w' 为 18 。输出结果如下:
y: tf.Tensor(9.0, shape=(), dtype=float32)
w: tf.Tensor(81.0, shape=(), dtype=float32)
z: tf.Tensor(81.0, shape=(), dtype=float32)
z: tf.Tensor(729.0, shape=(), dtype=float32)
dz_dy: tf.Tensor(243.0, shape=(), dtype=float32)
dw_dy: tf.Tensor(18.0, shape=(), dtype=float32)
5. Trax 深度学习库
Trax 是由 Google Brain 团队维护的深度学习库,“专注于清晰的代码和速度”。其文档地址为: https://trax.readthedocs.io/en/latest/ 。
Trax 与 Keras 类似,可以处理 Jax 和 TF-NumPy 等资源,并且 Trax 模型可以轻松转换为基于 Keras 的模型。Trax 代码示例可在以下 Github 仓库中找到: https://github.com/Sirsirious/trax_start/blob/colabs/TraxStart.ipynb 。
Trax 提供了预定义的层,如 LSTM 单元、密集层等。此外,还可以通过两种方式定义自定义层:
- 继承现有层。
- 为 trax.layers.PureLayer 提供一个函数,示例如下:
trax.layers.PureLayer(forward_fn = your_function_here)
指定自定义函数后,可将其作为一层添加到神经网络中。Trax 还支持各种 TensorFlow 实用工具,如 TensorFlow Datasets。例如,以下代码片段可下载 IMDB 数据集:
import trax.data as data
imdb = data.TFDS('imdb_reviews', keys=('text', 'label'), train=True)
6. Google Colaboratory
根据硬件不同,基于 GPU 的 TF 2 代码比基于 CPU 的 TF 2 代码快达 15 倍。但优质 GPU 的成本是一个重要因素,且 NVIDIA 提供的消费级 GPU 未针对多 GPU 支持进行优化(TF 2 支持多 GPU)。
Google Colaboratory 是一个经济实惠的替代方案,它提供免费的 GPU 和 TPU 支持,并且作为 Jupyter 笔记本环境运行。它在云端执行代码,无需配置,可通过以下链接访问: https://colab.research.google.com/notebooks/welcome.ipynb 。
这个 Jupyter 笔记本适合训练简单模型和快速测试想法。它便于上传本地文件、在 Jupyter 笔记本中安装软件,甚至可将其连接到本地机器上的 Jupyter 运行时。
Google Colaboratory 支持的一些功能包括:
- 使用 GPU 执行 TF 2 代码。
- 使用 Matplotlib 进行可视化。
- 通过“文件 > 保存副本到 GitHub”将笔记本保存到 GitHub。
此外,还可以通过在以下 URL 中添加路径来加载 GitHub 上的任何 Jupyter 笔记本: colab.research.google.com/github/ 。
需要注意的是,在 Google Colaboratory 中安装的任何软件仅在当前会话中可用,退出会话后需要重新安装。例如,安装 TFLearn 的代码如下:
!pip3 install tflearn
另外,每天可以免费在 GPU 上执行代码长达 12 小时,这对于本地没有合适 GPU 的用户非常有用。可以使用以下命令在 Google Colaboratory 笔记本中启动 TensorBoard(需将指定目录替换为自己的位置):
%tensorboard --logdir /logs/images
7. 其他云平台
Google Cloud Platform (GCP) 是一个基于云的服务,可在云端训练 TF 2 代码。GCP 提供深度学习 DL 镜像(类似于 Amazon AMIs),相关文档和镜像链接如下: https://cloud.google.com/deep-learning-vm/docs 。
该链接提供了文档,以及基于不同技术(包括 TF 2 和 PyTorch)的 DL 镜像链接,有 GPU 和 CPU 版本。除了支持多个 Python 版本外,还可以在浏览器会话或命令行中工作。
在 Mac 笔记本上安装 GCloud SDK,可通过以下链接下载软件: https://cloud.google.com/sdk/docs/quickstart-macos 。如果从未使用过 Google 云,还将获得价值 300 美元的信用额度(为期一年)。
8. TF2 和 tf.data.Dataset
TF 2 的 tf.data.Dataset 命名空间及其类支持一组丰富的运算符,用于处理非常大的数据集(即无法全部加载到内存中的数据集)。可以通过“方法链”调用所谓的惰性运算符(如 filter() 和 map() )从数据集中提取所需的数据子集。此外,还会涉及 TF 2 估计器(在 tf.estimator 命名空间中)和 TF 2 层(在 tf.keras.layers 命名空间中)。
这里的“数据集”指的是 tf.data.Dataset 命名空间中的 TF 2 类,它作为实际数据的“包装器”,实际数据可以是 CSV 文件或其他数据源。本部分不涵盖 TF 2 内置的“纯”数据数据集(如 MNIST、CIFAR 和 IRIS),除非它们是涉及 TF 2 惰性运算符的代码示例的一部分。
如果熟悉 lambda 表达式和函数式响应式编程,本部分内容会很容易理解。实际上,如果已经有 RxJS、RxAndroid、RxJava 或其他涉及惰性执行的环境中使用 Observables 的经验,代码示例将非常直观。本部分还会简要介绍 TF 2 数据集和 lambda 表达式,以及一些简单的代码示例,同时会介绍与 TF 1.x tf.data.Datasets 配合使用的迭代器和 TF 2 生成器(即带有 @tf.function 装饰器的 Python 函数)。
以下是一个简单的流程图,展示了使用 tf.GradientTape 计算梯度的基本流程:
graph TD;
A[定义张量] --> B[创建 tf.GradientTape 上下文];
B --> C[记录前向传播操作];
C --> D[计算梯度];
D --> E[使用梯度进行后续操作];
表格:不同计算环境的特点对比
| 计算环境 | 优点 | 缺点 |
| ---- | ---- | ---- |
| CPU | 成本低,无需额外硬件 | 计算速度慢 |
| GPU | 计算速度快 | 硬件成本高,部分消费级 GPU 不支持多 GPU |
| Google Colaboratory | 免费提供 GPU 和 TPU 支持,无需配置 | 安装的软件仅在会话中有效,GPU 免费使用时间有限 |
| Google Cloud Platform (GCP) | 可在云端训练代码,提供多种 DL 镜像 | 需要一定的云服务使用知识和费用 |
TensorFlow 2 入门指南
9. tf.data.Dataset 详细介绍
9.1 惰性运算符的使用
在处理大规模数据集时, tf.data.Dataset 提供了许多惰性运算符,如 filter() 和 map() 。这些运算符通过“方法链”的方式工作,避免一次性将整个数据集加载到内存中。
例如,以下代码展示了如何使用 filter() 和 map() 从一个简单的数据集中提取偶数并将其加倍:
import tensorflow as tf
# 创建一个简单的数据集
dataset = tf.data.Dataset.range(10)
# 使用 filter() 过滤出偶数
filtered_dataset = dataset.filter(lambda x: x % 2 == 0)
# 使用 map() 将每个元素加倍
mapped_dataset = filtered_dataset.map(lambda x: x * 2)
# 遍历数据集并打印元素
for element in mapped_dataset:
print(element.numpy())
在这个例子中, filter() 函数过滤出了数据集中的偶数, map() 函数将每个偶数加倍。整个过程是惰性执行的,即只有在遍历数据集时才会实际执行这些操作。
9.2 迭代器和生成器
TF 1.x 中的 tf.data.Datasets 使用迭代器来遍历数据集。而在 TF 2 中,我们可以使用生成器(带有 @tf.function 装饰器的 Python 函数)来实现类似的功能。
以下是一个简单的生成器示例:
import tensorflow as tf
@tf.function
def data_generator():
for i in range(5):
yield tf.constant(i)
# 创建数据集
dataset = tf.data.Dataset.from_generator(
data_generator,
output_types=tf.int32
)
# 遍历数据集并打印元素
for element in dataset:
print(element.numpy())
在这个例子中, data_generator 是一个生成器函数,它使用 yield 关键字逐个生成数据。 tf.data.Dataset.from_generator() 函数将生成器转换为一个数据集。
10. TF 2 估计器(tf.estimator)
TF 2 中的 tf.estimator 命名空间提供了高级的机器学习模型接口,它封装了模型的训练、评估和预测过程。使用 tf.estimator 可以简化模型的开发流程。
以下是一个简单的线性回归模型示例:
import tensorflow as tf
import numpy as np
# 生成一些示例数据
x_train = np.array([1, 2, 3, 4, 5], dtype=np.float32)
y_train = np.array([2, 4, 6, 8, 10], dtype=np.float32)
# 定义特征列
feature_columns = [tf.feature_column.numeric_column("x", shape=[1])]
# 创建一个线性回归估计器
estimator = tf.estimator.LinearRegressor(feature_columns=feature_columns)
# 定义输入函数
def input_fn():
dataset = tf.data.Dataset.from_tensor_slices({"x": x_train, "y": y_train})
dataset = dataset.shuffle(100).repeat().batch(1)
return dataset
# 训练模型
estimator.train(input_fn=input_fn, steps=1000)
# 定义预测输入函数
def predict_input_fn():
dataset = tf.data.Dataset.from_tensor_slices({"x": [6]})
return dataset
# 进行预测
predictions = estimator.predict(input_fn=predict_input_fn)
for pred in predictions:
print(pred["predictions"][0])
在这个例子中,我们首先定义了特征列和线性回归估计器。然后,使用输入函数将数据转换为 tf.data.Dataset 对象,并进行训练。最后,使用预测输入函数进行预测。
11. TF 2 层(tf.keras.layers)
tf.keras.layers 命名空间提供了各种神经网络层,如密集层、卷积层、循环层等。这些层可以方便地构建神经网络模型。
以下是一个简单的全连接神经网络示例:
import tensorflow as tf
from tensorflow.keras import layers
# 创建一个简单的全连接神经网络模型
model = tf.keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(10,)),
layers.Dense(1)
])
# 编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
loss='mse',
metrics=['mae'])
# 生成一些示例数据
x_train = tf.random.normal((100, 10))
y_train = tf.random.normal((100, 1))
# 训练模型
model.fit(x_train, y_train, epochs=10, batch_size=32)
在这个例子中,我们使用 tf.keras.Sequential 构建了一个简单的全连接神经网络模型,包含一个具有 64 个神经元的隐藏层和一个输出层。然后,编译模型并使用示例数据进行训练。
12. 总结与建议
在使用 TensorFlow 2 进行深度学习开发时,我们可以根据不同的需求选择合适的工具和方法:
- 对于张量运算和微分计算, tf.GradientTape 是一个强大的工具,可以方便地计算梯度。
- 处理大规模数据集时, tf.data.Dataset 及其惰性运算符可以帮助我们高效地处理数据。
- tf.estimator 提供了高级的模型接口,适合快速开发和训练模型。
- tf.keras.layers 则为构建复杂的神经网络模型提供了丰富的层选项。
同时,Google Colaboratory 和 Google Cloud Platform (GCP) 等云平台为我们提供了方便的计算资源,可以根据实际情况选择使用。
以下是一个流程图,展示了使用 TensorFlow 2 进行模型开发的一般流程:
graph TD;
A[数据准备] --> B[模型构建];
B --> C[模型编译];
C --> D[模型训练];
D --> E[模型评估];
E --> F[模型预测];
表格:不同 TensorFlow 组件的适用场景
| 组件 | 适用场景 |
| ---- | ---- |
| tf.GradientTape | 自动微分计算,如神经网络的反向传播 |
| tf.data.Dataset | 处理大规模数据集,使用惰性运算符进行数据处理 |
| tf.estimator | 快速开发和训练机器学习模型 |
| tf.keras.layers | 构建复杂的神经网络模型 |
通过本文的介绍,相信你对 TensorFlow 2 有了更深入的了解,可以开始使用这些工具和技术进行自己的深度学习项目了。在实践中不断探索和尝试,你将能够更好地掌握 TensorFlow 2 的强大功能。
超级会员免费看
1104

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



