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

深度学习框架Torch7解析-- Tensor篇

卫飞鹏
2023-12-01

Tensor

Tensor类可以说是Torch中最重要的类了,因为几乎所有的包都依赖于这个类实现.它是整个Torch实现的数据基础.

类型

Tensor由以下几种类型:

ByteTensor      -- 代表 unsigned char
CharTensor      -- 代表 signed char
ShortTensor     -- 代表 short
IntTensor       -- 代表 int
FloatTensor     --代表 float
DoubleTensor    -- 代表 double

大多数数学操作都仅仅是为FloatTensorDoubleTensor 实现的.但是,为了优化内存的话,其他类型就会用到了.

为了方便,我们一般使用torch.Tensor 来定义数据,因为它是独立于数据类型的.而要改变默认数据类型可以使用下面的函数:

torch.setdefaulttensortype("torch.FloatTensor")

多维矩阵

Tensor实际上就是一个多维矩阵,我们可以使用toch.Tensor或者storage来定义.
例子:

z = torch.Tensor(4, 5, 6, 2)

s = torch.longStorage(3)
s[1] = 2; s[2] = 3; s[3] = 5
x = torch.Tensor(s)

可以通过dim()或者nDimension()访问Tensor的维度数.size(i)可以返回第i维的大小.而size()会返回所有维的大小.

>x:dim()
3
>x:size()
2
3
5
>x:size(2)
3

数据的内部表示

其实,Tensor的数据是包含在一个Storage里的,可以使用storage()进入。也就是说,Tensor可以看做Storage的一种视角:Storage只是表示一块内存,Tensor将它分出了维度。

x = torch.Tensor(4,5)
s = x:storage()
for i=1,s:size() do -- fill up the Storage
  s[i] = i
end
> x -- s is interpreted by x as a 2D matrix
  1   2   3   4   5
  6   7   8   9  10
 11  12  13  14  15
 16  17  18  19  20
[torch.DoubleTensor of dimension 4x5]

注意在Torch7中,一行的数据是连续的,这有点类似C中的数组。

内存管理

所有的Tensor的操作都没有进行内存复制,所有的方法都是变换已经存在的Tensor,或者返回一个新的Tensor引用相同的Storage

x = torch.Tensor(5):zero()
> x
0
0
0
0
0
[torch.DoubleTensor of dimension 5]
> x:narrow(1, 2, 3):fill(1) -- narrow() returns a Tensor
                            -- referencing the same Storage as x
> x
 0
 1
 1
 1
 0
[torch.Tensor of dimension 5]

如果真的想复制Tensor,可以使用copy()

y = torch.Tensor(x:size()):copy(x)

或者使用clone()

y = x:clone()

常用函数

Tensor 的构造函数

构造函数,将构造新的Tensor。分配的内存并没有初始化,所以里面的数是随机的。

torch.Tensor()          --返回空的tensor
torch.Tensor(tensor)    --返回新的tensor,引用的是给定tensor的内存
torch.Tensor(sz1 [,sz2 [,sz3 [,sz4]]]]) --创造一个新的tensor,         大小为sz1 x sz2 x sx3 x sz4
torch.Tensor(table)     --从一个table构造tensor,包含table中所有的元素

例子:

x = torch.Tensor(2,5):fill(3.14)
> x
 3.1400  3.1400  3.1400  3.1400  3.1400
 3.1400  3.1400  3.1400  3.1400  3.1400
[torch.DoubleTensor of dimension 2x5]

y = torch.Tensor(x)
> y
 3.1400  3.1400  3.1400  3.1400  3.1400
 3.1400  3.1400  3.1400  3.1400  3.1400
[torch.DoubleTensor of dimension 2x5]

y:zero()
> x -- elements of x are the same as y!
0 0 0 0 0
0 0 0 0 0
[torch.DoubleTensor of dimension 2x5]

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

常用操作函数

复制和初始化:

[self] copy(tensor)     --复制tensor的值
[self] fill(value)      --用value的值填充
[self] zero()           --将tensor全初始化0

例子:

x = torch.Tensor(4):fill(1)
y = torch.Tensor(2,2):copy(x)
> x
 1
 1
 1
 1
[torch.DoubleTensor of dimension 4]

> y
 1  1
 1  1
[torch.DoubleTensor of dimension 2x2]

> torch.Tensor(4):zero()
 0
 0
 0
 0
[torch.DoubleTensor of dimension 4]

Rsizing

当调整至更大的尺寸时,底层的Storage将被调整至适应Tensor
当调整至更小的尺寸时,底层的Storage将不会被调整

[self] resizeAs(tensor)         --将尺寸调整为给定tensor的尺寸
[self] resize(sz1 [,sz2 [,sz3 [,sz4]]]])    --调整为给定尺寸

提取子tensor

[self] narrow(dim, index, size)

返回一个narrowed版本的tensor:dim维度的indexindex+size-1被提取

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

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 dimension 5x6]

y = x:narrow(1, 2, 3) -- narrow dimension 1 from index 2 to index 2+3-1
y:fill(1) -- fill with 1
> y
 1  1  1  1  1  1
 1  1  1  1  1  1
 1  1  1  1  1  1
[torch.DoubleTensor of dimension 3x6]

> x -- memory in x has been modified!
 0  0  0  0  0  0
 1  1  1  1  1  1
 1  1  1  1  1  1
 1  1  1  1  1  1
 0  0  0  0  0  0
[torch.DoubleTensor of dimension 5x6]
[Tensor] select(dim, index)

提取dim维度的第index

x = torch.Tensor(5,6):zero()
> x
 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 dimension 5x6]

y = x:select(1, 2):fill(2) -- select row 2 and fill up
> y
 2
 2
 2
 2
 2
 2
[torch.DoubleTensor of dimension 6]

> x
 0  0  0  0  0  0
 2  2  2  2  2  2
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
[torch.DoubleTensor of dimension 5x6]

z = x:select(2,5):fill(5) -- select column 5 and fill up
> z
 5
 5
 5
 5
 5
[torch.DoubleTensor of dimension 5]

> x
 0  0  0  0  5  0
 2  2  2  2  5  2
 0  0  0  0  5  0
 0  0  0  0  5  0
 0  0  0  0  5  0
[torch.DoubleTensor of dimension 5x6]

当然提取的神器在这儿:

[Tensor] [{ dim1,dim2,... }] or [{ {dim1s,dim1e}, {dim2s,dim2e} }]

例子:

x = torch.Tensor(5, 6):zero()
> x
 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 dimension 5x6]

x[{ 1,3 }] = 1 -- sets element at (i=1,j=3) to 1
> x
 0  0  1  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 dimension 5x6]

x[{ 2,{2,4} }] = 2  -- sets a slice of 3 elements to 2
> x
 0  0  1  0  0  0
 0  2  2  2  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
[torch.DoubleTensor of dimension 5x6]

x[{ {},4 }] = -1 -- sets the full 4th column to -1
> x
 0  0  1 -1  0  0
 0  2  2 -1  0  0
 0  0  0 -1  0  0
 0  0  0 -1  0  0
 0  0  0 -1  0  0
[torch.DoubleTensor of dimension 5x6]

x[{ {},2 }] = torch.range(1,5) -- copy a 1D tensor to a slice of x
> x

 0  1  1 -1  0  0
 0  2  2 -1  0  0
 0  3  0 -1  0  0
 0  4  0 -1  0  0
 0  5  0 -1  0  0
[torch.DoubleTensor of dimension 5x6]

x[torch.lt(x,0)] = -2 -- sets all negative elements to -2 via a mask
> x

 0  1  1 -2  0  0
 0  2  2 -2  0  0
 0  3  0 -2  0  0
 0  4  0 -2  0  0
 0  5  0 -2  0  0
[torch.DoubleTensor of dimension 5x6]

未完待续…

 类似资料: