TensorFlow 于 2011 年以 Google 的内部封闭源代码项目 DisBelief 诞生。 DisBelief 是采用深度学习神经网络的机器学习系统。 该系统演变为 TensorFlow,并在 2015 年 11 月 9 日根据 Apache 2.0 开源许可证发布到开发人员社区。版本 1.0.0 于 2017 年 2 月 11 日出现。此后有许多版本发布。 合并了许多新功能。
在撰写本书时,最新版本是 TensorFlow 2.0.0 alpha 版本,该版本在 2019 年 3 月 6 日的 TensorFlow 开发峰会上宣布。
TensorFlow 的名字来源于张量。 张量是向量和矩阵到更高维度的一般化。 张量的等级是唯一指定该张量的每个元素所用的索引数。 标量(简单数字)是等级 0 的张量,向量是等级 1 的张量,矩阵是等级 2 的张量,三维数组是等级 3 的张量。张量具有数据类型和形状(张量中的所有数据项必须具有相同的类型)。 4 维张量的示例(即等级 4)是图像,其中维是例如batch
,height
,width
和color
通道内的示例:
image1 = tf.zeros([7, 28, 28, 3]) # example-within-batch by height by width by color
尽管 TensorFlow 通常可以用于许多数值计算领域,尤其是机器学习,但其主要研究和开发领域是深层神经网络(DNN)的应用,它已在语音和声音识别等不同领域使用,例如,在如今广泛使用的声控助手中; 基于文本的应用,例如语言翻译器; 图像识别,例如系外行星搜寻,癌症检测和诊断; 以及时间序列应用(例如推荐系统)。
在本章中,我们将讨论以下内容:
- 现代 TensorFlow 生态系统
- 安装 TensorFlow
- 急切操作
- 提供有用的 TensorFlow 操作
让我们讨论急切执行。 TensorFlow 的第一个化身包括构造由操作和张量组成的计算图,随后必须在 Google 所谓的会话中对其进行评估(这称为声明性编程)。 这仍然是编写 TensorFlow 程序的常用方法。 但是,急切执行的功能(以研究形式从版本 1.5 开始可用,并从版本 1.7 被烘焙到 TensorFlow 中)需要立即评估操作,结果是可以将张量像 NumPy 数组一样对待(这被称为命令式编程)。
谷歌表示,急切执行是研究和开发的首选方法,但计算图对于服务 TensorFlow 生产应用将是首选。
tf.data
是一种 API,可让您从更简单,可重复使用的部件中构建复杂的数据输入管道。 最高级别的抽象是Dataset
,它既包含张量的嵌套结构元素,又包含作用于这些元素的转换计划。 有以下几种类:
Dataset
包含来自至少一个二进制文件(FixedLengthRecordDataset
)的固定长度记录集Dataset
由至少一个 TFRecord 文件(TFRecordDataset
)中的记录组成Dataset
由记录组成,这些记录是至少一个文本文件(TFRecordDataset
)中的行- 还有一个类表示通过
Dataset
(tf.data.Iterator
)进行迭代的状态
让我们继续进行估计器,这是一个高级 API,可让您构建大大简化的机器学习程序。 估计员负责训练,评估,预测和导出服务。
TensorFlow.js 是 API 的集合,可让您使用底层 JavaScript 线性代数库或高层 API 来构建和训练模型。 因此,可以训练模型并在浏览器中运行它们。
TensorFlow Lite 是适用于移动和嵌入式设备的 TensorFlow 的轻量级版本。 它由运行时解释器和一组工具组成。 这个想法是您在功率更高的机器上训练模型,然后使用工具将模型转换为.tflite
格式。 然后将模型加载到您选择的设备中。 在撰写本文时,使用 C++ API 在 Android 和 iOS 上支持 TensorFlow Lite,并且具有适用于 Android 的 Java 包装器。 如果 Android 设备支持 Android 神经网络(ANN)API 进行硬件加速,则解释器将使用此 API,否则它将默认使用 CPU 执行。
TensorFlow Hub 是一个旨在促进机器学习模型的可重用模块的发布,发现和使用的库。 在这种情况下,模块是 TensorFlow 图的独立部分,包括其权重和其他资产。 该模块可以通过称为迁移学习的方法在不同任务中重用。 这个想法是您在大型数据集上训练模型,然后将适当的模块重新用于您的其他但相关的任务。 这种方法具有许多优点-您可以使用较小的数据集训练模型,可以提高泛化能力,并且可以大大加快训练速度。
例如,ImageNet 数据集以及许多不同的神经网络架构(例如inception_v3
)已非常成功地用于解决许多其他图像处理训练问题。
TensorFlow Extended(TFX)是基于 TensorFlow 的通用机器学习平台。 迄今为止,已开源的库包括 TensorFlow 转换,TensorFlow 模型分析和 TensorFlow 服务。
tf.keras
是用 Python 编写的高级神经网络 API,可与 TensorFlow(和其他各种张量工具)接口。 tf.k
eras
支持快速原型设计,并且用户友好,模块化且可扩展。 它支持卷积和循环网络,并将在 CPU 和 GPU 上运行。 Keras 是 TensorFlow 2 中开发的首选 API。
TensorBoard 是一套可视化工具,支持对 TensorFlow 程序的理解,调试和优化。 它与急切和图执行环境兼容。 您可以在训练期间使用 TensorBoard 可视化模型的各种指标。
TensorFlow 的一项最新开发(在撰写本文时仍处于实验形式)将 TensorFlow 直接集成到 Swift 编程语言中。 Swift 中的 TensorFlow 应用是使用命令性代码编写的,即命令急切地(在运行时)执行的代码。 Swift 编译器会自动将此源代码转换为一个 TensorFlow 图,然后在 CPU,GPU 和 TPU 上以 TensorFlow Sessions 的全部性能执行此编译后的代码。
在本书中,我们将重点介绍那些使用 Python 3.6 和 TensorFlow 2.0.0 alpha 版本启动和运行 TensorFlow 的 TensorFlow 工具。 特别是,我们将使用急切的执行而不是计算图,并且将尽可能利用tf.keras
的功能来构建网络,因为这是研究和实验的现代方法。
TensorFlow 的最佳编程支持是为 Python 提供的(尽管确实存在 Java,C 和 Go 的库,而其他语言的库正在积极开发中)。
Web 上有大量信息可用于为 Python 安装 TensorFlow。
Google 也建议在虚拟环境中安装 TensorFlow,这是一种标准做法,该环境将一组 API 和代码与其他 API 和代码以及系统范围的环境隔离开来。
TensorFlow 有两种不同的版本-一个用于在 CPU 上执行,另一个用于在 GPU 上执行。 最后,这需要安装数值库 CUDA 和 CuDNN。 Tensorflow 将在可能的情况下默认执行 GPU。 参见这里。
与其尝试重新发明轮子,不如跟随资源来创建虚拟环境和安装 TensorFlow。
总而言之,可能会为 Windows 7 或更高版本,Ubuntu Linux 16.04 或更高版本以及 macOS 10.12.6 或更高版本安装 TensorFlow。
有关虚拟环境的完整介绍,请参见这里。
Google 的官方文档中提供了有关安装 TensorFlow 所需的所有方面的非常详细的信息。
安装后,您可以从命令终端检查 TensorFlow 的安装。 这个页面有执行此操作,以及安装 TensorFlow 的夜间版本(其中包含所有最新更新)的说明。
我们将首先介绍如何导入 TensorFlow,然后介绍 TensorFlow 编码风格,以及如何进行一些基本的整理工作。 之后,我们将看一些基本的 TensorFlow 操作。 您可以为这些代码片段创建 Jupyter 笔记本,也可以使用自己喜欢的 IDE 创建源代码。 该代码在 GitHub 存储库中都可用。
导入 TensorFlow 很简单。 请注意几个系统检查:
import tensorflow as tf
print("TensorFlow version: {}".format(tf.__version__))
print("Eager execution is: {}".format(tf.executing_eagerly()))
print("Keras version: {}".format(tf.keras.__version__))
对于 Python 应用,Google 遵守 PEP8 标准约定。 特别是,他们将 CamelCase 用于类(例如hub.LatestModuleExporter
),将snake_case
用于函数,方法和属性(例如tf.math.squared_difference
)。 Google 还遵守《Google Python 风格指南》,该指南可在这个页面中找到。
急切执行是 TensorFlow 2 中的默认设置,因此不需要特殊设置。
以下代码可用于查找是否正在使用 CPU 或 GPU,如果它是 GPU,则该 GPU 是否为#0
。
我们建议键入代码,而不要使用复制和粘贴。 这样,您将对以下命令有所了解:
var = tf.Variable([3, 3])
if tf.test.is_gpu_available():
print('Running on GPU')
print('GPU #0?')
print(var.device.endswith('GPU:0'))
else:
print('Running on CPU')
声明 TensorFlow 急切变量的方法如下:
t0 = 24 # python variable
t1 = tf.Variable(42) # rank 0 tensor
t2 = tf.Variable([ [ [0., 1., 2.], [3., 4., 5.] ], [ [6., 7., 8.], [9., 10., 11.] ] ]) #rank 3 tensor
t0, t1, t2
输出将如下所示:
(24,
<tf.Variable 'Variable:0' shape=() dtype=int32, numpy=42>,
<tf.Variable 'Variable:0' shape=(2, 2, 3) dtype=float32, numpy=
array([[[ 0., 1., 2.],
[ 3., 4., 5.]],
[[ 6., 7., 8.],
[ 9., 10., 11.]]], dtype=float32)>)
TensorFlow 将推断数据类型,对于浮点数默认为tf.float32
,对于整数默认为tf.int32
(请参见前面的示例)。
或者,可以显式指定数据类型,如下所示:
f64 = tf.Variable(89, dtype = tf.float64)
f64.dtype
TensorFlow 具有大量的内置数据类型。
示例包括之前看到的示例tf.int16
,tf.complex64
和tf.string
。 参见这里。 要重新分配变量,请使用var.assign()
,如下所示:
f1 = tf.Variable(89.)
f1
# <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=89.0>
f1.assign(98.)
f1
# <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=98.0>
TensorFlow 常量可以在以下示例中声明:
m_o_l = tf.constant(42)
m_o_l
# <tf.Tensor: id=45, shape=(), dtype=int32, numpy=42>
m_o_l.numpy()
# 42
同样,TensorFlow 将推断数据类型,或者可以像使用变量那样显式指定它:
unit = tf.constant(1, dtype = tf.int64)
unit
# <tf.Tensor: id=48, shape=(), dtype=int64, numpy=1>
张量的形状通过属性(而不是函数)访问:
t2 = tf.Variable([ [ [0., 1., 2.], [3., 4., 5.] ], [ [6., 7., 8.], [9., 10., 11.] ] ]) # tensor variable
print(t2.shape)
输出将如下所示:
(2, 2, 3)
张量可能会被重塑并保留相同的值,这是构建神经网络经常需要的。
这是一个示例:
r1 = tf.reshape(t2,[2,6]) # 2 rows 6 cols
r2 = tf.reshape(t2,[1,12]) # 1 rows 12 cols
r1
# <tf.Tensor: id=33, shape=(2, 6), dtype=float32,
numpy= array([[ 0., 1., 2., 3., 4., 5.], [ 6., 7., 8., 9., 10., 11.]], dtype=float32)>
这是另一个示例:
r2 = tf.reshape(t2,[1,12]) # 1 row 12 columns
r2
# <tf.Tensor: id=36, shape=(1, 12), dtype=float32,
numpy= array([[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.]], dtype=float32)>
张量的等级是它具有的维数,即指定该张量的任何特定元素所需的索引数。
张量的等级可以这样确定,例如:
tf.rank(t2)
输出将如下所示:
<tf.Tensor: id=53, shape=(), dtype=int32, numpy=3>
(the shape is () because the output here is a scalar value)
正如您期望的那样,通过指定所需的索引来指定张量的元素。
以这个为例:
t3 = t2[1, 0, 2] # slice 1, row 0, column 2
t3
输出将如下所示:
<tf.Tensor: id=75, shape=(), dtype=float32, numpy=8.0>
如果需要,可以将张量转换为numpy
变量,如下所示:
print(t2.numpy())
输出将如下所示:
[[[ 0\. 1\. 2.] [ 3\. 4\. 5.]] [[ 6\. 7\. 8.] [ 9\. 10\. 11.]]]
也可以这样:
print(t2[1, 0, 2].numpy())
输出将如下所示:
8.0
张量中的元素数量很容易获得。 再次注意,使用.numpy()
函数从张量中提取 Python 值:
s = tf.size(input=t2).numpy()
s
输出将如下所示:
12
TensorFlow 支持您期望的所有数据类型。 完整列表位于这里,其中包括tf.int32
(默认整数类型),tf.float32
(默认浮动点类型)和tf.complex64
(复数类型)。
要查找张量的数据类型,请使用以下dtype
属性:
t3.dtype
输出将如下所示:
tf.float32
如您所料,使用重载运算符+
,-
,*
和/
来指定逐元素基本张量操作,如下所示:
t2*t2
输出将如下所示:
<tf.Tensor: id=555332, shape=(2, 2, 3), dtype=float32, numpy= array([[[ 0., 1., 4.], [ 9., 16., 25.]], [[ 36., 49., 64.], [ 81., 100., 121.]]], dtype=float32)>
按元素张量操作以与 NumPy 数组相同的方式支持广播。 最简单的示例是将张量乘以标量:
t4 = t2*4
print(t4)
输出将如下所示:
tf.Tensor( [[[ 0\. 4\. 8.] [12\. 16\. 20.]] [[24\. 28\. 32.] [36\. 40\. 44.]]], shape=(2, 2, 3), dtype=float32)
在该示例中,在概念上至少将标量乘法器 4 扩展为一个数组,该数组可以与t2
逐元素相乘。 在上对广播进行了非常详细的讨论,网址为。
要紧急转置矩阵和矩阵乘法,请使用以下命令:
u = tf.constant([[3,4,3]])
v = tf.constant([[1,2,1]])
tf.matmul(u, tf.transpose(a=v))
输出将如下所示:
<tf.Tensor: id=555345, shape=(1, 1), dtype=int32, numpy=array([[14]], dtype=int32)>
再次注意,默认整数类型为tf.int32
,默认浮点类型为tf.float32
。
可用于构成计算图一部分的张量的所有操作也可用于急切执行变量。
在这个页面上有这些操作的完整列表。
一种类型的 TensorFlow 变量可以强制转换为另一种类型。 可以在这个页面中找到更多详细信息。
请看以下示例:
i = tf.cast(t1, dtype=tf.int32) # 42
i
输出将如下所示:
<tf.Tensor: id=116, shape=(), dtype=int32, numpy=42>
截断后,将如下所示:
j = tf.cast(tf.constant(4.9), dtype=tf.int32) # 4
j
输出将如下所示:
<tf.Tensor: id=119, shape=(), dtype=int32, numpy=4>
参差不齐的张量是具有一个或多个参差不齐尺寸的张量。 参差不齐的尺寸是具有可能具有不同长度的切片的尺寸。
声明参差不齐的数组的方法有很多种,最简单的方法是常量参差不齐的数组。
以下示例显示了如何声明一个常数的,参差不齐的数组以及各个切片的长度:
ragged =tf.ragged.constant([[5, 2, 6, 1], [], [4, 10, 7], [8], [6,7]])
print(ragged)
print(ragged[0,:])
print(ragged[1,:])
print(ragged[2,:])
print(ragged[3,:])
print(ragged[4,:])
输出如下:
<tf.RaggedTensor [[5, 2, 6, 1], [], [4, 10, 7], [8], [6, 7]]>
tf.Tensor([5 2 6 1], shape=(4,), dtype=int32)
tf.Tensor([], shape=(0,), dtype=int32)
tf.Tensor([ 4 10 7], shape=(3,), dtype=int32)
tf.Tensor([8], shape=(1,), dtype=int32)
tf.Tensor([6 7], shape=(2,), dtype=int32)
注意单个切片的形状。
创建参差不齐的数组的常用方法是使用tf.RaggedTensor.from_row_splits()
方法,该方法具有以下签名:
@classmethod
from_row_splits(
cls,
values,
row_splits,
name=None
)
在这里,values
是要变成参差不齐的数组的值的列表,row_splits
是要拆分该值列表的位置的列表,因此行ragged[i]
的值存储在其中 ragged.values[ragged.row_splits[i]:ragged.row_splits[i+1]]
:
print(tf.RaggedTensor.from_row_splits(values=[5, 2, 6, 1, 4, 10, 7, 8, 6, 7],
row_splits=[0, 4, 4, 7, 8, 10]))
RaggedTensor
如下:
<tf.RaggedTensor [[5, 2, 6, 1], [], [4, 10, 7], [8], [6, 7]]>
在这个页面上有所有 TensorFlow Python 模块,类和函数的完整列表。
可以在这个页面中找到所有数学函数。
在本节中,我们将研究一些有用的 TensorFlow 操作,尤其是在神经网络编程的上下文中。
在本书的后面,我们将需要找到两个张量之差的平方。 方法如下:
tf.math.squared.difference( x, y, name=None)
请看以下示例:
x = [1,3,5,7,11]
y = 5
s = tf.math.squared_difference(x,y)
s
输出将如下所示:
<tf.Tensor: id=279, shape=(5,), dtype=int32, numpy=array([16, 4, 0, 4, 36], dtype=int32)>
请注意,在此示例中,Python 变量x
和y
被转换为张量,然后y
跨x
广播。 因此,例如,第一计算是(1 - 5)^2 = 16
。
以下是tf.reduce_mean()
的签名。
请注意,在下文中,所有 TensorFlow 操作都有一个名称参数,当使用急切执行作为其目的是在计算图中识别操作时,可以安全地将其保留为默认值None
。
请注意,这等效于np.mean
,除了它从输入张量推断返回数据类型,而np.mean
允许您指定输出类型(默认为float64
):
tf.reduce_mean(input_tensor, axis=None, keepdims=None, name=None)
通常需要找到张量的平均值。 当在单个轴上完成此操作时,该轴被称为减少了。
这里有些例子:
numbers = tf.constant([[4., 5.], [7., 3.]])
求出所有轴的平均值(即使用默认的axis = None
):
tf.reduce_mean(input_tensor=numbers)
#( 4\. + 5\. + 7\. + 3.)/4 = 4.75
输出将如下所示:
<tf.Tensor: id=272, shape=(), dtype=float32, numpy=4.75>
用以下方法找到各列的均值(即减少行数):
tf.reduce_mean(input_tensor=numbers, axis=0) # [ (4\. + 7\. )/2 , (5\. + 3.)/2 ] = [5.5, 4.]
输出将如下所示:
<tf.Tensor: id=61, shape=(2,), dtype=float32, numpy=array([5.5, 4\. ], dtype=float32)>
当keepdims
为True
时,缩小轴将保留为 1:
tf.reduce_mean(input_tensor=numbers, axis=0, keepdims=True)
输出如下:
array([[5.5, 4.]]) (1 row, 2 columns)
使用以下方法找到各行的均值(即减少列数):
tf.reduce_mean(input_tensor=numbers, axis=1) # [ (4\. + 5\. )/2 , (7\. + 3\. )/2] = [4.5, 5]
输出将如下所示:
<tf.Tensor: id=64, shape=(2,), dtype=float32, numpy=array([4.5, 5\. ], dtype=float32)>
当keepdims
为True
时,缩小轴将保留为 1:
tf.reduce_mean(input_tensor=numbers, axis=1, keepdims=True)
输出如下:
([[4.5], [5]]) (2 rows, 1 column)
开发神经网络时,例如初始化权重和偏差时,经常需要随机值。 TensorFlow 提供了多种生成这些随机值的方法。
tf.random.normal()
输出给定形状的张量,其中填充了来自正态分布的dtype
类型的值。
所需的签名如下:
tf. random.normal(shape, mean = 0, stddev =2, dtype=tf.float32, seed=None, name=None)
以这个为例:
tf.random.normal(shape = (3,2), mean=10, stddev=2, dtype=tf.float32, seed=None, name=None)
ran = tf.random.normal(shape = (3,2), mean=10.0, stddev=2.0)
print(ran)
输出将如下所示:
<tf.Tensor: id=13, shape=(3, 2), dtype=float32, numpy= array([[ 8.537131 , 7.6625767], [10.925293 , 11.804686 ], [ 9.3763075, 6.701221 ]], dtype=float32)>
所需的签名是这样的:
tf.random.uniform(shape, minval = 0, maxval= None, dtype=tf.float32, seed=None, name=None)
这将输出给定形状的张量,该张量填充了从minval
到maxval
范围内的均匀分布的值,其中下限包括在内,而上限不包括在内。
以这个为例:
tf.random.uniform(shape = (2,4), minval=0, maxval=None, dtype=tf.float32, seed=None, name=None)
输出将如下所示:
tf.Tensor( [[ 6 7] [ 0 12]], shape=(2, 2), dtype=int32)
请注意,对于这两个随机操作,如果您希望生成的随机值都是可重复的,则使用tf.random.set_seed()
。 还显示了非默认数据类型的使用:
tf.random.set_seed(11)
ran1 = tf.random.uniform(shape = (2,2), maxval=10, dtype = tf.int32)
ran2 = tf.random.uniform(shape = (2,2), maxval=10, dtype = tf.int32)
print(ran1) #Call 1
print(ran2)
tf.random.set_seed(11) #same seed
ran1 = tf.random.uniform(shape = (2,2), maxval=10, dtype = tf.int32)
ran2 = tf.random.uniform(shape = (2,2), maxval=10, dtype = tf.int32)
print(ran1) #Call 2
print(ran2)
Call 1
和Call 2
将返回相同的一组值。
输出将如下所示:
tf.Tensor(
[[4 6]
[5 2]], shape=(2, 2), dtype=int32)
tf.Tensor(
[[9 7]
[9 4]], shape=(2, 2), dtype=int32)
tf.Tensor(
[[4 6]
[5 2]], shape=(2, 2), dtype=int32)
tf.Tensor(
[[9 7]
[9 4]], shape=(2, 2), dtype=int32)
这是一个适合从这个页面执行的小示例。
请注意,此示例显示了如何通过调用 TensorFlow 函数来初始化急切变量。
dice1 = tf.Variable(tf.random.uniform([10, 1], minval=1, maxval=7, dtype=tf.int32))
dice2 = tf.Variable(tf.random.uniform([10, 1], minval=1, maxval=7, dtype=tf.int32))
# We may add dice1 and dice2 since they share the same shape and size.
dice_sum = dice1 + dice2
# We've got three separate 10x1 matrices. To produce a single
# 10x3 matrix, we'll concatenate them along dimension 1.
resulting_matrix = tf.concat(values=[dice1, dice2, dice_sum], axis=1)
print(resulting_matrix)
示例输出如下:
tf.Tensor(
[[ 5 4 9]
[ 5 1 6]
[ 2 4 6]
[ 5 6 11]
[ 4 4 8]
[ 4 6 10]
[ 2 2 4]
[ 5 6 11]
[ 2 6 8]
[ 5 4 9]], shape=(10, 3), dtype=int32)
现在,我们将研究如何在张量轴上查找具有最大值和最小值的元素的索引。
这些函数的签名如下:
tf.argmax(input, axis=None, name=None, output_type=tf.int64 )
tf.argmin(input, axis=None, name=None, output_type=tf.int64 )
以这个为例:
# 1-D tensor
t5 = tf.constant([2, 11, 5, 42, 7, 19, -6, -11, 29])
print(t5)
i = tf.argmax(input=t5)
print('index of max; ', i)
print('Max element: ',t5[i].numpy())
i = tf.argmin(input=t5,axis=0).numpy()
print('index of min: ', i)
print('Min element: ',t5[i].numpy())
t6 = tf.reshape(t5, [3,3])
print(t6)
i = tf.argmax(input=t6,axis=0).numpy() # max arg down rows
print('indices of max down rows; ', i)
i = tf.argmin(input=t6,axis=0).numpy() # min arg down rows
print('indices of min down rows ; ',i)
print(t6)
i = tf.argmax(input=t6,axis=1).numpy() # max arg across cols
print('indices of max across cols: ',i)
i = tf.argmin(input=t6,axis=1).numpy() # min arg across cols
print('indices of min across cols: ',i)
输出将如下所示:
tf.Tensor([ 2 11 5 42 7 19 -6 -11 29], shape=(9,), dtype=int32)
index of max; tf.Tensor(3, shape=(), dtype=int64)
Max element: 42
index of min: tf.Tensor(7, shape=(), dtype=int64)
Min element: -11
tf.Tensor( [[ 2 11 5] [ 42 7 19] [ -6 -11 29]], shape=(3, 3), dtype=int32)
indices of max down rows; tf.Tensor([1 0 2], shape=(3,), dtype=int64)
indices of min down rows ; tf.Tensor([2 2 0], shape=(3,), dtype=int64)
tf.Tensor( [[ 2 11 5] [ 42 7 19] [ -6 -11 29]], shape=(3, 3), dtype=int32)
indices of max across cols: tf.Tensor([1 0 2], shape=(3,), dtype=int64)
indices of min across cols: tf.Tensor([0 1 1], shape=(3,), dtype=int64)
为了保存和加载张量值,这是最好的方法(有关保存完整模型的方法,请参见第 2 章和 “Keras,TensorFlow 2” 的高级 API):
variable = tf.Variable([[1,3,5,7],[11,13,17,19]])
checkpoint= tf.train.Checkpoint(var=variable)
save_path = checkpoint.save('./vars')
variable.assign([[0,0,0,0],[0,0,0,0]])
variable
checkpoint.restore(save_path)
print(variable)
输出将如下所示:
<tf.Variable 'Variable:0' shape=(2, 4) dtype=int32, numpy= array([[ 1, 3, 5, 7], [11, 13, 17, 19]], dtype=int32)>
tf.function
是将采用 Python 函数并返回 TensorFlow 图的函数。 这样做的好处是,图可以在 Python 函数(func
)中应用优化并利用并行性。 tf.function
是 TensorFlow 2 的新功能。
其签名如下:
tf.function(
func=None,
input_signature=None,
autograph=True,
experimental_autograph_options=None
)
示例如下:
def f1(x, y):
return tf.reduce_mean(input_tensor=tf.multiply(x ** 2, 5) + y**2)
f2 = tf.function(f1)
x = tf.constant([4., -5.])
y = tf.constant([2., 3.])
# f1 and f2 return the same value, but f2 executes as a TensorFlow graph
assert f1(x,y).numpy() == f2(x,y).numpy()
断言通过,因此没有输出。
在本章中,我们通过查看一些说明一些基本操作的代码片段开始熟悉 TensorFlow。 我们对现代 TensorFlow 生态系统以及如何安装 TensorFlow 进行了概述。 我们还研究了一些管家操作,一些急切操作以及各种 TensorFlow 操作,这些操作在本书的其余部分中将是有用的。 在 www.youtube.com/watch?v=k5c-vg4rjBw 上对 TensorFlow 2 进行了出色的介绍。
另请参阅“附录 A”,以获得tf1.12
到tf2
转换工具的详细信息。 在下一章中,我们将介绍 Keras,这是 TensorFlow 2 的高级 API。