torch tensor用法

1.

x = torch.Tensor(5):zero()

2.

conf_mask = torch.ones(nB, nA, dim, dim)

conf_mask[...]=0

Tensor构造的三种方式

下面2种比较常用。

-- 最多到4维度
x = torch.Tensor(2,5):fill(3.14) 
-- 大于4维度的
x = torch.Tensor(torch.LongStorage({4,4,3,2}))

注意:第二个函数调用方式是torch.Tensor(sizes, [strides]) 。sizes和[strides]都是LongStorage类型的。并且strides是每一维度中,一个元素到下一个元素之间的步长。并且可以随意设置!

x = torch.Tensor(torch.LongStorage({4}), torch.LongStorage({0})):zero() -- zeroes the tensor
x[1] = 1 -- all elements point to the same address!
> x
 1
 1
 1
 1

可以看到上面令stride为0了,也就是说x虽然有4个单元,但都实际上指向物理地址的同一个单元!让x[1]=1,整个x都变成1了。厉害了。

另外一个就是通过table进行构造。

> torch.Tensor({{1,2,3,4}, {5,6,7,8}})
 1  2  3  4
 5  6  7  8
[torch.DoubleTensor of dimension 2x4]

附:torch为了方便大家的使用,内部内部的绝大部分函数都可以用2种方法来进行调用—– src:function()或是torch.function(src, …)。也就是说,第二种风格的调用是将自身作为第一个参数进行调用。然而由于内部还是不太完善,有些函数只能用第一种方法或是第二种方法。比如

--下面两种是一样的
x = torch.Tensor(2,3):fill(2)
y = torch.fill(torch.Tensor(2,3),2)

--下面只能由第二种方法
local x = torch.transpose(vecInput, 2,3)  --这个会出错
local y = vecInput:transpose(2,3)  --这个正确

这些只能由自己去测试了,当然绝大部分都是完美支持两种的。所以也没啥好担心的。


截取Tensor数据

x[index],等价与select(1,index). 如果x是二维数据,那么x[2]代表第2行!就是相当于 x:select(1,2)。 选取第一维的第二个。

narrow, select, sub略!

这三个函数可以用x[{ {dim1s, dim1e}, {dim2s, dim2e},… }]来替代!

x = torch.Tensor(2,5,6):zero()

-- 第一种,如果是只有一个大括号,里面是单纯数字的话,
-- 就说明是"全部"
-- 选择"第一块,第三行,没指定列,所以是全部"
x[{1,3}] = 1
th> x
(1,.,.) =
  0  0  0  0  0  0
  0  0  0  0  0  0
  1  1  1  1  1  1
  0  0  0  0  0  0
  0  0  0  0  0  0

(2,.,.) =
  0  0  0  0  0  0
  0  0  0  0  0  0
  0  0  0  0  0  0
  0  0  0  0  0  0
  0  0  0  0  0  0
[torch.DoubleTensor of size 2x5x6]

-- 我么也可以通过这个快速取某个坐标的值
-- 比如 x[{1,3,2}],而不用写成x[{ {1},{3},{2}]

x[{ {dim1s, dim1e}, {dim2s, dim2e},… }]的用法略。

取Tensor中的某个坐标的值

x = torch.Tensor(2,3,4)

v = x[{1,2,2}]  --取坐标值时,用截取Tensor数据的方法,当index的元素个数等于x的nDimension时,才是取某个值!否则是等价于`select`的!!!!!!!!!!!!!!!!!!!!!!!!
v_false = x[{{1},{2},{3}}] --这个是错的!这个返回的是Tensor类型,不是num!

x[v] = 2  -- 这个会让x的一半的值都变成2!!!!

Tensor的赋值

以下只说对单个元素的赋值。

x = torch.Tensor(2,3,4)
--以下下两种方法等价!
x[{1,2,3}] = 2
x[{{1},{2},{3}}] = 2  

Tensor的搜索

这个就一个函数nonzero(). 返回非0元素的坐标的。

> x = torch.rand(4, 4):mul(3):floor():int()
> x
 2  0  2  0
 0  0  1  2
 0  2  2  1
 2  1  2  2
[torch.IntTensor of dimension 4x4]
> torch.nonzero(x)
 1  1
 1  3
 2  3
 2  4
 3  2
 3  3
 3  4
 4  1
 4  2
 4  3
 4  4
[torch.LongTensor of dimension 11x2]

Expanding/Replicating/Squeezing Tensors

expand

这个函数的作用就是在singleton维度进行扩展!吓人的是,这里使用了一个技巧:expand Tensor时并不需要开辟新的空间,而是直接让被扩展的那个维度的stride为0!

x = torch.rand(10,1)
> x
 0.3837
 0.5966
 0.0763
 0.1896
 0.4958
 0.6841
 0.4038
 0.4068
 0.1502
 0.2239
[torch.DoubleTensor of dimension 10x1]
>x:stride()
1
1

y = torch.expand(x,10,2)
> y
 0.3837  0.3837
 0.5966  0.5966
 0.0763  0.0763
 0.1896  0.1896
 0.4958  0.4958
 0.6841  0.6841
 0.4038  0.4038
 0.4068  0.4068
 0.1502  0.1502
 0.2239  0.2239
[torch.DoubleTensor of dimension 10x2]
>y:stride()
1
0


可以看见,被扩展的维度变成0了!! 
又比如:

th> x = torch.rand(5,1,4)
                                                                      [0.0001s]
th> x:stride()
 4    -- 1*4
 4    -- 4
 1
[torch.LongStorage of size 3]

th> x = torch.rand(5,2,4)
                                                                      [0.0001s]
th> x:stride()
 8    -- 2*4
 4    -- 4
 1
[torch.LongStorage of size 3]

这是因为直接调用构造函数,不指定stride的话,都是连续的。


th> x = torch.rand(10,1,5)
                                                                      [0.0001s]
th> x:stride()
 5
 5
 1
[torch.LongStorage of size 3]

th> y = torch.expand(x,10,2,5)
                                                                      [0.0001s]
th> y:stride()
 5
 0
 1
[torch.LongStorage of size 3]

repeatTensor

这个函数是需要新申请空间的!

x = torch.rand(5)
> x
 0.7160
 0.6514
 0.0704
 0.7856
 0.7452
[torch.DoubleTensor of dimension 5]

> torch.repeatTensor(x,3,2)
 0.7160  0.6514  0.0704  0.7856  0.7452  0.7160  0.6514  0.0704  0.7856  0.7452
 0.7160  0.6514  0.0704  0.7856  0.7452  0.7160  0.6514  0.0704  0.7856  0.7452
 0.7160  0.6514  0.0704  0.7856  0.7452  0.7160  0.6514  0.0704  0.7856  0.7452
[torch.DoubleTensor of dimension 3x10]

Squeeze

这个函数就是将所有singleton的维度压缩去除。

View—重新看待存储Storage

这里主要是5个函数:view,viewAs, transpose(), t(), permute()。 
这些都是对于Tensor以另一种角度取看待!因此是直接对原存储空间进行更改的! 
These methods are very fast, because they do not involve any memory copy.

x = torch.zeros(4)
> x:view(2,2)
 0 0
 0 0
[torch.DoubleTensor of dimension 2x2]

> x:view(2,-1)
 0 0
 0 0
[torch.DoubleTensor of dimension 2x2]

-- 利用view是进行增加一个“1”维的很好的方法
x = x:view(2,1,2)
th> x
(1,.,.) =
  0  0

(2,.,.) =
  0  0
[torch.DoubleTensor of size 2x1x2]

th> x:stride()
 2
 2
 1
[torch.LongStorage of size 3]

猜你喜欢

转载自blog.csdn.net/jacke121/article/details/80772627