一. Pytorch简介
1.1 优点
上手快,代码简洁,易调试,文档规范,资源多,维护稳定
学术界–论文
快速复现论文
工业界–项目
搭建最新模型
1.2 定位
深度学习框架,实现深度学习算法
数据(数据读取,预处理)–模型(构建模型模块,组织复杂网络)–
损失函数–优化器(管理模型参数,调整学习率)–迭代训练(观察训练效果)–模型应用
二. pytorch快速入门
2.1 张量
张量是一个多维数组,是标量,向量,矩阵的高维拓展
Variable:
主要封装Tensor,进行自动求导
data:被封装的Tensor
grad:data的梯度
grad_fn:创建Tensor的Function,是自动求导的关键
requires_grad:是否需要梯度
Variable现已并入Tensor
dtype:张量的数据类型
shape:张量的形状
device:张量所在设备
tensor转换类型
a.long().dtype
a.int().dtype
a.float().dtype
torch.set_default_tensor_type(torch.DoubleTensor) #可以设置默认的浮点数数据类型
torch.get_default_dtype() #查看默认的数据类型
2.2 张量的创建
2.2.1 直接创建
#torch.Tensor(data)
import numpy as np
arr = np.arange(12).reshape(3,4)
t_data = torch.Tensor(arr)
#arr与t_data数据是独立的
data:可以是list,numpy
dtype:默认与data一致
device:所在设备
required_grad:是否需要梯度
pin_memory:是否存于锁页内存 #默认False
t_data.shape与t_data.size()都可以看张量的形状
t_data.numel()#计算张量中的元素数量
torch.tensor() 是一个函数
torch.Tensor()相当于torch.FloatTensor()的别名
torch.Tensor(3,4)#生成一个特定大小张量,torch.tensor()不能这么使用
torch.from_numpy(ndarray)
改动一个数据,另一个也会改动
2.2.2 依据数值创建
torch.**_like()生成与指定张量维度相同,性质相似的张量
torch.ones_like()
torch.zeros_like()
torch.rand_like()
t_data.new_**()#由一个创建好的张量,创建出新的张量
t_data.new_tensor(list)#将列表转化为张量
t_data.new_full((3,3),fill_value=1)#使用指定值填充张量
t_data.new_zeros((3,3))#生成3*3的零向量
t_data.new_empty((3,3))#生成3*3的空向量
t_data.new_ones((3,3))#生成3*3的1向量
import torch
#创建全0张量
torch.zeros(3,3)
torch.zeros((3,3))
#创建全1张量
torch.ones(3,3)
torch.ones((3,3))
#指定数值
torch.full()
t = torch.full((3,3),10)
#size:形状
#fill_value:拟定的值
#创建空向量
torch.empty(4,3)
torch.empty((4,3))
#创建单位向量
torch.eye(3,4)
torch.eye((3,4))
torch.arange()
#功能:创建等差的一维向量
[start,end)
start:数列起始值
end:结尾
step:间隔,默认为1
torch.linspace(strat,end,step)
step:长度
[start,end]
torch.logspace()
start:数列起始
end:数列结束值
[start,end]
steps:数列长度
base:对数函数的底,默认为10
torch.eye()
创建单位对角矩阵(二维张量)
默认为方阵
n:矩阵行 m:矩阵列
2.2.3 依概率分布创建
import torch
torch.manual_seed(111)#生成种子
torch.normal()
生成正态分布
#mean:均值
#std:标准差
mean std可以为张量/标量,就有四种类型
mean为张量,std为张量
产生维度一致对应(mean,std)的数据
mean为标量,std为标量
normal函数还需要加上size
mean为张量,std为标量
mean对应,std一样
mean为标量,std为张量
mean一样,std对应
torch.randn()
#size:形状
torch.randn_like()
#input对应tensor类型
生成标准正态分布
torch.rand()
#size
torch.rand_like()
#[0,1)上生成均匀分布
torch.randint()
#low=0, high, size
torch.randint_like()
#[low,high)生成整数均匀分布
torch.randperm()
生成0-n-1的随机排列
#n:张量长度
torch.bernoulli()
#input为概率,生成伯努利分布
(0-1分布,两点分布)
#input=概率值
2.2.4 张量与Numpy相互转化
#将numpy转化为tensor
import numpy as np
a = np.ones((3,3))
t_a = torch.as_tensor(a)
t_a1 = torch.from_numpy(a)#使用numpy生成的数组默认是64位浮点数,且数据的内存空间是一致的
#将tensor转化为numpy
t_a.numpy()
2.3 张量操作
2.3.1 张量拼接与切分
#在指定的维度上进行拼接
#注意此处不是axis
t_3 = torch.cat((t_1,t_2)
,dim=0#按维度dim进行拼接
)
t_4 = torch.cat((t_1,t_2)
,dim=1#按维度dim进行拼接
)
#在新创建的维度上进行拼接
t_5 = torch.stack((t_1,t_2),dim=0) #(2,3,4)
#将张量按维度dim进行平均切分
#返回张量列表
#不能整除,则最后一份张量小于其他张量
a,b = torch.chunk(input=t_3
,chunks=2
,dim=0)
#可以确定指定维度切分的块数
torch.split()
A = torch.arange(6.0).reshape(2,3)
B = torch.linspace(0,10,6).reshape(2,3)
D = torch.cat((A,B),dim=1)
D = torch.cat((A,B),dim=1)
#tensor:要切分的张量
#split_size_or_sections:int 每一份的长度 list 按list元素切分
#dim 切分的维度
2.4 张量索引
A = torch.arange(12).reshape(1,3,4)
A[0,-1,-4:-1]#切片索引
B = -A
torch.where(A>5,A,B)
torch.index_select()
#在维度dim上,按index索引数据
#返回,依index索引数据拼接的张量
t = torch.index_select(t_3
,dim=0 ,index=torch.tensor([0,2],dtype=torch.int)
)
#input:索引的张量
#dim:索引的维度
#index:要索引的序号,指定为tensor类
#掩码索引
torch.masked_select()
#按照mask中的True进行索引
torch.masked_select(t_3
,mask=(t_3>5))
#mask:与input同形状的布尔类型张量
2.5 张量变换
#变换张量形状
torch.reshape()
#返回的是一个视图
new_t_3 = torch.reshape(t_3,shape=(3,8))
new_t_3[0,0] = 100
#t_3也会改变
#input:要变换的张量
#shape:新张量的形状
#交换张量的两个维度
torch.transpose()
#input:要交换的张量
#dim0:要交换的维度
#dim1:要交换的维度
#针对二维张量的转置
torch.t()
2.6 张量压缩
#压缩长度为1的维度
torch.squeeze()
#dim:若为None,移除所有长度为1的轴,可以指定
#根据dim拓展维度
torch.unsqueeze()
#dim:拓展的维度
t_1 = torch.arange(12).reshape(3,4)
t_2 = torch.arange(12).reshape(3,4)
t_2 = torch.arange(12).reshape(3,-1)#-1处会自动计算
torch.reshape(input=A,shape=(3,4))#使用torch的函数
t_data.resize_(2,6)#对张量形状进行修改
t_data1.resize_as_(t_data2)#将张量t_data1形状设置为跟张量t_data2相同的形状
a = torch.arange(12).reshape(3,4)
a = torch.unsqueeze(a,dim=0)#可以在张量的指定维度插入新的维度得到维度提升的张量
a.unsqueeze(dim=3)
a = torch.squeeze(a,dim=3)#可以移除指定或者所有维度大小为1的维度,得到维度减小的新张量
a.squeeze(dim=0)
#expand对维度进行扩展,主要用于size=1或者扩充第一维,不然会报错
A = torch.arange(6).reshape(2,3)
B = A.expand(3,2,3)#针对的第一个维度进行扩张
C = A.expand_as(t_data)#根据张量t_data进行扩充
#repeat对维度进行拓展,以各维度重复形式,从右到左
B.repeat(1,1,2,2).shape
2.7 张量的数学运算
2.7.1 加减乘除
t_data1
t_data2
+ - * /
整除 //
#逐元素计算input+alpha*other
torch.add()
#input:第一个张量
#alpha:乘项因子
#other:第二个张量
torch.addcdiv()#out=input+value*(t1/t2)
torch.addcmul()#out=input+value*t1*t2
torch.sub()
torch.mul()
torch.div()
2.7.2 对数,指数,幂函数
torch.pow(A,3)#计算张量的幂 t_data**3
torch.exp(A)#计算张量的指数
torch.log(A)#计算张量的对数
torch.sqrt(A)#计算张量的平方根
torch.rsqrt(A)#计算张量的平方根倒数
2.7.3 三角函数
torch.abs()
torch.acos()
torch.cosh()
torch.cos()
torch.asin()
torch.atan()
torch.atan2()
2.7.4 其它
比较大小
torch.allclose()#比较两个元素是否接近
#|A-B|<=atol+rtol*|B|
#input, other, rtol=1e-05, atol=1e-08, equal_nan=False
torch.eq(A,B)#判断两个张量元素是否相等
torch.equal(A,B)#判断两个张量是否具有相同形状和元素
torch.ge(A,B)#逐元素比较判断是否大于等于
torch.gt(A,B)#逐元素比较大于
torch.le(A,B)#逐元素比较判断是否小于等于
torch.lt(A,B)#逐元素比较小于
torch.ne(A,B)#逐元素比较不等于
torch.isnan(A,B)#判断是否为缺失值
针对张量数据的裁剪
大于/小于指定值的都替换为指定值
torch.clamp_max(A,max)
torch.clamp_min(A,min)
torch.clamp(A,min,max)
矩阵运算
torch.t(A)#矩阵的转置
A.t()
torch.matmul(A,B)#两个矩阵的乘积
A.matmul(B)
torch.inverse(A)#计算矩阵的逆矩阵
A.inverse()
多维矩阵相乘只计算最后两个维度的乘法
A = torch.arange(12.0).reshape(2,2,3)
B = torch.arange(12.0).reshape(2,3,2)
AB = torch.matmul(A,B)
C = torch.stack((A[0].matmul(B[0]),A[1].matmul(B[1])),dim=0)
torch.equal(AB,C)#True
统计相关的计算
多维张量中指定dim,对指定维度进行最大最小值的寻找
torch.max(A)#张量中的最大值
A.max()
torch.min(A)#张量中的最小值
A.min()
torch.argmax(A)#张量中最大值的位置
A.argmax()
torch.argmin(A)#张量中最小值的位置
A.argmin()
torch.sort()#对一维张量进行排序,或高维张量在指定维度的排序
t_data.sort()
sort_value,sort_index = torch.sort(torch.randn(12))
torch.topk(A,2,dim=0)#获取张量中前2个大的数值
torch.kthvalue(A,3,dim=1)#获取张量第k小的数值和位置 keepDim为True保持维度
torch.mean()#根据指定维度计算均值
torch.sum()#根据指定维度求和
torch.cumsum()#根据指定维度计算累加和
torch.median()#根据指定维度计算中位数
torch.cumprod()#根据指定维度计算累积乘
三. 计算图与动态图机制
3.1 计算图
用来描述计算的有向无环图
两个元素:节点(Node)和边(Edge)
节点表示数据:向量,矩阵,张量
边表示运算
方便反向求导!
is_leaf:指示张量是否是叶子节点(用户创建的节点)
非叶节点的梯度会释放
node.retain_grad() #保存非叶节点的梯度
grad_fn:记录创建该张量时所用的方法
3.2 动态图
根据计算图的搭建方法,可以将计算图分为静态图和动态图
动态图:运算和搭建同时进行 灵活 易调节
静态图:先搭建图,后运算 性能好
四. autograd自动求导系统
x = torch.tensor([[1.0,2.0],[3.0,4.0]],requires_grad=True)
y = torch.sum(x**2+2*x+1)
y.backward()
y.backward()