系列文章目录
一、Tensor(张量)基本概念
- 理解标量、向量、矩阵、张量
简单来说,张量是一个更加泛化的概念,包含了标量(0维张量)、向量(1维张量)、矩阵(2维张量)等数学概念。 - Tensor的属性
- dtype:数据类型(int、float等)
- device:Tensor的存储设备(cpu、gpu)
- layout:稠密张量、稀疏张量(torch.sparse_to_tensor)
- Tensor的算术运算
- 加减乘除:
- 哈达玛积(对应元素相乘)
C = A*B
C = torch.mul(a,b) - 矩阵运算
操作符:torch.mm()、torch.matmul()、@ - 高维tensor
Tensor(dim>2),定义其矩阵乘法仅在最后两个维度上,要求前面的维度必须保持一致
操作符:torch.matmul()
- 哈达玛积(对应元素相乘)
- 幂、开方、对数运算:
- 加减乘除:
print('幂运算')
a = torch.tensor([1.,2.])
b = torch.tensor([2.,3.])
c1 = a ** b
c2 = torch.pow(a, b)
print(c1,c2)
>>> tensor([1., 8.]) tensor([1., 8.])
import numpy as np
print('对数运算')
a = torch.tensor([2,10,np.e])
print(torch.log(a))
print(torch.log2(a))
print(torch.log10(a))
-
in-place
- 不允许使用临时变量
- x = x + y
- eg. add_、sub_、mul_等等
-
广播机制
- 张量参数可以自动扩展为相同大小(满足两个条件)
- 每个张量至少有一个维度
- 满足右对齐
- eg. torch.rand(2,1,1,3)与 torch.rand(1,3,2,3)
从右数,每个相同位置的维度 相等 or 为1 - eg.torch.rand(2,2,3) 与 torch.rand(3)
torch.rand(3) == torch.rand(1,1,3)
- 张量参数可以自动扩展为相同大小(满足两个条件)
-
近似值运算
a = torch.tensor(1.2345)
# .ceil() 向上取整
print(a.ceil())
>>>tensor(2.)
# .floor()向下取整
print(a.floor())
>>> tensor(1.)
# .trunc()取整数
print(a.trunc())
>>> tensor(1.)
# .frac()取小数
print(a.frac())
>>> tensor(0.2345)
# .round()四舍五入
print(a.round())
>>> tensor(1.)
- 比较运算
- torch.eq(input1,input2,out = None):按照成员进行等式操作,返回位置True or False
- torch.equal(input1,input2,out = None): 两个Tensor是否完全想通过,返回True or False
- torch.ge(input1,input2,out = None): # input1 > = input2
- torch.gt(input1,input2,out = None): # input1 > = input2
- torch.le(input1,input2,out = None): # input1 < =input2
- torch.lt(input1,input2,out = None): # input1 < input2
- torch.ne(input1,input2,out = None): # input1 ! = input2
- torch.sort(input,dim = None, descending = False, out = None) #对Tensor按照dim排序
- torch.topk(input, k, dim=None, largest=True, sorted=True) # 按照指定维度返回最大k个数值及其索引
# torch.topk()
import torch
output = torch.tensor([[-5.4783, 0.2298],
[-4.2573, -0.4794],
[-0.1070, -5.1511],
[-0.1785, -4.3339]])
maxk = max((1,)) # 取top1准确率,若取top1和top5准确率改为max((1,5))
value, index = output.topk(maxk, 1, True, True)
print(value)
tensor([[ 0.2298],
[-0.4794],
[-0.1070],
[-0.1785]])
print(index)
pred
tensor([[1],
[1],
[0],
[0]])
- torch.kthvalue(input,k,dim = None,out = None) # 沿着指定维度返回第k个最小值及其索引值
a = torch.rand(4,10)
: tensor([[0.4992, 0.4095, 0.5239, 0.8184, 0.3184, 0.6433, 0.2028, 0.1133, 0.6991,0.3260],
[0.1473, 0.2765, 0.1476, 0.2192, 0.8490, 0.7610, 0.0072, 0.6767, 0.1496, 0.2772],
[0.0691, 0.4229, 0.6794, 0.9665, 0.3935, 0.9259, 0.3509, 0.6875, 0.8682, 0.0592],
[0.2496, 0.3506, 0.8447, 0.2141, 0.4849, 0.2772, 0.3786, 0.6603, 0.8913, 0.1118]])
a.kthvalue(8,dim=1)# 第八小的值,在这里就是第三大的值
:(tensor([0.6433, 0.6767, 0.8682, 0.6603]), tensor([5, 7, 8, 7]))
a.kthvalue(8)
:(tensor([0.6433, 0.6767, 0.8682, 0.6603]), tensor([5, 7, 8, 7]))
二、Tensor(张量)统计学方法
-
统计函数
-
分布函数
-
随机抽样
- 定义随机种子 torch.manual_seed(seed)
功能等同于python random的随机种子,约束随机抽样 - 定义随机数满足的分布 torch.normal()
- 定义随机种子 torch.manual_seed(seed)
三、Tensor(张量)基本操作
- 范数运算(正则项)
-
l1 正则 产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择
-
l2 l正则 防止模型过拟合(overfitting);一定程度上,L1也可以防止过拟合
-
在泛函分析中,它定义在赋范线性空间中,并满足一定的条件,即:
- 非负性
- 齐次性
- 三角不等式
-
常用来度量向量空间(或矩阵)中的每个向量的长度或大小。
- torch.dist(self: Tensor, other: Tensor, p: Number=2)
两个向量或矩阵之间的相似性 - torch.norm(input, p=“fro”, dim=None, keepdim=False, out=None, dtype=None):
针对一个向量或矩阵
- torch.dist(self: Tensor, other: Tensor, p: Number=2)
-
x = torch.randn(4)
y = torch.randn(4)
torch.dist(x, y, 3)
torch.norm(x)
- 矩阵分解
常见的矩阵分解- LU分解:将矩阵A分解成一个L下三角矩阵和一个U上三角矩阵的乘积
- QR分解:将矩阵分解成一个正交矩阵和一个上三角矩阵的乘积
- EVD分解:将矩阵分解为 特征值*特征向量特征值分解 eg.PCA
PCA过程:
计算协方差矩阵
对协方差矩阵进行特征分解(对角化)
选择特征值绝对值最大的特征值对应的特征向量作为转换矩阵,将原始数据降维。 - SVD分解:eg.LDA
- Tensor的裁剪运算
- 对Tensor中的元素进行范围过滤(缩小解空间)
- 常用于梯度裁剪(gradient clipping),处理梯度爆炸、梯度消失
- eg.
a.clamp(2,10)
- Tensor的索引和数据筛选
- Tensor的组合/拼接
# cat
import torch
a = torch.zeros((2, 4))
b = torch.ones((2, 4))
out1 = torch.cat((a,b),dim = 0)
print(out)
tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
out2 = torch.cat((a,b),dim = 1)
print(out)
tensor([[0., 0., 0., 0., 1., 1., 1., 1.],
[0., 0., 0., 0., 1., 1., 1., 1.]])
# stack
a = torch.linspace(1,6,6).view(2, 3)
b = torch.linspace(7,12,6).view(2, 3)
print(a)
print(b)
out = torch.stack((a,b),dim=0)
print(out)
print(out.shape)
# dim=0
tensor([[1., 2., 3.],
[4., 5., 6.]])
tensor([[ 7., 8., 9.],
[10., 11., 12.]])
tensor([[[ 1., 2., 3.],
[ 4., 5., 6.]],
[[ 7., 8., 9.],
[10., 11., 12.]]])
torch.Size([2, 2, 3])
# dim=1
out = torch.stack((a,b),dim=1)
print(out)
print(out.shape)
tensor([[[ 1., 2., 3.],
[ 7., 8., 9.]],
[[ 4., 5., 6.],
[10., 11., 12.]]])
torch.Size([2, 2, 3])
-
Tensor切片
- torch.chunk(tensor,chunks,dim=0):按照某个维度平均切块(最后一个chunk会小于平均值)
- torch.split(tensor,split_size_or_sections,dim=0):按照某个维度,依照第二个参数给出的list或者int进行切割tensor
-
Tensor的张量变形
-
Tensor的张量填充
torch.full((2,3),3.14)
>> tensor([[3.1400, 3.1400, 3.1400],
[3.1400, 3.1400, 3.1400]])
- Tensor的频谱操作(时域信号与频率信号的转换)
- Tensor与numpy的相互转换
# numpy to torch
a = np.zeros([2,2])
out = torch.from_numpy(a)
# torch to numpy
b = out.numpy()
总结
整理了 PyTorch中 Tensor 的基本概念以及基础的函数操作。