01.md 27.2 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
# 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`)进行迭代的状态

让我们继续进行**估计** **ator** ,这是一个高级 API,可让您构建大大简化的机器学习程序。 估算员负责培训,评估,预测和导出服务。

**Te** **nsorFlow.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 上有大量信息可用于安装 TensorFlow for Python。

Google 也建议在虚拟环境中安装 TensorFlow,这是一种标准做法,该环境将一组 API 和代码与其他 API 和代码以及系统范围的环境隔离开来。

TensorFlow 有两种不同的版本-一个用于在 CPU 上执行,另一个用于在 GPU 上执行。 最后,这需要安装数值库 CUDA 和 CuDNN。 Tensorflow 将在可能的情况下默认执行 GPU。 参见 [https://www.tensorflow.org/alpha/guide/using_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/](http://docs.python-guide.org/en/latest/dev/virtualenvs/)

Google 的官方文档 [https://www.tensorflow.org/install/](https://www.tensorflow.org/install/) 中提供了有关安装 TensorFlow 所需的所有方面的非常详细的信息。

安装后,您可以从命令终端检查 TensorFlow 的安装。 [上有执行此操作的说明,http://www.laurencemoroney.com/tensorflow-to-gpu-or-not-to-gpu/](http://www.laurencemoroney.com/tensorflow-to-gpu-or-not-to-gpu/) 以及安装 TensorFlow 的夜间版本(其中包含所有 最新更新。

# 内务和急切的操作

我们将首先介绍如何导入 TensorFlow,然后介绍 TensorFlow 编码样式,以及如何进行一些基本的整理工作。 之后,我们将看一些基本的 TensorFlow 操作。 您可以为这些代码片段创建 Jupyter Notebook,也可以使用自己喜欢的 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](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 eager 变量的方法如下:

```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](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](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](https://www.tensorflow.org/api_guides/python/math_ops) 上有这些操作的完整列表。

# 将张量转换为另一个(张量)数据类型

一种类型的 TensorFlow 变量可以强制转换为另一种类型。 可以在 [https://www.tensorflow.org/api_docs/python/tf/cast](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](https://www.tensorflow.org/api_docs/python/tf) 上有所有 TensorFlow Python 模块,类和函数的完整列表。

可以在 [https://www.tensorflow.org/api_docs/python/tf/math](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) <sup>2</sup> = 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](https://colab.research.google.com/notebooks/mlcc/creating_and_manipulating_tensors.ipynb#scrollTo=6UUluecQSCvr) 执行的小示例。

请注意,此示例显示了如何通过调用 TensorFlow 函数来初始化 eager 变量。

```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 章](../Text/02.html)*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。