PyTorch张量运算与自动微分

PyTorch张量运算与自动微分

PyTorch由Facebook人工智能研究院于2017年推出,具有强大的GPU加速张量计算功能,并且能够自动进行微分计算,从而可以使用基于梯度的方法对模型参数进行优化,大部分研究人员、公司机构、数据比赛都使用PyTorch。

张量创建

在深度学习领域你会经常看到张量(Tensor)的表述,张量是深度学习的基础,所以谷歌会把他的深度学习框架叫做TensorFlow。深度学习中的张量可以理解成数组,类似numpy的array。例如:

  • 单个数字就是0维张量,称为标量(scalar);
  • 1维张量称为向量(vector);
  • 2维张量称为矩阵(matrix);
  • 再多点维度就统一称作张量了。

高等代数中学习过矩阵运算,就是最基本的张量运算。

在用Transformers时最常见的是二维和三维张量。二维张量一般是权重矩阵W等,三维张量一般是原数据处理成序列长度模型维度batchsize×序列长度×模型维度。

在描述张量维度时,或者创建多维张量时,你会经常看到 W ∈ R d m × d k × d h W\in\mathbb{R}^{d_m \times d_k \times d_h} W∈Rdm×dk×dh这种类似表述,用几行几列这样的方式去理解的话,相当不直观。

一种直观理解就是用类似多维数组的思想,用"框的数量"来理解。

d m × d k × d h d_m \times d_k \times d_h dm×dk×dh代表最大一个框包着m个框、再下一层有k个,最里层有h个。

第零维m个框:

m 个 [ [ . . . ] , [ . . . ] , . . . , [ . . . ] ⏞ ] \begin{array}{c} m个 \\ [\overbrace{[...],[...],...,[...]}] \end{array} m个[[...],[...],...,[...] ]

第一维k个框

k 个 [ [ [ . . . ] , . . . , [ . . . ] ⏞ ] , . . . , ] \begin{array}{} k个 \\ [[\overbrace{[...],...,[...]}],...,] \end{array} k个[[[...],...,[...] ],...,]

第二维h个框

h 个 [ [ [ [ . . . ] , . . . , [ . . . ] ⏞ ] , . . . ] , . . . ] \begin{array}{} h个 \\ [[[\overbrace{[...],...,[...]}],...],...] \end{array} h个[[[[...],...,[...] ],...],...]

Pytorch张量操作

PyTorch提供了多种方式来创建张量,以创建一个2×3的矩阵为例:

python 复制代码
import torch
# empty作用就是初始化一块内存放着,里面数据不重要,根本不会用
t = torch.empty(2, 3)
# 随机初始化张量,范围是[0,1)
t = torch.rand(2, 3)
# 随机初始化张量,服从标准正态分布
t = torch.randn(2, 3)
# 全0矩阵,其中的0是长整型,也可以换成torch.double、torch.float64
t = torch.zeros(2, 3, dtype=torch.long)
# 同理有全1矩阵
t = torch.ones(2, 3, dtype=torch.long)

上面比较常用的是全0和全1,对判断真假很有用。也可以从一个张量创造维度相同的张量:

python 复制代码
import torch
t = torch.empty(2, 3)
x = torch.rand_like(a)
x = torch.randn_like(a)
x = torch.zeros_like(a)
x = torch.ones_like(a)

也可以通过基于已有的数组创建张量:

python 复制代码
# 从列表
_list = [[1.0, 3.8, 2.1], [8.6, 4.0, 2.4]]
t = torch.tensor(_list)
# 从ndarray
import numpy as np
array = np.array([[1.0, 3.8, 2.1], [8.6, 4.0, 2.4]])
t = torch.from_numpy(array)

这样创建的张量默认在CPU ,将其调入GPU有如下方式:

python 复制代码
t = torch.empty(2, 3).cuda()
t = torch.empty(2, 3, device="cuda")
t = torch.empty(2, 3).to("cuda")

默认是使用当前第0张卡,指定用第1张卡:

python 复制代码
t= torch.empty(2, 3).cuda(1)
t= torch.empty(2, 3, device="cuda:1")
t= torch.empty(2, 3).to("cuda:1")

对应的可以调入CPU

python 复制代码
t = torch.empty(2, 3).cpu()
t = torch.empty(2, 3, device="cpu")
t = torch.empty(2, 3).to("cpu")

张量运算

张量的加减乘除、拆拼换调、特殊函数,都能在PyTorch找到快速方法。

加减乘除

python 复制代码
x = torch.rand(2, 3)
y = torch.rand(2, 3)
# 等价于x + y
z = torch.add(x, y)
# torch没有减方法,但是可以x - y
# 矩阵点乘,multiplication,Hadamard积,等价于x * y
z = torch.mul(x, y)
# 矩阵叉乘,矩阵乘法,matrix multiplication,等价于x @ y
z = torch.mm(x, y)
# 会报错,因为两者的维度不能做叉乘,需要如下转置
z = torch.mm(x, y.T)
# 三维对应矩阵乘法,batch matrix multiplication
x = torch.rand(2, 3, 4)
y = torch.rand(2, 4, 3)
z = torch.bmm(x, y)
# 更普遍的矩阵叉乘
z = torch.matmul(x, y)
# 除法不常用,但也可以x / y

广播机制

前面我们都是假设参与运算的两个张量形状相同,但是PyTorch同样可以处理不相同形状的张量。

python 复制代码
x = torch.ones(2, 3, 4)
y = torch.ones(1, 3, 4)
z = x + y

PyTorch会使得最外面的框维度相同,做法是复制,如上例的y复制一份变成2×3×4,然后以此类推使得前面的框框都相同,最后可以做相同维度运算。再来个更极端的例子:

python 复制代码
import torch
x = torch.ones(2, 1, 3, 4)
y = torch.ones(5, 4, 3)
z = torch.matmul(x, y)
print(z)

这么乱都能乘?耶斯。

  1. 首先来看,不乱的是最后两位的3×4和4×3和,刚好能做叉乘,好,所以结果的最后两位是3×3。
  2. 再看前面的维度,y少了框,先补最外面y变成2×5×4×3
  3. 这时第二维1的少了,复制成2×5×3×4,这样就可以乘了。

聪明的你要问,如果x第二维是3,复制不成5啊,那怎么办?怎么办?难办就别办了!答案就是会报错。

拆拼换调

这些方法几乎是最常用的,跟着我好好理解一遍哦。首先是拼接cat方法:

python 复制代码
x = torch.tensor([[1, 2, 3], [ 4,  5,  6]], dtype=torch.double)
y = torch.tensor([[7, 8, 9], [10, 11, 12]], dtype=torch.double)
z = torch.cat((x, y), dim=0)

看到dim=0了吗,根据框框理论,这是把第0维的几个框框拼起来,得到:

python 复制代码
tensor([[ 1.,  2.,  3.],
    [ 4.,  5.,  6.],
    [ 7.,  8.,  9.],
    [10., 11., 12.]], dtype=torch.float64)

dim=1,则是把第一个框框里的拼起来,得到:

python 复制代码
tensor([[ 1.,  2.,  3.,  7.,  8.,  9.],
    [ 4.,  5.,  6., 10., 11., 12.]], dtype=torch.float64)

拆分 就用索引与切片,操作如同list

python 复制代码
# 取第0维第1个框里的第2位,注意第X是从0开始
t = torch.randn(3, 4)
x = t[1, 2]
# 取第0维的前两项
x = t[0:2]
复制代码
相关推荐
KevinAha几秒前
django 实战(python 3.x/django 3/sqlite)
python·django·sqlite
Donvink4 分钟前
Transformers在计算机视觉领域中的应用【第3篇:Swin Transformer——多层次的Vision Transformer】
人工智能·深度学习·目标检测·计算机视觉·transformer
龙的爹233310 分钟前
2024论文翻译 | Multi-Review Fusion-in-Context
人工智能·深度学习·自然语言处理·prompt
梁小憨憨23 分钟前
变分推断(Variational Inference)
人工智能·算法·机器学习
是十一月末32 分钟前
Python语法之正则表达式详解以及re模块中的常用函数
开发语言·python·正则表达式
资讯分享周1 小时前
思特奇亮相2024数字科技生态大会,以“智”谋新共赢AI新时代
人工智能·科技
HuggingAI1 小时前
Stable Diffusion Controlnet常用控制类型解析与实战课程 2
人工智能·ai·stable diffusion·ai绘画
灵封~1 小时前
PythonQt练习
python
一尘之中1 小时前
基于Transformer的编码器-解码器图像描述模型在AMD GPU上的应用
人工智能·深度学习·transformer
IT古董2 小时前
【机器学习】机器学习的基本分类-监督学习-决策树-C4.5 算法
人工智能·学习·算法·决策树·机器学习·分类