# 张量 > 原文: 张量是一种特殊的数据结构,与数组和矩阵非常相似。 在 PyTorch 中,我们使用张量对模型的输入和输出以及模型的参数进行编码。 张量与 NumPy 的`ndarray`相似,除了张量可以在 GPU 或其他专用硬件上运行以加速计算。 如果您熟悉`ndarray`,就可以使用张量 API。 如果没有,请遵循此快速 API 演练。 ```py import torch import numpy as np ``` ## 张量初始化 张量可以通过多种方式初始化。 看下面的例子: **直接来自数据** 张量可以直接从数据创建。 数据类型是自动推断的。 ```py data = [[1, 2],[3, 4]] x_data = torch.tensor(data) ``` **来自 NumPy 数组** 可以从 NumPy 数组创建张量(反之亦然-参见[与 NumPy 桥接](#bridge-to-np-label))。 ```py np_array = np.array(data) x_np = torch.from_numpy(np_array) ``` **来自另一个张量**: 除非明确覆盖,否则新张量将保留参数张量的属性(形状,数据类型)。 ```py x_ones = torch.ones_like(x_data) # retains the properties of x_data print(f"Ones Tensor: \n {x_ones} \n") x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data print(f"Random Tensor: \n {x_rand} \n") ``` 出: ```py Ones Tensor: tensor([[1, 1], [1, 1]]) Random Tensor: tensor([[0.2143, 0.8153], [0.5212, 0.8607]]) ``` **具有随机或恒定值**: `shape`是张量尺寸的元组。 在下面的函数中,它确定输出张量的维数。 ```py shape = (2,3,) rand_tensor = torch.rand(shape) ones_tensor = torch.ones(shape) zeros_tensor = torch.zeros(shape) print(f"Random Tensor: \n {rand_tensor} \n") print(f"Ones Tensor: \n {ones_tensor} \n") print(f"Zeros Tensor: \n {zeros_tensor}") ``` 出: ```py Random Tensor: tensor([[0.6513, 0.6193, 0.5550], [0.7230, 0.3545, 0.9288]]) Ones Tensor: tensor([[1., 1., 1.], [1., 1., 1.]]) Zeros Tensor: tensor([[0., 0., 0.], [0., 0., 0.]]) ``` * * * ## 张量属性 张量属性描述了它们的形状,数据类型以及存储它们的设备。 ```py tensor = torch.rand(3,4) print(f"Shape of tensor: {tensor.shape}") print(f"Datatype of tensor: {tensor.dtype}") print(f"Device tensor is stored on: {tensor.device}") ``` 出: ```py Shape of tensor: torch.Size([3, 4]) Datatype of tensor: torch.float32 Device tensor is stored on: cpu ``` * * * ## 张量运算 [在此处](https://pytorch.org/docs/stable/torch.html)全面描述了超过 100 个张量运算,包括转置,索引,切片,数学运算,线性代数,随机采样等。 它们每个都可以在 GPU 上运行(通常比 CPU 上更高的速度)。 如果您使用的是 Colab,请通过转到“编辑”>“笔记本设置”来分配 GPU。 ```py # We move our tensor to the GPU if available if torch.cuda.is_available(): tensor = tensor.to('cuda') ``` 尝试从列表中进行一些操作。 如果您熟悉 NumPy API,则可以轻松使用张量 API。 **类似 Numpy 的标准索引和切片**: ```py tensor = torch.ones(4, 4) tensor[:,1] = 0 print(tensor) ``` 出: ```py tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) ``` **连接张量**可以使用`torch.cat`沿给定维度连接一系列张量。 另请参见[`torch.stack`](https://pytorch.org/docs/stable/generated/torch.stack.html),这是另一个与`torch.cat`稍有不同的张量连接操作。 ```py t1 = torch.cat([tensor, tensor, tensor], dim=1) print(t1) ``` 出: ```py tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]]) ``` **相乘张量** ```py # This computes the element-wise product print(f"tensor.mul(tensor) \n {tensor.mul(tensor)} \n") # Alternative syntax: print(f"tensor * tensor \n {tensor * tensor}") ``` 出: ```py tensor.mul(tensor) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor * tensor tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) ``` 计算两个张量之间的矩阵乘法 ```py print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n") # Alternative syntax: print(f"tensor @ tensor.T \n {tensor @ tensor.T}") ``` 出: ```py tensor.matmul(tensor.T) tensor([[3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.]]) tensor @ tensor.T tensor([[3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.]]) ``` **原地操作**后缀为`_`的操作就位。 例如:`x.copy_(y)`,`x.t_()`将更改为`x`。 ```py print(tensor, "\n") tensor.add_(5) print(tensor) ``` 出: ```py tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.]]) ``` 注意 原地操作可以节省一些内存,但是在计算导数时可能会因为立即丢失历史记录而出现问题。 因此,不鼓励使用它们。 * * * ## 与 NumPy 桥接 CPU 和 NumPy 数组上的张量可以共享其基础内存位置,更改一个将更改另一个。 ### 张量到 NumPy 数组 ```py t = torch.ones(5) print(f"t: {t}") n = t.numpy() print(f"n: {n}") ``` 出: ```py t: tensor([1., 1., 1., 1., 1.]) n: [1\. 1\. 1\. 1\. 1.] ``` 张量的变化反映在 NumPy 数组中。 ```py t.add_(1) print(f"t: {t}") print(f"n: {n}") ``` 出: ```py t: tensor([2., 2., 2., 2., 2.]) n: [2\. 2\. 2\. 2\. 2.] ``` ### 将 NumPy 数组转换为张量 ```py n = np.ones(5) t = torch.from_numpy(n) ``` NumPy 数组中的更改反映在张量中。 ```py np.add(n, 1, out=n) print(f"t: {t}") print(f"n: {n}") ``` 出: ```py t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64) n: [2\. 2\. 2\. 2\. 2.] ``` **脚本的总运行时间**:(0 分钟 0.045 秒) [下载 Python 源码:`tensor_tutorial.py`](https://pytorch.org/tutorials/_downloads/092fba3c36cb2ab226bfdaa78248b310/tensor_tutorial.py) [下载 Jupyter 笔记本:`tensor_tutorial.ipynb`](https://pytorch.org/tutorials/_downloads/3c2b25b8a9f72db7780a6bf9b5fc9f62/tensor_tutorial.ipynb) [由 Sphinx 画廊](https://sphinx-gallery.readthedocs.io)生成的画廊