入门
这一小节是基本操作,要掌握!
导入库:
import torch
本文所有代码段属于同一python文件。
需要做两件重要的事:
- 获取数据;
- 将数据读入计算机后对其进行处理
张量(tensor),即nnn维数组。
- 创建一个111维数组(向量),默认元素的数据类型时整数
int64,加入参数dtype=torch.float可改为浮点数:
x = torch.arange(12)
print('x:',x)
print('x的元素数据类型:', x.dtype)
运行结果:
x: tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
x的元素数据类型: torch.int64
拓展:torch.arange()的进阶用法torch.arange(1, 12, 2)会生成什么,其规律是什么?
生成 tensor([ 0, 2, 4, 6, 8, 10, 11]),规律:以111为起始值,12−112-112−1为终止值,步长为二生成一位输入(向量)。
- 查看张量形状:
print('x.shape', x.shape)
运行结果:
x.shape torch.Size([12])
- 查看张量元素的总数:
print('x元素总数', x.numel())
运行结果:
x元素总数 12
- 改变张量形状,重点说明一下,虽然张量的形状发生了改变,但其元素值和数量并没有变,也解释说各维度之积要一致:
X = x.reshape(3, 4)
print(X)
运行结果:
X: tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
拓展:x和X指向一样的数据,但是他们与哦不同的维度信息,如图:![[Pasted image 20220326171749.png]]
- 指定维度,生成元素全为零的张量:
print(torch.zeros((1, 2, 3)))
运行结果:
tensor([[[0., 0., 0.],
[0., 0., 0.]]])
- 指定维度,生成元素全为1的张量:
print(torch.ones((1, 2, 3)))
运行结果:
tensor([[[1., 1., 1.],
[1., 1., 1.]]])
- 指定维度,生成**元素服从标准正态分布(随机)**张量:
print(torch.randn(3, 4))
运行结果:
tensor([[ 0.0847, -1.3477, -0.3928, 0.1887],
[ 0.0056, -0.9155, 0.3376, 0.9903],
[-0.3440, -0.8092, -1.3417, -0.2063]])
- 传入列表生成张量:
torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
运行结果:
tensor([[2, 1, 4, 3],
[1, 2, 3, 4],
[4, 3, 2, 1]])
运算符
两个形状相同的张量的四则运算+ - * /*和求幂**都是针对这两个张量的单个元素,对应位置元素进行运算,由每对元素运算的结果合为的张量作为两个张量的运算结果。要能区分出按元素计算!
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
print('x * y:', x * y)
运行结果:
x * y: tensor([ 2., 4., 8., 16.])
此外还有其他按元素运算的操作(比较运算也是典型的按元素运算),如求exe^xex:
print('e^x:', torch.exp(x))
运行结果:
e^x: tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])
- 张量连结,只需要提供张量列表,并给出沿哪个轴连结:
X = torch.tensor([[1,2,3], [4,5,6]])
Y = torch.tensor([[7, 8, 9], [10, 11, 12]])
print('cat dim=0', torch.cat((X, Y), dim=0))
print('cat dim=1', torch.cat((X, Y), dim=1))
运行结果:
cat dim=0 tensor([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
cat dim=1 tensor([[ 1, 2, 3, 7, 8, 9],
[ 4, 5, 6, 10, 11, 12]])
- 元素求和,即求张量的所元素之和,或这指定维度,在这个维度上求元素和:
x=torch.arange(12).reshape(3, 4)
print(x)
print('x.sum():', x.sum()) # 求所有元素之和
print('x.sum(dim=1)', x.sum(dim=1)) # 在1维度上求元素和
运行结果:
cat dim=0 tensor([[ 1, 2, 3],
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
x.sum(): tensor(66)
x.sum(dim=1) tensor([ 6, 22, 38])
广播机制
在某些情况下(不讨论这些情况,大概知道广播机制即可),即使形状不同,我们仍然可以通过调用 广播机制(broadcasting mechanism)来执行按元素操作。
首先,通过适当复制元素来扩展一个或两个数组, 以便在转换之后,两个张量具有相同的形状。 其次,对生成的数组执行按元素操作。
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
print('a:', a)
print('b:', b)
print('a+b:', a+b)
运算结果:
a: tensor([[0],
[1],
[2]])
b: tensor([[0, 1]])
a+b: tensor([[0, 1],
[1, 2],
[2, 3]])
注解:a是3×13\times 13×1的矩阵,b是1×21\times 21×2的矩阵,广播机制会将a复制列,将b复制行,使他们扩大成3×23\times 23×2的矩阵,再按元素相加。
切片和索引
在python和pytorch中,-1表示最末元素,0表示首元素。使用0:4表示取第0个到第3个元素。
- 利用切片索引访问(包含修改)元素:
print(X)
print(X[-1]) # 第0个维度上的最后一个元素
print(X[0,1:3]) # 第0个维度上的第0个元素的第1到2个元素
X[:] = 0 # 将X的所有元素赋值为零
print(X)
运算结果:
tensor([[1, 2, 3],
[4, 5, 6]])
tensor([4, 5, 6])
tensor([2, 3])
tensor([[0, 0, 0],
[0, 0, 0]])
节省内存
id(ob)会返回ob的“内存地址”,具有唯一性。因而可以利用它来判断两个对象是否指向同一内存空间。
zeros_like(Y)将生成一个元素全为0,形状与Y一样的张量,类似的还有ones_like。
节省内存主要想强调的是原地操作,即将计算结果存入原来的内存(计算的输入)。
转换为其他Python对象
- 将
pytorch定义的张量转换为NumPy张量(ndarray):
print('X\'class:', type(X))
A = X.numpy()
print('A\'class:', type(A))
运行结果:
X'class: <class 'torch.Tensor'>
A'class: <class 'numpy.ndarray'>
- Numpy张量(
ndarray)转换为pytorch定义的张量:
B = torch.tensor(A)
print('B\'class:', type(B))
运行结果:
B'class: <class 'torch.Tensor'>
本文是本人看李沐大佬的https://zh.d2l.ai/chapter_preliminaries/ndarray.html的笔记,供一部分伙伴参考。
本文介绍PyTorch的基础操作,包括张量的创建、运算、索引及转换等。涵盖张量的基本概念、数据类型、形状操作、广播机制等内容。

被折叠的 条评论
为什么被折叠?



