首先来介绍张量:
在数学中,一个单独的数可以称为标量,一列或者一行数组可以称为向量,一个二维数组称为矩阵,矩阵中的每一个元素都可以被行和列的索引位移确定,如果数组的维度超过2,那么我们可以称该数组为张量(Tensor)。但是在pytorch中,张量属于一种数据结构,他可以是一个标量、一个向量、一个矩阵,甚至是更高位的数组,所以pytorch中Tensor和Numpy中的数组(ndarray)非常相似,再使用时也经常将Pytorch中的张量和Numpy中的数组相互转化。在深度网络中,基于Pytorch的先关计算和优化都是在Tensor的基础上完成的。
在pytorch的0.4版本之前,Tensor是不能计算梯度的,所以在深度学习网络中,需要计算梯度的Tensor都需要使用Variable(Tensor)将张量进行封装,这样才能构件计算图。但是在Pytorch的0.4版本之后,合并了Tensor和Variable类,可直接计算Tensor的梯度,不再需要使用Variable封装Tensor,因此Variable()的使用逐渐从API中消失。
在torch中CPU和GPU张量分别有8种数据类型。
数据类型 |
dtype |
CPU Tensor |
GPU Tensor |
32位浮点型 |
torch.float32或torch.float |
torch.FloatTensor |
torch.cuda.FloatTensor |
64位浮点型 |
torch.float64或torch.double |
torch.DoubleTensor |
torch.cuda.DoubleTensor |
16位浮点型 |
torch.float16或torch.half |
torch.HalfTensor |
torch.cuda.HalfTensor |
8位无符号整数 |
torch.unit8 |
torch.ByteTensor |
torch.cuda.ByteTensor |
8位有符号整数 |
8 |
torch.CharTensor |
torch.cuda.CharTensor |
16位有符号整形 |
16或torch.short |
torch.ShortTensor |
torch.cuda.ShortTensor |
32位有符号整形 |
32或 |
torch.IntTensor |
torch.cudTensor |
64位有符号整形 |
64或torch.long |
torch.LongTensor |
torch.cuda.LongTensor |
在torch中默认的数据类型是32位浮点型(torch.FloatTensor),可以通过torch.set_default_tensor_type()函数设置默认的数据类型,但是该函数只支持设置浮点型数据类型,下面使用程序展示如何查看和设置张量的数据类型。
在程序中使用torch.tensor()函数生成一个张量,然后使用.dtype方法获取张量的数据类型,结果为32位浮点型。
在上面的程序中,从张量的.type方法输出结果为torch.float64可知,通过torch.set_default_tensor_type(torch.DoubleTensor)已经将默认的数据类型设置为64位浮点型。
在torch中还有其它类型的数据,将浮点型转化为其它数据类型的方法如下:
由于在程序片段In[2]中已经将张量默认的数据类型设置为64位浮点型,所以生成的张量a的数据类型为torch.float64.针对张量a,可以使用a.long()方法将其转化为64位有符号整数,()方法将其转化为32位有符号整型,a.float()方法将其转化为32位浮点型。
如果想要恢复默认的32位浮点型数据类型,需要再次使用torch.set_default_tensor_type()函数,程序如下:
在上面的程序中,从张量的.dtype方法输出结果为torch.float32可知,已经将默认的数据类型恢复为32位浮点型。
也可以使用torch.get_default_dtype()函数,获取默认的数据类型,如:
在pytorch中有多种方式可以生成一个张量,下面使用具体的代码介绍如何生成深度学习过程需要的张量。
(1)使用torch.tensor()函数生成张量
Python的列表或序列可以通过torch.tensor()函数构造张量。
上面程序使用torch.tensor()函数将Python的列表转化为张量。张量的维度可以通过.shape查看,并可使用.size()方法计算张量的形状大小,使用.numel()方法计算张量中包含元素的数量,例如:
在使用torch.tensor()函数时,可以使用参数dtype来指定张量的数据类型,使用参数requires_grad来指定张量是否需要计算梯度。只有计算了梯度的张量,才能在深度网络优化时根据梯度大小进行更新。
程序中使用参数dtype=torch.float32指定张量B中的元素为32位浮点型,使用参数requires_grad=True表明张量B可以计算每个元素的梯度。下面针对张量B计算sum(B^2)在每个元素上的梯度大小:
从输出结果可以看出每个位置上的梯度为2*b。这里需要注意的是,只有浮点型数据才能计算梯度,其它类型的数据是不能计算张量的梯度,下面的程序就会报错。
根据报错信息我们就知道只有浮点类型的数据需要梯度。
(2)torch.Tensor()函数
在pytorch中也可以使用torch.Tensor()函数来生成张量,而且可以根据指定的形状生成张量。例如,根据Python列表生成张量。
也可以根据形状参数生成特定尺寸的张量。
针对已经生成的张量可以使用torch.**_like()系列函数生成与指定张量维度相同、性质相似的张量,如使用torch.ones_like()函数生成与D维度相同的全1张量。
使用torch.zeros_like()函数生成与D维度相同的全0张量:
使用torch.rand_like()函数生成与D维度相同的随机张量:
针对一个创建好的张量D,可以使用D.new_**()系列函数创建出新的张量,如使用D.new_tensor()将列表转化为张量:
上面的程序使用D。new_tensor(e)将列表转化为32位浮点型的张量。还可以用其它函数得到新的张量。如下所示
函数 |
描述 |
d.new_full((3,3),fill_value=1) |
3*3使用1填充的张量 |
d.new_zeros((3,3)) |
3*3的全0张量 |
d.new_empty((3,3)) |
3*3的空向量 |
d.new_ones((3,3)) |
3*3的全1向量 |