PyTorch基础语法大全

一、创建 Tensor

1.1 torch.empty(5, 3)

创建一个大小为 5*3 未初始化的 Tensor:

x = torch.empty(5,3)

输出为:

tensor([[8.4490e-39, 9.6429e-39, 9.2755e-39],
        [1.0286e-38, 9.0919e-39, 8.9082e-39],
        [9.2755e-39, 8.4490e-39, 9.2755e-39],
        [9.6429e-39, 9.6429e-39, 9.3674e-39],
        [1.0469e-38, 1.0102e-38, 9.2755e-39]])
1.2 torch.rand(5, 3)

创建一个大小为 5*3 随机初始化的 Tensor:

x = torch.rand(5, 3)

输出为:

tensor([[0.9481, 0.9788, 0.6261],
        [0.3213, 0.4617, 0.4188],
        [0.1769, 0.4106, 0.5583],
        [0.5643, 0.5224, 0.8899],
        [0.4977, 0.0276, 0.7517]])
1.3 torch.zeros(5, 3)

创建一个大小为 5x3 且指定数据类型为 long 型值全 0 的 Tensor:

x = torch.zeros(5, 3, dtype=torch.long)

输出为:

tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])
1.4 torch.tensor([5.5, 3])

根据数据直接创建 Tensor:

x = torch.tensor([5.5, 3])

输出为:

tensor([5.5000, 3.0000])
1.5 new_ones

根据现有 Tensor 创建。

x = x.new_ones(5, 3, dtype=torch.float64)  
# 返回的tensor默认具有相同的torch.dtype和torch.device
# 得到的x为:
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)


x = torch.randn_like(x, dtype=torch.float) 
# 指定新的数据类型
# 得到的x为:
tensor([[ 0.6035,  0.8110, -0.0451],
        [ 0.8797,  1.0482, -0.0445],
        [-0.7229,  2.8663, -0.5655],
        [ 0.1604, -0.0254,  1.0739],
        [ 2.2628, -0.9175, -0.2251]])
1.6 shape/size()

获取 Tensor 的形状:

print(x.size())
print(x.shape)

# 输出都为:
torch.Size([5, 3]) # 返回的torch.Size是一个tuple, 支持所有tuple的操作。
1.7 其余创建 Tensor 操作
函数 功能
Tensor(*sizes) 基础构造函数
tensor(data,) 类似np.array的构造函数
ones(*sizes) 全1Tensor
zeros(*sizes) 全0Tensor
full(*sizes,data) 值全为data,大小为sizes
ones_like(tensor) 值全为1,大小和指定的tensor相同
eye(*sizes) 对角线为1,其他为0
arange(s,e,step) 从s到e,步长为step
linspace(s,e,steps) 从s到e,均匀切分成steps份
rand/randn(*sizes) 均匀/标准分布
normal(mean,std)/uniform(from,to) 正态分布/均匀分布
randperm(m) 随机排列

这些创建方法都可以在创建的时候指定数据类型dtype和存放设备device(CPU/GPU)。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
x = torch.tensor([1,1,1],dtype=torch.float64, device =device)

二、算术操作

两个 Tensor 进行加减乘除算术操作时会自动进行Broadcasting。

2.1 torch.add(x, y)

加法运算。

还可以指定输出:

result = torch.empty(5, 3)
torch.add(x, y, out=result)
2.2 torch.sub(x, y)

减法运算。

2.3 torch.mul(x, y)

对应元素相乘。

2.4 torch.div(x, y)

除法运算。

2.5 torch.mm()、torch.matmul()、@

矩阵相乘。

import torch
a = torch.ones(2, 1)
b = torch.ones(1, 2)
print(torch.mm(a, b).shape)
print(torch.matmul(a, b).shape)
print((a @ b).shape)

# 输出:
torch.Size([2, 2])
torch.Size([2, 2])
torch.Size([2, 2])

注意:对于高维的Tensor(dim>2),定义其矩阵乘法仅在最后的两个维度上,要求前面的维度必须保持一致,就像矩阵的索引一样并且运算操作语法只有torch.matmul()。(前面的"矩阵索引维度"如果符合Broadcasting机制,也会自动做广播,然后相乘)

c = torch.rand(4, 3, 28, 64)
d = torch.rand(4, 3, 64, 32)
print(torch.matmul(c, d).shape)

# 输出:
torch.Size([4, 3, 28, 32])

c = torch.rand(4, 3, 28, 64)
d = torch.rand(4, 1, 64, 32)
print(torch.matmul(c, d).shape) # 自动广播

# 输出:
torch.Size([4, 3, 28, 32])
2.6 .pow(2)

幂运算。

a = torch.full([2, 2], 3, dtype=torch.long)
b = a.pow(2)  # 也可以a**2
print(b)
tensor([[9., 9.],
        [9., 9.]])
2.7 .sqrt()

开方运算。

c = b.sqrt()  # 也可以a**(0.5)
tensor([[3., 3.],
        [3., 3.]])

d = b.rsqrt()  # 平方根的倒数
tensor([[0.3333, 0.3333],
        [0.3333, 0.3333]])
2.8 torch.exp()、torch.log()

指数和对数运算。

import torch
 
a = torch.exp(torch.ones(2, 2))  # 得到2*2的全是e的Tensor
print(a)
print(torch.log(a))  # 取自然对数
tensor([[2.7183, 2.7183],
        [2.7183, 2.7183]])
tensor([[1., 1.],
        [1., 1.]])

注意 log 是以自然对数为底数的,以2为底的用log2,以10为底的用 log10。

2.9 其他运算
函数 功能
.floor() 取下
.ceil() 取上
.trunc() 取整数
.frac() 取小数
.round() 四舍五入
.max() 最大值
.min() 最小值
.abs() 绝对值
.median() 平均值
.clamp(10) 裁剪运算,小于10的都变成10
.clamp(3, 10) 裁剪运算,小于3的变成3,大于10的变成10

三、索引

可以使用类似NumPy的索引操作来对Tensor进行索引,需要注意的是:索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。

y = x[0, :]
y += 1
print(y)
print(x[0, :]) # 源tensor也被改了

输出为:

tensor([1.6035, 1.8110, 0.9549])
tensor([1.6035, 1.8110, 0.9549])

一些索引高级函数:

函数 功能
index_select(input, dim, index) 在指定维度dim上选取,比如选取某些行、某些列
masked_select(input, mask) 例子如上,a[a>0],使用ByteTensor进行选取
nonzero(input) 非0元素的下标
gather(input, dim, index) 根据index,在dim维度上选取数据,输出的size与index一样

四、改变形状

4.1 view()

用 view() 函数来改变 Tensor 的形状。

y = x.view(15)
z = x.view(-1, 5)  # -1所指的维度可以根据其他维度的值推出来
print(x.size(), y.size(), z.size())

# 输出
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])

注意:view()返回的新Tensor与源Tensor虽然可能有不同的size,但是是共享data的,也即更改其中的一个,另外一个也会跟着改变。(view仅仅是改变了对这个张量的观察角度,内部数据并未改变。)

4.2 clone()、reshape()

如果想返回一个真正新的副本(即不共享data内存):

Pytorch还提供了一个reshape()可以改变形状,但是此函数并不能保证返回的是其拷贝,所以不推荐使用推荐先用clone创造一个副本然后再使用view。

x_cp = x.clone().view(15)

使用clone还有一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源Tensor。

4.3 item()

将一个标量 Tensor 转换成一个 Python number。

x = torch.randn(1)
print(x)
print(x.item())
tensor([2.3466])
2.3466382026672363

五、线性代数

PyTorch还支持一些线性函数,具体用法参考官方文档。如下表所示:

函数 功能
trace 对角线元素之和(矩阵的迹)
diag 对角线元素
triu/tril 矩阵的上三角/下三角,可指定偏移量
mm/bmm 矩阵乘法,batch的矩阵乘法
addmm/addbmm/addmv/addr/baddbmm… 矩阵运算
t 转置
dot/cross 内积/外积
inverse 求逆矩阵
svd 奇异值分解

六、广播机制

当对两个形状不同的Tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个Tensor形状相同后再按元素运算。


七、Tensor和Numpy转换

用numpy()和from_numpy()可以将Tensor和NumPy中的数组相互转换。但是需要注意的一点是: 这两个函数所产生的的Tensor和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中一个时另一个也会改变

7.1 Tensor转Numpy
a = torch.ones(5)
b = a.numpy()
7.2 Numpy转Tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)

此外上面提到还有一个常用的方法就是直接用torch.tensor()将NumPy数组转换成Tensor,需要注意的是该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存


八、在GPU上操作

用方法to()可以将Tensor在CPU和GPU(需要硬件支持)之间相互移动。

# 以下代码只有在PyTorch GPU版本上才会执行
if torch.cuda.is_available():
    device = torch.device("cuda")          # GPU
    y = torch.ones_like(x, device=device)  # 直接创建一个在GPU上的Tensor
    x = x.to(device)                       # 等价于 .to("cuda")
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # to()还可以同时更改数据类型
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
x = torch.tensor([1,1,1,1],dtype=torch.float64, device =device)

猜你喜欢

转载自blog.csdn.net/qq_40585800/article/details/108672533