# 2.9 张量API

本节，你将知道PyTorch张量是什么以及在内部它们如何运行。在结束本章之前，我们还会看一下PyTorch提供的张量的操作。在这里列出所有操作没什么用，取而代之的是，我们将为你提供相关API的一般感觉并展示如何在[官方文档](http://pytorch.org/docs)中查找相关内容。

首先，在`torch`模块下可进行张量上和张量之间的绝大多数操作，这些操作也可以作为张量对象的方法进行调用。例如，你可以通过`torch`模块使用先前遇到的`transpose`函数：

``` python
a = torch.ones(3, 2)
a_t = torch.transpose(a, 0, 1)
```

或者调用`a`张量的方法：

```
a = torch.ones(3, 2)
a_t = a.transpose(0, 1)
```

以上两种形式之间没有区别，可以互换使用。需要注意的是：有少量的操作仅作为张量对象的方法存在。你可以通过名称中的下划线来识别它们，例如`zero_`，下划线标识表明该方法是就地（inplace）运行的，即直接修改输入而不是创建新的输出并返回。例如，`zero_`方法会将输入的所有元素清零。任何不带下划线的方法都将保持源张量不变并返回新的张量：

``` python
a = torch.ones(3, 2)
a.zero_()
a
```
输出:
```
tensor([[0., 0.],
        [0., 0.],
        [0., 0.]])
```

刚刚我们提到了[官方文档](http://pytorch.org/docs)，它是详尽无遗并且组织合理的，它将张量操作分为几组：

* 创建操作 —— 构造张量的函数，例如`ones`和`from_numpy`；
* 索引、切片、联接和变异操作 —— 更改形状、步长或张量内容，例如`transpose`；
* 数学操作 —— 通过计算来操纵张量内容的函数：
    * 按点（pointwise）操作 —— 将函数分别应用于每个元素（例如`abs`和`cos`）的函数
    * 简化（reduction）操作 —— 通过张量迭代计算合计值的函数，例如`mean`、`std`和`norm`；
    * 比较操作 —— 用于比较张量的函数，例如`equal`和`max`；
    * 频谱操作 —— 在频域中转换和运行的函数，例如`stft`和`hamming_window`；
    * 其他操作 —— 一些特殊函数，例如对于向量的`cross`，对于矩阵的`trace`；
    * BLAS和LAPACK操作 —— 遵循BLAS（Basic Linear Algebra Subprograms）规范的函数，用于标量、向量与向量、矩阵与向量和矩阵与矩阵的运算。

* 随机采样操作 —— 从概率分布中随机采样值的函数，例如`randn`和`normal`;
* 序列化操作 —— 用于保存和加载张量的函数，例如`save`和`load`；
* 并行操作 —— 控制并行CPU执行的线程数的函数，例如`set_num_threads`；

动手探索常见张量API是很有帮助的。本章提供了此类交互式探索的所有先决知识。

## 练习
* 从`list(range(9))`创建一个张量`a`，然后预测并验证一下尺寸、偏移和步长。
* 创建一个张量`b = a.view(3, 3)`，`b[1,1]`的值是多少？
* 创建一个张量`c = b [1:, 1:]`，然后预测并验证一下尺寸、偏移和步长。
* 选择一个余弦或平方根之类的数学运算。你能找到在`torch`找到正确的对应方法吗？
* 你刚刚选择的函数有就地（inplace）版本吗？

## 总结

* 神经网络将浮点表示形式转换为其他浮点表示形式，起始和结束的表示形式通常是人类可以理解的，但中间表示则不是这样。
* 这些浮点表示存储在张量中。
* 张量是多维数组，它是PyTorch中的基本数据结构。
* PyTorch有一个全面的标准库，用于张量创建、操作和数学运算。
* 张量可以序列化存储到磁盘上也可以加载回来。
* PyTorch中的所有张量操作都可以在CPU和GPU上执行，无需更改代码。
* PyTorch使用结尾下划线标识来表示就地操作（例如`Tensor.sqrt_`）。
