赞
踩
2019 年初,TensorFlow 官方推出了 2.0 预览版本,也意味着 TensorFlow 即将从 1.x 过度到 2.x 时代。
根据 TensorFlow 官方介绍内容 显示,2.0 版本将专注于简洁性和易用性的改善,主要升级方向包括:
接下来,加载 TensorFlow 并查看版本号,看是否已经为 2.x。
In [ ]:
import tensorflow as tf
tf.__version__
TensorFlow 2 带来的最大改变之一是将 1.x 的 Graph Execution(图与会话机制)更改为 Eager Execution(动态图机制)。在 1.x 版本中,低级别 TensorFlow API 首先需要定义数据流图,然后再创建 TensorFlow 会话,这一点在 2.0 中被完全舍弃。
TensorFlow 2 中的 Eager Execution 是一种命令式编程环境,可立即评估操作,无需构建图:操作会返回具体的值,而不是构建以后再运行的计算图。实际上,Eager Execution 在 1.x 的后期版本中也存在,但需要单独执行 tf.enable_eager_execution()
进行手动启用。不过,2.0 版本的 TensorFlow 默认采用了 Eager Execution,无法关闭并回到 1.x 的 Graph Execution 模式中。
下面,我们来演示 Eager Execution 带来的变化。
1.x 版本中,如果我们新建一个张量 tf.Variable([[1, 2], [3, 4]])
并执行输出,那么只能看到这个张量的形状和属性,并不能直接输出其数值。结果如下:
<tf.Variable 'Variable:0' shape=(2, 2) dtype=int32_ref>
如今,Eager Execution 模式下则可以直接输出张量的数值了,并以 NumPy 数组方式呈现。
c = tf.Variable([[1, 2], [3, 4]])
c
你还可以直接通过 .numpy()
输出张量的 NumPy 数组。Eager Execution 适合与 NumPy 一起使用。NumPy 操作接受 tf.Tensor
参数。TensorFlow 数学运算将 Python 对象和 NumPy 数组转换为 tf.Tensor
对象。tf.Tensor.numpy
方法返回对象的值作为 NumPy ndarray。
c.numpy()
Eager Execution 带来的好处是不再需要手动管理图和会话。例如,现在使用示例张量进行数学计算,可以像 Python 一样直接相加。
c + c # 加法计算
而在 1.x 版本中,我们需要初始化全局变量 → 建立会话 → 执行计算,最终才能打印出张量的运算结果。
init_op = tf.global_variables_initializer() # 初始化全局变量
with tf.Session() as sess: # 启动会话
sess.run(init_op)
print(sess.run(c + c)) # 执行计算
Eager Execution 带来的好处显而易见,其进一步降低了 TensorFlow 的入门门槛。之前,因为图与会话的模式,让很多人在入门时都很纳闷。除此之外,得益于自动微分的使用,在 Eager Execution 期间,可以使用 tf.GradientTape
这类跟踪操作以便稍后计算梯度。
In [1]:
w = tf.Variable([[1.0]]) # 新建张量
with tf.GradientTape() as tape: # 追踪梯度
loss = w * w
grad = tape.gradient(loss, w) # 计算梯度
grad
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-1e9ac7891209> in <module>
----> 1 w = tf.Variable([[1.0]]) # 新建张量
2
3 with tf.GradientTape() as tape: # 追踪梯度
4 loss = w * w
5
NameError: name 'tf' is not defined
`tf.GradientTape` 会像磁带一样记录下计算图中的梯度信息,然后使用 `.gradient` 即可回溯计算出任意梯度,这对于使用 TensorFlow 低阶 API 构建神经网络时更新参数非常重要。
Markdown Code
`tf.GradientTape` 会像磁带一样记录下计算图中的梯度信息,然后使用 `.gradient` 即可回溯计算出任意梯度,这对于使用 TensorFlow 低阶 API 构建神经网络时更新参数非常重要。
Eager Execution 的好处很多,但带来的问题也是很明显的,尤其是对于已经熟练使用 TensorFlow 的工程师而言简直是噩梦。
如今,TensorFlow 的默认执行模式为 Eager Execution,这就意味着之前基于 Graph Execution 构建的代码将完全无法使用,因为 2.0 中已经没有了相应的 API。例如,先前构建神经网络计算图时,都习惯于使用 tf.placeholder
占位符张量,等最终执行时再传入数据。Eager Execution 模式下,tf.placeholder
已无存在必要,所以此 API 已被移除。
所以,随着 TensorFlow 2 默认引入 Eager Execution 机制,也就意味着原 1.x 低阶 API 构建图的方法后续已无法使用。
TensorFlow 1.x 中,我们可以通过 tf.layers
高阶层封装开快速搭建神经网络。如果,2.0 已完全移除了 tf.layers
模块,转而引入了 tf.keras
。
如果你熟悉 Keras 的使用,那么 tf.keras
用起来就得心应手了,因为其基本和单独发行版本一致,子模块结构也几乎完全一样。除此之外,原 tf.contrib
也已经在 2.0 版本中被移除。
低阶 API 实现,实际上就是利用 Eager Execution 机制来完成。实验首先初始化一组随机数据样本,并添加噪声,然后将其可视化出来。
低阶 API 实现,实际上就是利用 Eager Execution 机制来完成。实验首先初始化一组随机数据样本,并添加噪声,然后将其可视化出来。
import matplotlib.pyplot as plt
import tensorflow as tf
%matplotlib inline
TRUE_W = 3.0
TRUE_b = 2.0
NUM_SAMPLES = 100
# 初始化随机数据
X = tf.random.normal(shape=[NUM_SAMPLES, 1]).numpy()
noise = tf.random.normal(shape=[NUM_SAMPLES, 1]).numpy()
y = X * TRUE_W + TRUE_b + noise # 添加噪声
plt.scatter(X, y)
接下来,我们定义一元线性回归模型。
f
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。