跳转至

数据操作#

N 维数组#

N 维数组是机器学习和神经网络中使用的主要数据结构。

  • 0-d(标量):如 1.0,可以作为一个类别
  • 1-d(向量):如 [1.0, 2.7, 3.4],可以作为一个特征向量
  • 2-d(矩阵):如 [[1.0, 2.7, 3.4], [5.0, 0.2, 4.6], [4.3, 8.5, 0.2]],可以作为一个样本-特征矩阵
  • 3-d:一张 RGB 图片(宽 × 高 × 通道)
  • 4-d:一个 RGB 图片批量(批量大小 × 宽 × 高 × 通道)
  • 5-d:一个视频批量(批量大小 × 时间 × 宽 × 高 × 通道)

创建数组需要三样东西:形状、每个元素的数据类型、每个元素的值。

访问元素#

写法 含义
[1, 2] 访问一个元素
[1, :] 访问编号为 1 的一整行
[:, 1] 访问编号为 1 的一整列
[1:3, 1:] 访问子区域:第 1 行开始、第 3 行结束(开区间),每行从编号 1 取到行尾
[::3, ::2] 从 (0, 0) 元素开始间隔访问,行间隔 3、列间隔 2

意即,对于二维张量来说,第一维表示行,第二维表示列。更高维的情况可以递归理解: 对于形状为 \((d_0, d_1, \dots, d_{n-1})\) 的 \(n\) 维张量,可以看作 \(d_0\) 个 \(n-1\) 维张量,dim0 对应最外层。

实际操作数据#

需要用到 torch 包:

import torch

张量#

PyTorch 中的张量实际上就是 n 维数组,但与 NumPy 中的数组有些区别, 比如张量可以放在 GPU 上、可以自动求导等。

常见的创建方式:

torch.tensor([1, 2, 3])        # 从数据创建,整数默认 int64
torch.tensor([1., 2., 3.])     # 浮点默认 float32
torch.zeros(2, 3)              # 全 0
torch.ones(2, 3)               # 全 1
torch.randn(2, 3)              # 标准正态分布
torch.arange(0, 10, 2)         # 序列
torch.from_numpy(np_array)     # 从 NumPy 创建,可能共享内存

既然 tensor 本质仍是 n 维数组,它也可以和 NumPy 中的数组互相转换:

x.numpy()                      # tensor -> ndarray
torch.from_numpy(np_array)     # ndarray -> tensor

张量的常用操作:

x.shape                        # 形状,等价于 x.size()
x.dtype                        # 数据类型
x.device                       # 所在设备
x.ndim                         # 维度数
x.numel()                      # 元素总数
x.requires_grad
torch.cat([a, b], dim=0)       # 在现有维度拼接
torch.stack([a, b], dim=0)     # 新建维度堆叠
torch.chunk(x, 2, dim=0)       # 分成若干块
torch.split(x, 2, dim=0)       # 按大小拆分

注意原地操作和重新分配的差别:

Y = Y + x    # 会为新的 Y 分配内存
Y += x       # 原地操作