Pytorch系列之——Pytorch的Tensor(张量)

张量的构建

  • Tensor概念
  • Tensor创建一:直接创建
  • Tensor创建二:依据数值创建
  • Tensor创建三:依据概率创建

张量是什么?

张量其实就是一个多维数组,它是标量、向量、矩阵的高维拓展:
Pytorch系列之——Pytorch的Tensor(张量)

Tensor与Variable

Variable是torch.autograd中的数据类型,主要用于封装Tensor,进行自动求导,接下来先来看下torch.autograd.Variable这个数据类型,理解了Variable其实对于理解张量是有帮助的:
Pytorch系列之——Pytorch的Tensor(张量)可以看到,Variable中包含了5个属性:

  • data:表示被包装的Tensor
  • grad:表示data的梯度
  • grad_fn:表示创建Tensor的Function,是自动求导的关键
  • requires_grad:指示是否需要梯度,并不是所有的张量都需要计算梯度,若张量需要计算梯度,那么设置requires_grad=True,反之设置requires_grad=False
  • is_leaf:指示是否是叶子结点(张量)

Tensor

从Pytorch0.4.0版本开始,Variable就并入了Tensor,那么我们来看下torch.Tensor这个数据类型的具体细节:

torch.Tensor主要包含8个数据类型,其中有5个属性上面介绍Variable时已经讲述过了,所以主要介绍一下其余的3个属性:
Pytorch系列之——Pytorch的Tensor(张量)

  • dtype:张量的数据类型,如torch.FloatTensor,torch.cuda.FloatTensor
  • shape:张量的形状,如(64,3,224,224)
  • device:张量所在的设备,GPU/CPU,是加速的关键

张量的创建

一、直接创建
torch.tensor()
功能:从data创建tensor
Pytorch系列之——Pytorch的Tensor(张量)

  • data:数据,可以是list,numpy
  • dtype:数据类型,默认与data的一致
  • device:所在设备,cuda/cpu
  • requires_grad:是否需要梯度
  • pin_memory:是否存于锁页内存

torch.from_numpy(ndarray)
功能:从numpy创建tensor
需要注意的是,从torch.from_numpy创建的tensor与原ndarray共享内存,当修改其中一个的数据,另外一个也将会被改动。
Pytorch系列之——Pytorch的Tensor(张量)二、依据数值创建
torch.zeros()
功能:依size创建全0张量
Pytorch系列之——Pytorch的Tensor(张量)

  • size:张量的形状,如(3,3),(3,224,224)
  • out:输出的张量
  • layout:内存中布局形式,有stride,sparse_coo等
  • device:所在设备,gpu/cpu
  • requires_grad:是否需要梯度

torch.zeros_like()
功能:依input形状创建全0张量
Pytorch系列之——Pytorch的Tensor(张量)

  • input:创建与input同形状的全0张量
  • dtype:数据类型
  • layout:内存中布局形式

除此之外,还有torch.ones()、torch.ones_like()
功能:依input形状创建全1张量
Pytorch系列之——Pytorch的Tensor(张量)

  • size:张量的形状,如(3,3)、(3,224,224)
  • dtype:数据类型
  • layout:内存中布局形式
  • device:所在设备,gpu/cpu
  • requires_grad:是否需要梯度

torch.full()、torch.full_like()
功能:依inputing形状创建全值为fill_value的张量
Pytorch系列之——Pytorch的Tensor(张量)

  • size:张量的形状,如(3,3)
  • fill_value:张量的值

torch.arange()
功能:创建等差的1维张量
Pytorch系列之——Pytorch的Tensor(张量)

  • start:数列起始值
  • end:数列结束值
  • step:数列公差,默认为1

torch.linspace()
功能:创建均分的1维张量
Pytorch系列之——Pytorch的Tensor(张量)

  • start:数列起始值
  • end:数列结束值
  • steps:数列长度(注意和数列步长进行区别)

torch.logspace()
功能:创建对数均分的1维张量
Pytorch系列之——Pytorch的Tensor(张量)

  • start:数列起始值
  • end:数列结束值
  • steps:数列长度
  • base:对数函数的底,默认为10

torch.eye()
功能:创建单位对角矩阵(2维张量)
Pytorch系列之——Pytorch的Tensor(张量)

  • n:矩阵行数
  • m:矩阵列数

三、依概率分布创建张量
torch.normal()
功能:生成正态分布(高斯分布)
Pytorch系列之——Pytorch的Tensor(张量)

  • mean:均值
  • std:标准差
    有四种模式:
    1.mean为标量,std为标量
    2.mean为标量,std为张量
    3.mean为张量,std为标量
    4.mean为张量,std为张量

更常用的是:torch.randn()、torch.randn_like()
功能:生成标准正态分布
Pytorch系列之——Pytorch的Tensor(张量)

  • size:张量的形状

torch.randint()
功能:在区间[0,1)上,生成均匀分布
torch.randint_like()
功能:在区间[low,high)生成整数均匀分布

  • size:张量的形状
    Pytorch系列之——Pytorch的Tensor(张量)
    最后两个方法:
    torch.randperm()
    功能:生成从0—n-1的随机排列

  • n:张量的长度
    torch.bernoulli()
    功能:以input为概率,生成伯努利分布(0-1分布,两点分布)

  • input:概率值
    Pytorch系列之——Pytorch的Tensor(张量)

张量操作与线性回归

  • 张量的操作:拼接、切分、索引和变换
  • 张量的数学运算
  • 线性回归

一、张量拼接与切分
Pytorch系列之——Pytorch的Tensor(张量)

1.1 torch.cat()
功能:将张量按维度dim进行拼接

  • tensors:张量序列
  • dim:要拼接的维度

1.2 torch.stack()
功能:在新创建的维度dim上进行拼接

  • tensors:张量序列
  • dim:要拼接的维度

需要注意的是torch.cat()和torch.stack()的区别在于,前者不会扩张张量的维度,而后者会扩张张量的维度。
Pytorch系列之——Pytorch的Tensor(张量)Pytorch系列之——Pytorch的Tensor(张量)从代码中我们可以看出,torch.stack()方法对dim=0维度进行了扩张。

1.3 torch.chunk()
功能:将张量按维度dim进行平均切分
返回值:张量列表
注意事项:若不能整除,最后一份张量小于其他张量
Pytorch系列之——Pytorch的Tensor(张量)

  • input:要切分的张量
  • chunks:要切分的份数
  • dim:要切分的维度

1.4 torch.split()
功能:将张量按维度dim进行切分
返回值:张量列表
Pytorch系列之——Pytorch的Tensor(张量)

  • tensor:要切分的张量
  • split_size_or_sections:为int时,表示每一份的长度;为list时,按list元素切分
  • dim:要切分的维度

二、张量索引
2.1 torch.index_select()
功能:在维度dim上,按index索引数据
返回值:依index索引数据拼接的张量
Pytorch系列之——Pytorch的Tensor(张量)

  • input:要索引的张量
  • dim:要索引的维度
  • index:要索引数据的序号

2.2 torch.masked_select()
功能:按mask中的True进行索引
返回值:一维张量
Pytorch系列之——Pytorch的Tensor(张量)

  • input:要索引的张量
  • mask:与input同形状的布尔类型张量

三、张量变换
3.1 torch.reshape()
功能:变换张量形状
注意事项:当张量在内存中是连续时,新张量与input共享数据内存
Pytorch系列之——Pytorch的Tensor(张量)

  • input:要变换的张量
  • shape:新张量的形状

3.2 torch.transpose()
功能:交换张量的两个维度

  • input:要交换的张量
  • dim0:要交换的维度
  • dim1:要交换的维度

3.3 torch.t()
功能:2维张量转置,对矩阵而言,等价于:
torch.transpose(input,0,1)
Pytorch系列之——Pytorch的Tensor(张量)
3.4 torch.squeeze()
功能:压缩长度为1的维度(轴)

  • dim:若为None,移除所有长度为1的轴;若指定维度,当且仅当该轴长度为1时,可以被移除;

3.5 torch.unsqueeze()
功能:依据dim扩展维度

  • dim:扩展的维度

Pytorch系列之——Pytorch的Tensor(张量)

张量数学运算

加减乘除;对数、指数、幂函数;三角函数,用的时候自行查阅即可:
Pytorch系列之——Pytorch的Tensor(张量)
在这里着重介绍一下torch.add()
torch.add():
功能:逐元素计算input+alpha*other

  • input:第一个张量
  • alpha:乘项因子
  • other:第二个张量
    Pytorch系列之——Pytorch的Tensor(张量)Pytorch系列之——Pytorch的Tensor(张量)以上两个方法在优化过程中经常会使用到。

线性回归

线性回归是分析一个变量与另外一(多)个变量之间关系的方法
线性回归求解步骤:

  1. 确定模型
    Model: y=wx+b

  2. 选择损失函数
    Pytorch系列之——Pytorch的Tensor(张量)通常选择均方误差作为线性回归的损失函数。

  3. 求解梯度并更新w,b
    w= w - LR * w.grad
    b= b - LR * w.grad

计算图与动态图机制

  1. 计算图
  2. Pytorch的动态图机制

深度学习其实就是对张量进行一系列操作,随着操作种类和数量的增多,会导致各种各样想不到的问题。比如,多个操作之间应该并行还是顺序执行?如何协同不同底层设备?以及如何避免各种冗余的操作?…计算图就是为了解决这些问题而产生的。

计算图

计算图是用来描述运算的有向无环图,计算图有两个主要元素:结点(node)和边(edge)。其中,结点表示数据,如向量、矩阵、张量;边表示运算,如加减乘除卷积等。
用计算图表示:y=(x+w) * (w+1)
Pytorch系列之——Pytorch的Tensor(张量)
使用计算图不仅使运算更加简洁,更重要的作用是它使得梯度求导更加方便。
Pytorch系列之——Pytorch的Tensor(张量)

Pytorch系列之——Pytorch的Tensor(张量)
非叶子结点的梯度是会被释放掉的(retain_grad()方法可以保存梯度)

grad_fn:记录创建该张量时所用的方法:

  • y_grad_fn=(MulBackward0)
  • a.grad_fn=(AddBackward0)
  • b.grad_fn=(AddBackward0)
    a和b是通过加法运算得到的,y是通过乘法运算得到的

动态图

pytorch采用的是动态图机制,而tensorflow采用的是静态图机制,那么二者的差异体现在哪儿呢?
动态图是运算与搭建同时进行,而静态图是先搭建图,之后再运算,根据计算图的搭建方式,可将计算图分为动态图(灵活、易调节)和静态图(高效、不灵活)。
静态图——Tensorflow:
Pytorch系列之——Pytorch的Tensor(张量)先创建计算图,之后才可以在Input处进行数据的输入。
动态图——Pytorch:
Pytorch系列之——Pytorch的Tensor(张量)计算图的构建是和数据的输入同时进行的。

autograd与逻辑回归

  • torch.autograd
  • 逻辑回归

torch.autograd.backward()
功能:自动求取梯度
Pytorch系列之——Pytorch的Tensor(张量)

  • tensors:用于求导的张量,如loss
  • retain_graph:保存计算图
  • create_graph:创建导数计算图,用于高阶求导
  • grad_tensors:多梯度权重(当有多个Loss需要计算梯度时,需要计算各个梯度权重之间的比例)

torch.autograd.grad()
功能:求取梯度
Pytorch系列之——Pytorch的Tensor(张量)

  • outputs:用于求导的张量,如loss
  • inputs:需要梯度的张量
  • create_graph:创建导数计算图,用于高阶求导
  • retain_graph:保存计算图
  • grad_outputs:多梯度权重

autograd小贴士:

  • 梯度不自动清零(使用grad.zero_()方法)
  • 依赖于叶子结点的结点,requires_grad默认为True
  • 叶子结点不可执行in-place,in-place操作就是在原始内存中去改变这个数据

逻辑回归

逻辑回归(对数几率回归)是线性的二分类模型:
Pytorch系列之——Pytorch的Tensor(张量)线性回归是分析自变量x与因变量y(标量)之间关系的方法;
逻辑回归是分析自变量x与因变量y(概率)之间关系的方法。

机器学习模型训练的五个步骤,接下来的关于pytorch构建的模型都是基于这五大步骤来进行:
Pytorch系列之——Pytorch的Tensor(张量)

总结

这次主要学习了pytorch框架中张量的基本操作和运算,包括对张量的介绍和构建,其中创建张量可以通过三种方式来创建,分别为:直接构建、根据数值构建和根据概率构建。此外,比较重要的还有torch.Tensor数据类型中包含的8个属性,这些应该在理解的基础上记忆。其中比较细节的部分主要是对张量的一些操作和数学运算,并用最简单的线性回归作为案例。篇末介绍了pytorch中最为重要的计算图和动态图机制,这里需要和Tensorflow的静态图机制进行区分。最后引出了机器学习模型训练的五个步骤,即:数据模块、模型模块、损失函数、优化器和迭代训练,这五个步骤贯穿机器学习模型训练的始终。