这个主要是提供了类似很多Matlab的函数。所有的math函数具有第一篇所说的两种调用方法等价的特性。
torch.log(x,x) --将返回值存储x内
x:log() --返回一个值,此时x的值已经变成返回值了。
值得注意的是,能用第一种则尽量用第一种,因为math函数默认是要开辟一个新的空间来存储返回值的,而第一种方法则不需要,因此用第一种好。
由于这里的函数大部分类似matlab,所以默认大家已经学过matlab。。
Math函数介绍按照
构造 –>逐像素操作 —> 逐维度操作 —> Matrix-wide操作—>卷积操作 —> 矩阵分解等 —> 对Tensor进行逻辑操作
-- 在第一维度上联合
> 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]
这个略。
其中rand是生成均匀分布,而randn是生成均值为0,方差为1的正态分布。
略
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]
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]
一个很常用的较为高级的函数就是累加乘。
[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])
这个都类似,一般是
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是对两个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]
y, i = torch.kthvalue(x, k, n) 沿着n维度返回第k小的数据
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的关系很重要!
求某一维度的标准差和方差。略略
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和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矩阵与卷积网络中的卷积的直观理解
这些操作都将对应的位置替换成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]