Tensor是PyTorch中最基础的概念,其参与了整个运算过程,包含属性,如data, device, dtype等,
tensor的基本创建方法,如直接创建、依数值创建和依概率分布创建等。
1、Variable
Variable是0.4.0之前版本的一种数据类型。下面是variable的一些属性
torch.autograd.Variable.data #就是这张量
torch.autograd.Variable.grad
torch.autograd.Variable.grad_fn # 一些运算
torch.autograd.Variable.requires_grad
torch.autograd.Variable.is_leaf
2、Variable并入tensor,4个与数据有关,4个与求导相关
# 除了上面五个,还要三个
torch.Tensor.dtype # torch.FloatTensor
torch.Tensor.shape
torch.Tensor.device
3.1、直接创建:torch.Tensor()
torch.tensor(data,dtype,device,requires_grad,pin_memory)
# 例如
arr = np.ones((3,3))
t = torch.tensor(arr,device="cuda")
t = torch.tensor(arr)
3.2、numpy数组创建:torch.from_numpy(ndarray) 注意:共享内存
arr = np.array([[1,2],[3,4]])
t = torch.from_numpy(arr)
# 共享内存
arr[0,0]=-1 # 通过直接赋值进行修改
t[0,0]=-1 # 通过直接赋值进行修改
print(t)
print(arr)
4、依据数值创建
torch.zeros(*size,out,dtype,layout,device,requires_grad) #注意out,使用时再看,现在还不明白
torch.zeros_like()
torch.ones()
torch.ones_like()
torch.full(size,fill_value,out,dtype,layout,device,reauires_grad)
torch.full_like()
torch.arange([starr,end),step) # 等差数列 step是步长
torch.linspace([starr,end),steps) # 均分数列 steps是数列长度
torch.logspace()
torch.eye() # 对角矩阵
# 例如
torch.full((3,3),10)
5、概率分布创建
torch.normal() # 正态分布,四种模式,均值和方差分别为均值和方差的四种情况
# 均为张量
mean = torch.arange(1,5,dtype=torch.float)
std = torch.arange(1,5,dtype=torch.float)
t = torch.normal(mean,std)
torch.randn() # 标准正态分布
torch.randn_like()
torch.rand() # 均匀分布【0,1)
torch.rand_like()
torch.randint() # 均匀分布【low,high)
torch.randint_like()
torch.randperm() # 生成0-n-1的随机排序
torch.bernoulli(input=p) # 伯努利 0-1分布
6、拼接
torch.cat(tensors,dim,out) # 不会改变维度
返回张量列表
torch.stack(tensors,dim,out) # 会改变维度,可以增加维度
返回张量列表
7、切分
torch.chunk(input,chunks,dim)
# 平均切分 切分张量、要切分的块数,切分的维度,最后一块可能数量不够
返回依index索引数据拼接的张量
torch.split(tensor,split_size_or_sections,dim)
# split_size_or_sections每份的长度,int(长度是2)或者list(根据list的数来决定每份的长度)。长度要和该维长度一致
返回一维张量
8、索引
torch.index_select(input,dim,index)
# 例如
t = torch.randint(0,9,size=(3,3))
idx = torch.tensor([0,2],dtype=torch.long) # dtype=torch.long规定
t_select = torch.index_select(t,dim=0,index=idx)
torch.masked_select(input,mask)
t.ge(4) #返回大于等于4
t.gt(4) #返回小于等于4
# 例如
t = torch.randint(0,9,size(3,3)) # 生成一个0-9之间的3X3张量
mask = t.ge(5) # 与张量同形状的布尔类型张量
t_select = torch.masked_select(t,mask) # 按照mask中的true进行索引
9、变换
torch.reshape() # 新张量和旧张量共享内存
torch.transpose()
torch.t() # 针对二维张量的转置
torch.squeeze()
torch.unsqueeze()
10、数学运算
torch.add(input,alpha,other) # 加法结合乘法,不是两个参数,是三个
torch.addcdiv() # 加法结合除法
torch.addcmul() # 加法结合乘法
11、线性回归模型的训练--求解W,b
确定模型->损失函数(MSE)->求解梯度并更新权重和偏置(参数+梯度的负方向*学习率)
创建训练数据->构建线性回归模型->迭代(前向传播->计算损失->y反向传播->更新参数->停止迭代的条件(loss小于1时停止)绘图)
12、计算图
is_leaf:叶子节点可以理解为数据入口
反向传播以后非叶子节点的值就会被释放掉,想保存的话,a.retain_grad()就可以了
grad_fn:记录创建张量时的所用的方法(函数)可以理解为如何和叶子节点创建联系
13、自动求导系统
13.1、torch.autograd.backward:自动求取导数
torch.autograd.backward(tensors,# 用于求导的张量
grad_tensors,# 多重梯度求导,当有多个loss时,就可以设置多个loss间的比例
retrain_graph,# 设置为True,保存计算图
create_graph) # 创建导数计算图,用于高阶求导
构建前向传播,搭建好计算图,然后对Y执行backward方法就可以求梯度
具体为:
创建数据(叶子节点),requires_grad设置为true,即要计算梯度->
构建计算(搭建运算图,即前向传播)->
y执行backward方法,即直接调用了torch.autograd.backward
注意retain_grad:如果想进行多次反向传播(再次使用计算图),需要将backward的retain_grad设置为true,这样,动态图就被保存,继而执行下一个反向传播
注意grad_tensors:
"""grad_tensors设置多个梯度的权重"""
# 例如
w=torch.tensor([1.],requires_grad=True)
x=torch.tensor([2.],requires_grad=True)
a=torch.add(w,x)
b=torch.add(w,1)
y0=torch.mul(a,b)
y1=torch.add(a,b)
loss=torch.cat([y0,y1],dim=0)
grad_tensors=torch.tensor([1.,2.]) # 多个梯度的权重
loss.backward(gradient=grad_tensors)
print(w.grad)
13.2、torch.autograd.grad:求取梯度
torch.autograd.grad(outputs,inputs,create_graph..)
14、autograd注意
梯度不自动清零
依赖与叶子节点的节点,requires_grad默认为true
叶子节点不可以执行in-place