教程 | TensorFlow 1.11 教程 —— 研究和实验 —— Eager execution(9.15 ver.)

更新至 2018-9-15 版本

译自:TensorFlow 官方教程

TensorFlow 的 Eager Execution 是一种命令式编程环境,可立即评估操作,无需构建图:操作会返回具体的值,而不是构建以后再运行的计算图。可以编写自定义层、前向传播以及使用自动微分训练循环。

Eager execution 基础

这是使用 TensorFlow 的入门教程,它包括:

  • 导入需要的包
  • 创建和使用张量
  • 使用 GPU 加速
  • 数据集

导入 TensorFlow

首先,导入 tensorflow 模块并启用 eager execution。Eager execution 可以使 TensorFlow 的前端具有更强的交互性,具体细节我们将在稍后讨论。

import tensorflow as tf

tf.enable_eager_execution()

张量(Tensor)

张量是一个多维数组。与 NumPy ndarray 对象类似,Tensor 对象具有数据类型和形状。此外,张量可以驻留在加速器(如GPU)内存中。TensorFlow 提供了一个可以生成和使用张量的操作库。这些操作自动转换原始的 Python 类型。例如:

print(tf.add(1, 2))
print(tf.add([1, 2], [3, 4]))
print(tf.square(5))
print(tf.reduce_sum([1, 2, 3]))
print(tf.encode_base64("hello world"))

# 支持操作符重载
print(tf.square(2) + tf.square(3))
tf.Tensor(3, shape=(), dtype=int32)
tf.Tensor([4 6], shape=(2,), dtype=int32)
tf.Tensor(25, shape=(), dtype=int32)
tf.Tensor(6, shape=(), dtype=int32)
tf.Tensor(b'aGVsbG8gd29ybGQ', shape=(), dtype=string)
tf.Tensor(13, shape=(), dtype=int32)

每个张量都有形状和数据类型

x = tf.matmul([[1]], [[2, 3]])
print(x.shape)
print(x.dtype)
(1, 2)
<dtype: 'int32'>

NumPy 数组和 TensorFlow 张量之间最明显的区别是:

  1. 张量支持加速器存储器(如GPU, TPU)。
  2. 张量是不可变的。

NumPy 兼容性

TensorFlow 张量与 Numpy 数组之间的转换非常简单:

  • TensorFlow 操作会自动将 NumPy 数组转换成张量。
  • NumPy 操作会自动将张量转换成 NumPy 数组。

通过在张量上调用 .numpy() 方法可以显式地将其转换为 NumPy 数组。这些转换通常不需要太多的计算资源,因为如果可能的话,数组和张量共享底层内存表示。

但是,共享底层表示并不总是可能的,因为张量可能驻留在 GPU 内存中,而 NumPy 数组总是由主机内存支持,因此转换将涉及从 GPU 到主机内存的副本拷贝。

import numpy as np

ndarray = np.ones([3, 3])

print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.multiply(ndarray, 42)
print(tensor)


print("And NumPy operations convert Tensors to numpy arrays automatically")
print(np.add(tensor, 1))

print("The .numpy() method explicitly converts a Tensor to a numpy array")
print(tensor.numpy())
TensorFlow operations convert numpy arrays to Tensors automatically
tf.Tensor(
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]], shape=(3, 3), dtype=float64)
And NumPy operations convert Tensors to numpy arrays automatically
[[43. 43. 43.]
 [43. 43. 43.]
 [43. 43. 43.]]
The .numpy() method explicitly converts a Tensor to a numpy array
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]]

GPU 加速

通过使用 GPU 进行计算,可以加速许多 TensorFlow 操作。在没有任何注释的情况下,TensorFlow 将自动决定是否使用 GPU 或 CPU 进行操作(如果需要的话,将会在 CPU 和 GPU 内存之间复制张量)。由操作产生的张量通常由执行操作的设备的内存支持。例如:

x = tf.random_uniform([3, 3])

print("Is there a GPU available: "),
print(tf.test.is_gpu_available())

print("Is the Tensor on GPU #0:  "),
print(x.device.endswith('GPU:0'))
Is there a GPU available: 
True
Is the Tensor on GPU #0:  
True

设备名称

Tensor.device 属性提供了容纳张量内容的设备的完全限定字符串名称。这个名称编码了许多细节,例如正在执行这个程序的主机的网络地址的标识符,以及该主机中的设备。对于 TensorFlow 程序的分布式执行来说,这是必需的,但是我们现在先跳过它。如果张量放在主机上的第 N 个张量上,字符串将以 GPU:<N> 结束。

显式设备安置(placement)

TensorFlow 中的术语“安置”指的是如何将单个操作分配(放置在)一个设备上执行。如上所述,当没有提供明确的信息时,TensorFlow 自动决定用哪个设备执行操作,并在需要时将张量复制到该设备。但是,可以使用 tf.device 上下文管理器显式地将 TensorFlow 操作放置在特定的设备上。例如:

def time_matmul(x):
  %timeit tf.matmul(x, x)  # 该语句在 notebook 中可用

# 强制在 CPU 上执行
print("On CPU:")
with tf.device("CPU:0"):
  x = tf.random_uniform([1000, 1000])
  assert x.device.endswith("CPU:0")
  time_matmul(x)

# 如果可行,将强制在 GPU #0 上执行
if tf.test.is_gpu_available():
  with tf.device("GPU:0"): # 或者 GPU:1 使用第 2 个 GPU, GPU:2 使用第三个 GPU 等
    x = tf.random_uniform([1000, 1000])
    assert x.device.endswith("GPU:0")
    time_matmul(x)
On CPU:
7.45 ms ± 149 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

数据集

本节演示使用 tf.data.Dataset API 来构建管道,将数据输入模型,步骤包括:

  • 创建一个 Dataset
  • 启用 eager execution 的情况下,在 Dataset 上进行迭代。

我们建议使用 Datasets API 从简单的、可重用的片段开始构建,这些片段将为你的模型的训练或评估循环提供支持。

如果您熟悉 TensorFlow 图形,那么在启用 eager execution 时,构造 Dataset 对象的 API 完全相同,但是遍历数据集元素的过程稍微简单一些。你可以在 tf.data.Dataset 上使用 Python 直接迭代,不需要显式创建 tf.data.Iterator 对象。因此,当启用了 eager execution 时,在 TensorFlow 指南 中关于迭代器的讨论就不相关了。

创建一个源 Dataset

使用 Dataset.from_tensorsDataset.from_tensor_slices 等工厂函数或者使用 TextLineDataset 以及 TFRecordDataset 对象从文件中读取数据来创建源数据集。参阅 TensorFlow 指南 获取更多信息。

ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])

# 创建 CSV 文件
import tempfile
_, filename = tempfile.mkstemp()

with open(filename, 'w') as f:
  f.write("""Line 1
Line 2
Line 3
  """)

ds_file = tf.data.TextLineDataset(filename)

应用变换

使用 mapbatchshuffle 等变换函数对数据集进行变换。参阅 tf.data.Dataset API 文档获取详细信息。

ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)

ds_file = ds_file.batch(2)

迭代

当启用 eager execution 时,Dataset 对象支持迭代。如果你熟悉在 TensorFlow 图中使用 Dataset,请注意,不需要调用 Dataset.make_one_shot_iterator()get_next()

print('Elements of ds_tensors:')
for x in ds_tensors:
  print(x)

print('\nElements in ds_file:')
for x in ds_file:
  print(x)
Elements of ds_tensors:
tf.Tensor([4 1], shape=(2,), dtype=int32)
tf.Tensor([16 25], shape=(2,), dtype=int32)
tf.Tensor([36  9], shape=(2,), dtype=int32)

Elements in ds_file:
tf.Tensor([b'Line 1' b'Line 2'], shape=(2,), dtype=string)
tf.Tensor([b'Line 3' b'  '], shape=(2,), dtype=string)

猜你喜欢

转载自blog.csdn.net/qq_20084101/article/details/82469417
今日推荐