常用的tensor操作
- 形状改变家族(view,squeeze,unsqueeze,reshape):该方法可以改变tensor的形状,但必须要保证调整前后元素的一致性。view不会修改自身的数据,返回新的tensor与原来的tensor共享内存,只要更改其中的一个,另外一个也会随着改变。当然,这里也就引出了在深度学习模型中常用到的unsqueeze和squeeze,一个是将维数增加,一个是将维度压缩。
a = torch.arange(6)
print(a)
a.view(2,3)
输出:tensor([0, 1, 2, 3, 4, 5])
tensor([[0, 1, 2],
[3, 4, 5]])
b = a.view(-1,3)#-1是自适应的作用
b:tensor([[0, 1, 2],
[3, 4, 5]])
b = b.unsqueeze(0)#在0这个维度增加
b.size()
b:torch.Size([1, 2, 3])
b = b.squeeze(0)#在0这个维度压缩
b.size()
b:torch.Size([2, 3])
由于一些tensor在内存上是不连续的,无法执行view操作,所以我们经常看到tensor.contiguous().view(-1)。解决的办法是resize()该方法将contiguous()方法封装在里面,省去了将内存连续的操作。
下面介绍一下什么叫共享内存,这对于像我这样的初学者来说没有直观的感受,说白了,就是两个变量指向同一个物理地址(即内存),改变其中的一个变量导致了内存空间中的数据的变化,另外一个也会改变,废话不多说,举个栗子:
a = t.rand(2,3)
b = a
print(a)
a:tensor([[0.8543, 0.8587, 0.9426],
[0.3482, 0.2721, 0.3712]])
a[0,0]=10000
print(a)
a:tensor([[1.0000e+04, 8.5874e-01, 9.4255e-01],
[3.4824e-01, 2.7212e-01, 3.7116e-01]])
print(b)
b:tensor([[1.0000e+04, 8.5874e-01, 9.4255e-01],
[3.4824e-01, 2.7212e-01, 3.7116e-01]])
可以发现b的值也改变了!!!!!!!
2. 归并操作家族:该类操作可以对tensor的某个维度进行归并操作。
函数 | 功能 |
---|---|
mean/sum/median/mode | 均值/和/中位数/众数 |
norm/dist | 范数/距离 |
std/var/cumsum/cumprod | 标准差/方差/累加/累乘 |
注意在对某个维度的元素进行归并操作时,keepdim的作用,设为True则保留维度,False则删除维度,如下:
b = t.ones(2,3)
b = b.sum(dim=0,keepdim=True)
print(b.size())
》》》torch.Size([1, 3])
b = t.ones(2,3)
b = b.sum(dim=0,keepdim=False)
print(b.size())
》》》torch.Size([3])
- 逐元素家族:对tensor中的每一个元素同时进行变化。
函数 | 功能 |
---|---|
abs/sqrt/div/exp/fmod/log/pow… | 绝对值/平方根/除/指数/求余/对数/幂 |
cos/sin/asin/atan2/cosh | 三角函数 |
ceil/round/floor/trunc | 上取整/四舍五入/下取整/只保留整数部分 |
clamp(input,min,max) | 夹断 |
- 线性代数家族
函数 | 功能 |
---|---|
trace/diag/triu/tril | 对角线元素之和/对角线元素/矩阵的上三角/下三角 |
mm/bmm | 矩阵乘法/batch的矩阵乘法 |
t/dot/cross/inverse/svd | 转置/内积/外积/求逆矩阵/奇异值分解 |