Appearance
数据操作 (张量函数)
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()
# 12shape
[ ʃ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) == before17. 转换为其他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)