💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 一、TensorFlow 2 简介 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`通道内的示例: ```py image1 = tf.zeros([7, 28, 28, 3]) # example-within-batch by height by width by color ``` 尽管 TensorFlow 通常可以用于许多数值计算领域,尤其是机器学习,但其主要研究和开发领域是**深层神经网络**(**DNN**)的应用,它已在语音和声音识别等不同领域使用,例如,在如今广泛使用的声控助手中; 基于文本的应用,例如语言翻译器; 图像识别,例如系外行星搜寻,癌症检测和诊断; 以及时间序列应用(例如推荐系统)。 在本章中,我们将讨论以下内容: * 现代 TensorFlow 生态系统 * 安装 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 TensorFlow 的最佳编程支持是为 Python 提供的(尽管确实存在 Java,C 和 Go 的库,而其他语言的库正在积极开发中)。 Web 上有大量信息可用于为 Python 安装 TensorFlow。 Google 也建议在虚拟环境中安装 TensorFlow,这是一种标准做法,该环境将一组 API 和代码与其他 API 和代码以及系统范围的环境隔离开来。 TensorFlow 有两种不同的版本-一个用于在 CPU 上执行,另一个用于在 GPU 上执行。 最后,这需要安装数值库 CUDA 和 CuDNN。 Tensorflow 将在可能的情况下默认执行 GPU。 参见[这里](https://www.tensorflow.org/alpha/guide/using_gpu)。 与其尝试重新发明轮子,不如跟随资源来创建虚拟环境和安装 TensorFlow。 总而言之,可能会为 Windows 7 或更高版本,Ubuntu Linux 16.04 或更高版本以及 macOS 10.12.6 或更高版本安装 TensorFlow。 有关虚拟环境的完整介绍,请参见[这里](http://docs.python-guide.org/en/latest/dev/virtualenvs/)。 [Google 的官方文档](https://www.tensorflow.org/install/)中提供了有关安装 TensorFlow 所需的所有方面的非常详细的信息。 安装后,您可以从命令终端检查 TensorFlow 的安装。 [这个页面](http://www.laurencemoroney.com/tensorflow-to-gpu-or-not-to-gpu/)有执行此操作,以及安装 TensorFlow 的夜间版本(其中包含所有最新更新)的说明。 # 急切的操作 我们将首先介绍如何导入 TensorFlow,然后介绍 TensorFlow 编码风格,以及如何进行一些基本的整理工作。 之后,我们将看一些基本的 TensorFlow 操作。 您可以为这些代码片段创建 Jupyter 笔记本,也可以使用自己喜欢的 IDE 创建源代码。 该代码在 GitHub 存储库中都可用。 # 导入 TensorFlow 导入 TensorFlow 很简单。 请注意几个系统检查: ```py 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__)) ``` # TensorFlow 的编码风格约定 对于 Python 应用,Google 遵守 PEP8 标准约定。 特别是,他们将 CamelCase 用于类(例如`hub.LatestModuleExporter`),将`snake_case`用于函数,方法和属性(例如`tf.math.squared_difference`)。 Google 还遵守《Google Python 风格指南》,该指南可在[这个页面](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)中找到。 # 使用急切执行 急切执行是 TensorFlow 2 中的默认设置,因此不需要特殊设置。 以下代码可用于查找是否正在使用 CPU 或 GPU,如果它是 GPU,则该 GPU 是否为`#0`。 我们建议键入代码,而不要使用复制和粘贴。 这样,您将对以下命令有所了解: ```py 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 急切变量的方法如下: ```py 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 ``` 输出将如下所示: ```py (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`(请参见前面的示例)。 或者,可以显式指定数据类型,如下所示: ```py f64 = tf.Variable(89, dtype = tf.float64) f64.dtype ``` TensorFlow 具有大量的内置数据类型。 示例包括之前看到的示例`tf.int16`,`tf.complex64`和`tf.string`。 参见[这里](https://www.tensorflow.org/api_docs/python/tf/dtypes/DType)。 要重新分配变量,请使用`var.assign()`,如下所示: ```py 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 常量 TensorFlow 常量可以在以下示例中声明: ```py m_o_l = tf.constant(42) m_o_l # <tf.Tensor: id=45, shape=(), dtype=int32, numpy=42> m_o_l.numpy() # 42 ``` 同样,TensorFlow 将推断数据类型,或者可以像使用变量那样显式指定它: ```py unit = tf.constant(1, dtype = tf.int64) unit # <tf.Tensor: id=48, shape=(), dtype=int64, numpy=1> ``` # 调整张量 张量的形状通过属性(而不是函数)访问: ```py t2 = tf.Variable([ [ [0., 1., 2.], [3., 4., 5.] ], [ [6., 7., 8.], [9., 10., 11.] ] ]) # tensor variable print(t2.shape) ``` 输出将如下所示: ```py (2, 2, 3) ``` 张量可能会被重塑并保留相同的值,这是构建神经网络经常需要的。 这是一个示例: ```py 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)> ``` 这是另一个示例: ```py 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)> ``` # 张量的等级(尺寸) 张量的等级是它具有的维数,即指定该张量的任何特定元素所需的索引数。 张量的等级可以这样确定,例如: ```py tf.rank(t2) ``` 输出将如下所示: ```py <tf.Tensor: id=53, shape=(), dtype=int32, numpy=3> (the shape is () because the output here is a scalar value) ``` # 指定张量的元素 正如您期望的那样,通过指定所需的索引来指定张量的元素。 以这个为例: ```py t3 = t2[1, 0, 2] # slice 1, row 0, column 2 t3 ``` 输出将如下所示: ```py <tf.Tensor: id=75, shape=(), dtype=float32, numpy=8.0> ``` # 将张量转换为 NumPy/Python 变量 如果需要,可以将张量转换为`numpy`变量,如下所示: ```py print(t2.numpy()) ``` 输出将如下所示: ```py [[[ 0\. 1\. 2.] [ 3\. 4\. 5.]] [[ 6\. 7\. 8.] [ 9\. 10\. 11.]]] ``` 也可以这样: ```py print(t2[1, 0, 2].numpy()) ``` 输出将如下所示: ```py 8.0 ``` # 查找张量的大小(元素数) 张量中的元素数量很容易获得。 再次注意,使用`.numpy()`函数从张量中提取 Python 值: ```py s = tf.size(input=t2).numpy() s ``` 输出将如下所示: ```py 12 ``` # 查找张量的数据类型 TensorFlow 支持您期望的所有数据类型。 完整列表位于[这里](https://www.tensorflow.org/versions/r1.1/programmers_guide/dims_types),其中包括`tf.int32`(默认整数类型),`tf.float32`(默认浮动点类型)和`tf.complex64`(复数类型)。 要查找张量的数据类型,请使用以下`dtype`属性: ```py t3.dtype ``` 输出将如下所示: ```py tf.float32 ``` # 指定按元素的基本张量操作 如您所料,使用重载运算符`+`,`-`,`*`和`/`来指定逐元素基本张量操作,如下所示: ```py t2*t2 ``` 输出将如下所示: ```py <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 数组相同的方式支持广播。 最简单的示例是将张量乘以标量: ```py t4 = t2*4 print(t4) ``` 输出将如下所示: ```py tf.Tensor( [[[ 0\. 4\. 8.] [12\. 16\. 20.]] [[24\. 28\. 32.] [36\. 40\. 44.]]], shape=(2, 2, 3), dtype=float32) ``` 在该示例中,在概念上至少将标量乘法器 4 扩展为一个数组,该数组可以与`t2`逐元素相乘。 在[上对广播进行了非常详细的讨论,网址为](https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)。 # 转置 TensorFlow 和矩阵乘法 要紧急转置矩阵和矩阵乘法,请使用以下命令: ```py u = tf.constant([[3,4,3]]) v = tf.constant([[1,2,1]]) tf.matmul(u, tf.transpose(a=v)) ``` 输出将如下所示: ```py <tf.Tensor: id=555345, shape=(1, 1), dtype=int32, numpy=array([[14]], dtype=int32)> ``` 再次注意,默认整数类型为`tf.int32`,默认浮点类型为`tf.float32`。 可用于构成计算图一部分的张量的所有操作也可用于急切执行变量。 在[这个页面](https://www.tensorflow.org/api_guides/python/math_ops)上有这些操作的完整列表。 # 将张量转换为另一个(张量)数据类型 一种类型的 TensorFlow 变量可以强制转换为另一种类型。 可以在[这个页面](https://www.tensorflow.org/api_docs/python/tf/cast)中找到更多详细信息。 请看以下示例: ```py i = tf.cast(t1, dtype=tf.int32) # 42 i ``` 输出将如下所示: ```py <tf.Tensor: id=116, shape=(), dtype=int32, numpy=42> ``` 截断后,将如下所示: ```py j = tf.cast(tf.constant(4.9), dtype=tf.int32) # 4 j ``` 输出将如下所示: ```py <tf.Tensor: id=119, shape=(), dtype=int32, numpy=4> ``` # 声明参差不齐的张量 参差不齐的张量是具有一个或多个参差不齐尺寸的张量。 参差不齐的尺寸是具有可能具有不同长度的切片的尺寸。 声明参差不齐的数组的方法有很多种,最简单的方法是常量参差不齐的数组。 以下示例显示了如何声明一个常数的,参差不齐的数组以及各个切片的长度: ```py 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,:]) ``` 输出如下: ```py <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()`方法,该方法具有以下签名: ```py @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]]`: ```py 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`如下: ```py <tf.RaggedTensor [[5, 2, 6, 1], [], [4, 10, 7], [8], [6, 7]]> ``` # 提供有用的 TensorFlow 操作 在[这个页面](https://www.tensorflow.org/api_docs/python/tf)上有所有 TensorFlow Python 模块,类和函数的完整列表。 可以在[这个页面](https://www.tensorflow.org/api_docs/python/tf/math)中找到所有数学函数。 在本节中,我们将研究一些有用的 TensorFlow 操作,尤其是在神经网络编程的上下文中。 # 求两个张量之间的平方差 在本书的后面,我们将需要找到两个张量之差的平方。 方法如下: ```py tf.math.squared.difference( x, y, name=None) ``` 请看以下示例: ```py x = [1,3,5,7,11] y = 5 s = tf.math.squared_difference(x,y) s ``` 输出将如下所示: ```py <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`): ```py tf.reduce_mean(input_tensor, axis=None, keepdims=None, name=None) ``` 通常需要找到张量的平均值。 当在单个轴上完成此操作时,该轴被称为减少了。 这里有些例子: ```py numbers = tf.constant([[4., 5.], [7., 3.]]) ``` # 求所有轴的均值 求出所有轴的平均值(即使用默认的`axis = None`): ```py tf.reduce_mean(input_tensor=numbers) #( 4\. + 5\. + 7\. + 3.)/4 = 4.75 ``` 输出将如下所示: ```py <tf.Tensor: id=272, shape=(), dtype=float32, numpy=4.75> ``` # 求各列的均值 用以下方法找到各列的均值(即减少行数): ```py tf.reduce_mean(input_tensor=numbers, axis=0) # [ (4\. + 7\. )/2 , (5\. + 3.)/2 ] = [5.5, 4.] ``` 输出将如下所示: ```py <tf.Tensor: id=61, shape=(2,), dtype=float32, numpy=array([5.5, 4\. ], dtype=float32)> ``` 当`keepdims`为`True`时,缩小轴将保留为 1: ```py tf.reduce_mean(input_tensor=numbers, axis=0, keepdims=True) ``` 输出如下: ```py array([[5.5, 4.]]) (1 row, 2 columns) ``` # 求各行的均值 使用以下方法找到各行的均值(即减少列数): ```py tf.reduce_mean(input_tensor=numbers, axis=1) # [ (4\. + 5\. )/2 , (7\. + 3\. )/2] = [4.5, 5] ``` 输出将如下所示: ```py <tf.Tensor: id=64, shape=(2,), dtype=float32, numpy=array([4.5, 5\. ], dtype=float32)> ``` 当`keepdims`为`True`时,缩小轴将保留为 1: ```py tf.reduce_mean(input_tensor=numbers, axis=1, keepdims=True) ``` 输出如下: ```py ([[4.5], [5]]) (2 rows, 1 column) ``` # 生成充满随机值的张量 开发神经网络时,例如初始化权重和偏差时,经常需要随机值。 TensorFlow 提供了多种生成这些随机值的方法。 # 使用`tf.random.normal()` `tf.random.normal()`输出给定形状的张量,其中填充了来自正态分布的`dtype`类型的值。 所需的签名如下: ```py tf. random.normal(shape, mean = 0, stddev =2, dtype=tf.float32, seed=None, name=None) ``` 以这个为例: ```py 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) ``` 输出将如下所示: ```py <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()` 所需的签名是这样的: ```py tf.random.uniform(shape, minval = 0, maxval= None, dtype=tf.float32, seed=None, name=None) ``` 这将输出给定形状的张量,该张量填充了从`minval`到`maxval`范围内的均匀分布的值,其中下限包括在内,而上限不包括在内。 以这个为例: ```py tf.random.uniform(shape = (2,4), minval=0, maxval=None, dtype=tf.float32, seed=None, name=None) ``` 输出将如下所示: ```py tf.Tensor( [[ 6 7] [ 0 12]], shape=(2, 2), dtype=int32) ``` 请注意,对于这两个随机操作,如果您希望生成的随机值都是可重复的,则使用`tf.random.set_seed()`。 还显示了非默认数据类型的使用: ```py 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`将返回相同的一组值。 输出将如下所示: ```py 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) ``` # 使用随机值的实际示例 这是一个适合从[这个页面](https://colab.research.google.com/notebooks/mlcc/creating_and_manipulating_tensors.ipynb#scrollTo=6UUluecQSCvr)执行的小示例。 请注意,此示例显示了如何通过调用 TensorFlow 函数来初始化急切变量。 ```py 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) ``` 示例输出如下: ```py 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) ``` # 查找最大和最小元素的索引 现在,我们将研究如何在张量轴上查找具有最大值和最小值的元素的索引。 这些函数的签名如下: ```py tf.argmax(input, axis=None, name=None, output_type=tf.int64 ) tf.argmin(input, axis=None, name=None, output_type=tf.int64 ) ``` 以这个为例: ```py # 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) ``` 输出将如下所示: ```py 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): ```py 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) ``` 输出将如下所示: ```py <tf.Variable 'Variable:0' shape=(2, 4) dtype=int32, numpy= array([[ 1, 3, 5, 7], [11, 13, 17, 19]], dtype=int32)> ``` # 使用`tf.function` `tf.function`是将采用 Python 函数并返回 TensorFlow 图的函数。 这样做的好处是,图可以在 Python 函数(`func`)中应用优化并利用并行性。 `tf.function`是 TensorFlow 2 的新功能。 其签名如下: ```py tf.function( func=None, input_signature=None, autograph=True, experimental_autograph_options=None ) ``` 示例如下: ```py 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](https://www.youtube.com/watch?v=k5c-vg4rjBw) 上对 TensorFlow 2 进行了出色的介绍。 另请参阅“附录 A”,以获得`tf1.12`到`tf2`转换工具的详细信息。 在下一章中,我们将介绍 Keras,这是 TensorFlow 2 的高级 API。