当前位置: 首页 > 工具软件 > Torch7 > 使用案例 >

Torch7入门续集(二)---- 更好的使用Math函数

史超英
2023-12-01

这个主要是提供了类似很多Matlab的函数。所有的math函数具有第一篇所说的两种调用方法等价的特性。

torch.log(x,x)  --将返回值存储x内
x:log() --返回一个值,此时x的值已经变成返回值了。

值得注意的是,能用第一种则尽量用第一种,因为math函数默认是要开辟一个新的空间来存储返回值的,而第一种方法则不需要,因此用第一种好。
由于这里的函数大部分类似matlab,所以默认大家已经学过matlab。。
Math函数介绍按照
构造 –>逐像素操作 —> 逐维度操作 —> Matrix-wide操作—>卷积操作 —> 矩阵分解等 —> 对Tensor进行逻辑操作

构造与抽取类函数

cat

-- 在第一维度上联合
> torch.cat(torch.ones(2, 2), torch.zeros(2, 2), 1)  
 1  1
 1  1
 0  0
 0  0
[torch.DoubleTensor of size 4x2]
--在第二维度上联合
> torch.cat(torch.ones(2, 2), torch.zeros(2, 2), 2)
 1  1  0  0
 1  1  0  0
[torch.DoubleTensor of size 2x4]

diag,eye, linespace, logspace

这个略。

ones,rand, randn,range

其中rand是生成均匀分布,而randn是生成均值为0,方差为1的正态分布。

randperm, reshape, zeros

element-wise的函数

abs, sign, acos, …各种三角函数,… ceil, floor, log,
log是以e为底的。
neg, cinv(这个是取1.0/x) , sqrt, sigmoid, tanh,

--trunc()截取整数部分
>k
  19.3070
  26.8270
  37.2759
  51.7947
  71.9686
 100.0000
[torch.DoubleTensor of size 8]

                                                                      [0.0001s]
th> k:trunc()
  10
  13
  19
  26
  37
  51
  71
 100
[torch.DoubleTensor of size 8]

Tensor操作的数学函数

equal

-- 加只有add,没有cadd(可能是看起来怪怪的)
-- 减只有csub,没有sub
csub  -- csub(value), csub(tensor2)
add  -- add(tensor,value)或者 add(tensor1,tensor2)

--乘法除法秉承:有“c”表示两个tensor进行逐个元素对应操作,
-- 没有"c"表示tensor与value进行操作。
[res] torch.mul([res,] tensor1, value)
[res] torch.cmul([res,] tensor1, tensor2)
[res] torch.div([res,] tensor, value)
[res] torch.cdiv([res,] tensor1, tensor2)

-- 一些常用的其他函数
[res] torch.cpow([res,] tensor1, tensor2)
> x = torch.Tensor(2, 2):fill(2)
> y = torch.Tensor(4):fill(3)
> x:cpow(y)
> x --每个位置均为2^3
 8  8
 8  8
[torch.DoubleTensor of size 2x2]
-- 左移右移操作
-- lshift, rshift, 相应的也有clshift和crshift
z = torch.lshift(x, 2)  -- x的每个元素 x<<2

-- 下面是分别左移1~4位
-- range是"左闭右闭"的
> x = torch.LongTensor(2, 2):fill(1)
> y = torch.LongTensor(2, 2):range(1, 4)
> x:clshift(y)
> x
 2  4
 8 16
[torch.LongTensor of size 2x2]

-- 矩阵的“点乘dot product(或者称为内积inner product)”与“矩阵乘法”与两个向量的外积(outer product或是cross product叉积, 向量积)
addr(vec1,vec2) -- 外积
ger([res],vec1,vec2) --也是外积,功能较上一个简单一点
dot(tensor1,tensor2)  --点乘
mv(mat,vec) -- 这个估计没什么人用。因为只是下面一种的特殊情况
mm(mat1,mat2)  -- 矩阵乘法
bmm(mat1,mat2) --这个适用于batch的tensor进行矩阵相乘

--线性插值 对于a和b两个向量或者两个数
[res] torch.lerp([res,] a, b, weight)
-- res = a + weight * (b - a)

运算符重载

注意:最好还是用前面的函数!因为这种重载速度会变慢!

x = 5 + torch.rand(3)  --出现错误,只有第一个操作数是tensor才能进行重载
-- 当然 + ,- , *, /, %都能重载咯。不推荐用。
> x = torch.Tensor(2, 2):fill(2)
> = x + 3
 5  5
 5  5
[torch.DoubleTensor of size 2x2]

dimension-wise 操作

cumprod与cumsum

一个很常用的较为高级的函数就是累加乘
[res] torch.cumprod([res,] x [,dim])

> A = torch.LongTensor{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}
> A
 1  4  7
 2  5  8
 3  6  9
[torch.LongTensor of size 3x3]

> B = torch.cumprod(A,1)  --默认沿着第一维(第一维度不断变化,其他维度下标不变,此为“沿着”含义)
> B  --比如 504 = 7*8*9
   1    4    7
   2   20   56
   6  120  504
[torch.LongTensor of size 3x3]

> B = torch.cumprod(A, 2)
> B
   1    4   28
   2   10   80
   3   18  162
[torch.LongTensor of size 3x3]

类似的,也有累加加。。好吧,个人翻译的有点难听啊。。反正没多少人看,。管他呢
[res] torch.cumsum([res,] x [,dim])

max,mean, min, median, prod

这个都类似,一般是
torch.max(x, n) 沿着n维进行某种操作。得到的是某一维度的最大值之类的,如果不加维度n,则返回所有元素的最大值之类的

> x = torch.randn(3, 3)
> x
 1.1994 -0.6290  0.6888
-0.0038 -0.0908 -0.2075
 0.3437 -0.9948  0.1216
[torch.DoubleTensor of size 3x3]

> torch.max(x)
1.1993977428735

> torch.max(x, 1)
 1.1994 -0.0908  0.6888
[torch.DoubleTensor of size 1x3]

prod表示沿着某一维计算所有元素的乘积。

> a = torch.Tensor{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}
> a
(1,.,.) =
  1  2
  3  4

(2,.,.) =
  5  6
  7  8
[torch.DoubleTensor of dimension 2x2x2]

> torch.prod(a, 1)
(1,.,.) =
   5  12
  21  32
[torch.DoubleTensor of dimension 1x2x2]

-- 当然了不加维度就可以计算所有元素的乘积
th> torch.prod(a)
40320

cmax, cmin

这个还是挺强大的。cmax是对两个tensor逐点进行比较,取其最大值!

> a = torch.Tensor{1, 2, 3}
> b = torch.Tensor{3, 2, 1}
> torch.cmax(a, b)
 3
 2
 3
[torch.DoubleTensor of size 3]

排序有关的函数

kthvalue直接返回第k小的元素

y, i = torch.kthvalue(x, k, n) 沿着n维度返回第k小的数据

topk返回k个最小的元素,未排序

sort排序,这个重要

y, i = torch.sort(x, d, true) --有true,则表示降序,默认升序

这些函数要注意的是返回y是相应的值,而i是坐标,存储的是LongStorage类型的。前面说过,Tensor就是将LongStorage类型的看成是有维度的。
要注意的特殊情况是,如果x不是一维的,那么返回的i是一个LongStrage的多维的值

th> a = torch.randn(5,1):mul(4):floor()
                                                                      [0.0001s]
th> a   --注意,a是2维的
-1
 0
-1
 9
-4
[torch.DoubleTensor of size 5x1]

                                                                      [0.0001s]
th> _,i = torch.sort(a,1)
                                                                      [0.0001s]
th> i   --此时i也是2维的
 5
 1
 3
 2
 4
[torch.LongTensor of size 5x1]

                                                                      [0.0001s]
th> i[1]
 5
[torch.LongTensor of size 1]

可以看到上面的 i[1]不是一个数!!所以如果你写 tb[i[1]]就会出错!然后你还不知道为什么错,因为潜意识认为a既然只有一列,那么i就是一个一维数据,i[1]就是一个数啊。那怎么改呢?
写成tb[i][1]!!这个故事告诉我们,弄清楚LongStorage, Tensor和number的关系很重要!

std与var

求某一维度的标准差和方差。略略

Matrix-wide 操作

norm, dist

y = torch.norm(x)   -- 默认F-范式,有些人错误的称之为2范式,其实错了。自己去查矩阵分析书。
y = torch.norm(x, p)  -- p-范式

y = torch.dist(x,y)   -- x-y的2范式,就是欧式距离
y = torch.dist(x,y,p) -- x-y的p-范式

numel,trace

numel和matlab的函数一样,就是表示矩阵中有多少个元素的
trace:矩阵的迹

卷积操作

这里的卷积值得是信号处理的卷积!就是先要将卷积核旋转180°,再卷。 如果是相关的话,则卷积核不旋转,直接卷。卷积用conv2,conv3, 相关xcoor2, xcoor3等。

require("torch")

local wt = torch.Tensor(2,2)
wt[{1,1}]=5
wt[{1,2}]=6
wt[{2,1}]=7
wt[{2,2}]=8

local input = torch.Tensor(2,2)
input[{1,1}]=1
input[{1,2}]=5
input[{2,1}]=3
input[{2,2}]=4

print('xcorr2')
print(torch.xcorr2(input,wt))

print('conv2')
print(torch.conv2(input,wt))

-- 输出结果
xcorr2
 88
[torch.DoubleTensor of size 1x1]


-- 这里确实是卷积核旋转180度,再卷
conv2
 81
[torch.DoubleTensor of size 1x1]

这与卷积网络中说的卷积是不一样的,卷积网络中的卷积实际上是信号处理中所说的相关,可以参考 Gram矩阵与卷积网络中的卷积的直观理解

Tensor上的逻辑运算

简单的比较操作

这些操作都将对应的位置替换成true或者false,即1或者0(这里的true和false是C语言意思的true
和false,你知道的,lua中,当且仅当 false和nil才是false,其他都是true!!)
torch.lt(a,b) 小于
torch.le(a,b) 小于等于
torch.gt(a,b) 大于
.
.
.
类似的还有 ne, eq.

> a = torch.rand(10)
> b = torch.rand(10)
> a
 0.5694
 0.5264
 0.3041
 0.4159
 0.1677
 0.7964
 0.0257
 0.2093
 0.6564
 0.0740
[torch.DoubleTensor of dimension 10]

> b
 0.2950
 0.4867
 0.9133
 0.1291
 0.1811
 0.3921
 0.7750
 0.3259
 0.2263
 0.1737
[torch.DoubleTensor of dimension 10]

> torch.lt(a, b)
 0
 0
 1
 0
 1
 0
 1
 1
 0
 1
[torch.ByteTensor of dimension 10]
 类似资料: