引言
疫情正当时,在家办公的时候对自己也不能太放松,正好年前学习了很多大数据生态以及机器学习相关的内容,感觉自己达到了一个瓶颈,正需要动手来慢慢消化。接下来就使用pytorch来一步步的实践自己的学习。
首先第一篇文章用来持续记录在进行深度学习开发过程中常用的PyTorch方法,方便后期遗忘时翻阅。
Tensor
创建5x3的未初始化的Tensor
x = torch.empty(5, 3)
创建5x3的随机初始化的Tensor
x = torch.rand(5, 3)
创建5x3的long类型全0的Tensor
x = torch.zeros(5, 3, dtype=torch.long)
创建5x3的float32类型全1的Tensor
x = torch.ones(5, 3, dtype=torch.float32)
创建5x3的float32类型对角线是1的Tensor
x = torch.eye(5, 3, dtype=torch.float32)
常用函数:
函数 | 功能 |
---|---|
Tensor(*sizes) | 基础构造函数 |
tensor(data,) | 类似np.array的构造函数 |
ones(*sizes) | 全1Tensor |
zeros(*sizes) | 全0Tensor |
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) | 随机排列 |
点乘
使用torch.mul方法实现,也可直接使用*。当维度不同时,会触发广播机制。
>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
>>> b = torch.Tensor([1,2,3]).reshape((3,1))
>>> b
tensor([[1.],
[2.],
[3.]])
>>> torch.mul(a, b)
tensor([[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.]])
矩阵乘
torch.mm和torch.matmul两个函数都是用来计算矩阵相乘。mm是处理二维矩阵,超过二维将报错;matmul是处理高维。
# 二维乘二维
>>> a = torch.ones(3,4)
>>> b = torch.ones(4,2)
>>> torch.mm(a, b)
tensor([[4., 4.],
[4., 4.],
[4., 4.]])
# 二维乘三维
>>> a = torch.ones(3,4)
>>> b = torch.ones(5,4,2)
>>> torch.matmul(a, b).shape
torch.Size([5, 3, 2])
# 三维乘三维
>>> a = torch.ones(5,4,2)
>>> b = torch.ones(5,2,3)
>>> torch.matmul(a, b).shape
torch.Size([5, 4, 3])
Tensor运算
推荐使用+,-,*,/ 计算。
等价于torch.add,torch.mul,torch.sub,torch.div
torch.pow(a, n) 表示a的n次方。
推荐使用 a ** n 也表示次方(可以是2,0.5,0.25,3)
exp(n) 表示:e的n次方
log(a) 表示:ln(a)
log2() 、 log10()
In[18]: a = torch.exp(torch.ones(2,2))
In[19]: a
Out[19]:
tensor([[2.7183, 2.7183],
[2.7183, 2.7183]])
In[20]: torch.log(a)
Out[20]:
tensor([[1., 1.],
[1., 1.]])
In[22]: torch.log2(a)
Out[22]:
tensor([[1.4427, 1.4427],
[1.4427, 1.4427]])
In[23]: torch.log10(a)
Out[23]:
tensor([[0.4343, 0.4343],
[0.4343, 0.4343]])
floor、ceil 向下取整、向上取整
round 4舍5入
trunc、frac 裁剪
In[24]: a = torch.tensor(3.14)
In[25]: a.floor(),a.ceil(),a.trunc(),a.frac()
Out[25]: (tensor(3.), tensor(4.), tensor(3.), tensor(0.1400))
In[26]: a = torch.tensor(3.499)
In[27]: a.round()
Out[27]: tensor(3.)
In[28]: a = torch.tensor(3.5)
In[29]: a.round()
Out[29]: tensor(4.)
tensor变换形状
y = x.view(15)
z = x.view(-1, 5) # -1所指的维度可以根据其他维度的值推出来
print(x.size(), y.size(), z.size())
注意view()返回的新Tensor与源Tensor虽然可能有不同的size,但是是共享data的,也即更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变)
x_cp = x.clone().view(15) # 不共享数据
x -= 1
print(x)
print(x_cp)
Numpy转Tensor
除chartensor外所有tensor都可以转换为numpy
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
Tensor转Numpy
需要注意,转换后的tensor与numpy指向同一地址,所以,对一方的值改变另一方也随之改变
a = torch.ones(5)
b= a.numpy()
高级函数:
函数 | 功能 |
---|---|
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一样 |
线性代数
函数 | 功能 |
---|---|
trace | 对角线元素之和(矩阵的迹) |
diag | 对角线元素 |
triu/tril | 矩阵的上三角/下三角,可指定偏移量 |
mm/bmm | 矩阵乘法,batch的矩阵乘法 |
addmm/addbmm/addmv/addr/baddbmm… | 矩阵运算 |
t | 转置 |
dot/cross | 内积/外积 |
inverse | 求逆矩阵 |
svd | 奇异值分解 |