Skip to content

数据操作 (张量函数)

1. 数据类型

机器学习的最多的是 N维数组,也称为张量(Tensor),表示一个数值组成的数组,这个数组可能有多个维度。

  • 标量(Scalar):0维数组,只有一个元素
    • 例如:1.0, 2.0
  • 向量(Vector):1维数组,有多个元素
    • 例如:[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
  • 矩阵(Matrix):2维数组,有多个向量
    • 例如:[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
  • 张量(Tensor):n维数组,有多个矩阵
    • 3-d 例如, RGB 图像(宽x高x通道)
    • 4-d 例如, 一个批次的 RGB 图像(批量大小x宽x高x通道)
    • 5-d 例如, 一个批次视频(批量大小x时间x宽x高x通道)

2. 访问元素

语法:

  • [行, 列]

  • [起始(含):结束(不含):步长, 起始(含):结束(不含):步长]

  • 一个元素:[1, 2]

  • 一行: [1, :]

  • 一列: [:, 2]

  • 子区域:[1:3, 1:]

  • 子区域:[::3, ::2]

3. 导入 torch 库

PyTorch 虽然叫这个名字, 但是应该导入 torch 而不是 pytorch

python
import torch

x = torch.arange(12) # 生成一个从 0 到 11 的张量
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

4. 生成张量

python
x = torch.arange(12)
x
# tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

默认是行向量, 可通过 torch.reshape.t() 方法改成列向量

python
x = torch.reshape(-1,1) # -1 表示自动计算维度, 1 表示列向量
x
# tensor([[ 0],
#         [ 1],
#         [ 2],
#         [ 3],
#         [ 4],
#         [ 5],
#         [ 6],
#         [ 7],
#         [ 8],
#         [ 9],
#         [10],
#         [11]])

5. 查看张量的形状 和 张量中的元素值

python
x.shape
# torch.Size([12])
x.numel()
# 12
shape
[ ʃeɪp ]
形状

6. 改变张量的形状 不改变张量中的元素值

python
X = torch.reshape(3, 4)
X
# tensor([[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]])
shape = X.shape
# torch.Size([3, 4])

7. 创造一个全0 或全1 张量

python
x0 = torch.zeros(2,3,4)
# tensor([[[0., 0., 0., 0.],
#          [0., 0., 0., 0.],
#          [0., 0., 0., 0.]],
#         [[0., 0., 0., 0.],
#          [0., 0., 0., 0.],
#          [0., 0., 0., 0.]]])
x1 = torch.ones(2,3,4)
# tensor([[[1., 1., 1., 1.],
#          [1., 1., 1., 1.],
#          [1., 1., 1., 1.]],
#         [[1., 1., 1., 1.],
#          [1., 1., 1., 1.],
#          [1., 1., 1., 1.]]])

8. 随机初始化张量

每个元素都从均值为0、标准差为1的标准高斯分布(正态分布)中随机采样

python
x_rand = torch.rand(2,3,4)
# tensor([[[0.5242, 0.2212, 0.2224, 0.3222],
#          [0.1222, 0.1232, 0.1222, 0.1222],
#          [0.1222, 0.1222, 0.1222, 0.1222]],
#         [[0.1222, 0.1222, 0.1222, 0.1222],
#          [0.1222, 0.1222, 0.1222, 0.1222],
#          [0.1222, 0.1222, 0.1222, 0.1222]]])

9. 通过嵌套列表创建张量

python
X = torch.tensor([[1, 2, 3], [4, 5, 6]])
X
# tensor([[1, 2, 3],
#         [4, 5, 6]])
tensor
[ tensər ]
张量

10. 算数运算符

+, - , * , / , **, 都可以被升级为元素运算

python
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
x + y, x - y, x * y, x / y, x**y  # **运算符是求幂运算
# (tensor([ 3.,  4.,  6., 10.]),
#  tensor([-1.,  0.,  2.,  6.]),
#  tensor([ 2.,  4.,  8., 16.]),
#  tensor([0.5000, 1.0000, 2.0000, 4.0000]),
#  tensor([ 1.,  4., 16., 64.]))

11. 多张量连结在一起

python
X = torch.arange(12, dtype=torch.float32).reshape((3,4)) # 创造一个12个元素的张量(内容dtyoe 为浮点数),然后reshape为3行4列的矩阵
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0) # 按行连结
# tensor([[ 0.,  1.,  2.,  3.],
#         [ 4.,  5.,  6.,  7.],
#         [ 8.,  9., 10., 11.],
#         [ 2.,  1.,  4.,  3.],
#         [ 1.,  2.,  3.,  4.],
#         [ 4.,  3.,  2.,  1.]])
torch.cat((X, Y), dim=1) # 按列连结
# tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],
#         [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],
#         [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]])

12. 逻辑运算符

python
X == Y
# tensor([[False,  True, False,  True],
#         [False, False, False, False],
#         [False, False, False, False]])

13. 张量求和

python
x.sum()
# tensor(66.)

14. 广播机制

两个张量的形状不一样,可以通过广播机制来进行运算。 reshape((3, 1)) = reshape((3, 1))

python
a = torch.arange(3).reshape((3, 1))
a
# tensor([[0],
#         [1],
#         [2]])
b = torch.arange(2).reshape((1, 2))
b
# tensor([[0, 1]])
a + b
# tensor([[0, 1],
#         [1, 2],
#         [2, 3]])

15. 赋值

x = torch.arange(12).reshape((3, 4))
x
# tensor([[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]])
x[1, 2] = 99 # 单个赋值
x
# tensor([[ 0,  1,  2,  3],
#         [ 4,  5, 99,  7],
#         [ 8,  9, 10, 11]])
x[1:3, :] = 0 # 区域赋值
x
# tensor([[ 0,  1,  2,  3],
#         [ 0,  0,  0,  0],
#         [ 0,  0,  0,  0]])

16. 内存

运行一些操作可能会导致为新结果分配内存。 例如,如果我们用Y = X + Y,我们将取消引用Y指向的张量,而是指向新分配的内存处的张量。

python
before = id(Y)
Y = Y + X
id(Y) == before
  • 原地操作 执行原地操作非常简单
python
Z = torch.zeros_like(Y) # 创造一个和Y形状相同的全0张量
print('id(Z):', id(Z))
Z[:] = X + Y
print('id(Z):', id(Z))

如果在后续计算中没有重复使用X, 我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销。

python
before = id(X)
X += Y
id(X) == before

17. 转换为其他Python对象

Numpy 是python中最基础的框架

python
A = X.numpy()
B = torch.tensor(A) # 将numpy数组转换为torch张量
type(A), type(B)
# (numpy.ndarray, torch.Tensor)
  • 将大小为1的张量转换为Python标量
python
a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
# (tensor([3.5000]), 3.5, 3.5, 3)

京ICP备2024093538号-1