写在前面: 学习pytorch也有一段时间了,一直都是在网上看别人的代码然后自己再敲一遍,把不理解的地方查找一下资料,但是总感觉缺点是什么,仔细思考一下整个过程,有点类似背代码的意思,这是非常要命的一点,所以今天就索性把这个在从头一点一点的利用晚上的时间再复习一边. 今天我们复习的是计算图与动态机制 深度学习一直在操控的是各种张量,少量的张量我们可以处理,但是随着网络的加深,各种参数的增多,张量的增多,会导致各种各样的问题产生,那么我们应该怎么处理这个现象呢?这时候便有了计算图的产生,那么什么又是计算图呢,先见到那介绍一下计算图 计算图 是一种特殊的有向无环图,在autograd中,它的作用是用来记录算子和变量之间的关系其中最重要的是节点和边。那么什么是节点呢?节点就是我们自己创建的变量,边呢?就是这些变量是通过什么样的方式结合在一起的,比如加减乘除卷积等等, 这个图片是y=wx+b的计算图,其中矩形框内的东西是算子(边),椭圆里面的内容就是节点(变量),这就是一个计算图,其中的X和b又被称为叶子节点,因为这两个是我们自己创建的数据,不依赖于其他变量,y就依赖于别的变量,我们利用链式法则很容易获得各个叶子节点的梯度, 前向传播就是我们从上向下求,反向传播就是从下向上求导数, 简单提一句,张量是数据的载体。 在正向反向传播过程中还有好多细节和函数,说一下叶子节点(张量的重要属性),在正向计算和反向传播过程中都紧紧的依赖于叶子节点进行,属性是 is_leaf,我们通过这个属性可以判断该变量是不是叶子节点,print(w.is_leaf)—》True那么他就是叶子节点,否则不是, 叶子节点的存在是为了节省内存,在反向传播的过程中,非叶子节点的梯度是被默认放掉的,不占据内存。 其中还有一个属性是grad_fn(也是张量的重要属性) 是记录创建该张量时所利用的方法,记录该方法是为了在求解梯度,不然不知道具体的运算,参照上图的add和mul,但是我们自己不用管它,这是在反向计算的时候采用的,不用我们去调用,但是我们可以查看 pytorch的动态图机制有一个非常重要的过程,那就i是反向求导, 那就是torch.autograd.backward 我们在用的时候直接y.backward()就行了,它就会开始利用计算图的那个链式法则,开始计算各个节点的梯度,非叶子节点的梯度计算出来后被默认释放掉,叶子节点的梯度不会被释放掉,但是我们必须要手动释放 w.grad.zeros_()就可以了,至于为啥要手动释放,因为不释放这个梯度是会叠加的,会影响接下来的计算 这个释放过程也叫梯度清零 到这里我们来简单的小总结一下 我们现有数据,也就是张量,然后根据张量之间的关系会有计算图,这个计算图是运算用的,前向运算和反向运算,有了数据和计算图我们就可以开始训练模型了
from symbol import parameters
import torch
from torch import nn
a=torch.manual_seed(1)
n_data=torch.ones(100,2)
x0=torch.normal(1.7*n_data,1)+1
y0=torch.zeros(100,1)
x1=torch.normal(-1.7*n_data,1)+1
y1=torch.ones(100,1)
train_x=torch.cat([x0,x1],0)
train_y=torch.cat([y0,y1],0)
class LR(nn.Module):
def __init__(self):
super(LR, self).__init__()
self.feature=torch.nn.Linear(2,1)
self.sigmod=torch.nn.Sigmoid()
pass
def forward(self,x):
x=self.feature(x)
x=self.sigmod(x)
return x
pass
lr_fn=LR()
loss_fn=torch.nn.BCELoss()
lr=0.01
optimzer=torch.optim.SGD(lr_fn.parameters(),lr=lr,momentum=0.9)
print(optimzer.param_groups[0]['params'])
for iteration in range(1000):
y_pred=lr_fn(train_x)
loss=loss_fn(y_pred,train_y)
loss.backward()
optimzer.step()
optimzer.zero_grad()
上边这个是一个简单的逻辑回归模型, 整个过程就是: 1、数据准备 2、模型构建 3、选择损失函数 4、选择优化器 5、开始迭代更新 其中5里面还有重要步骤: 5.1、调用模型实现前向传播 5.2、计算损失值:前向传播后我们要把结果与期望值做比较得出损失值, 5.3、反向传播:有了损失值之后我们就知道待测值与目标值的差距,计算梯度,寻找更优的参数,然后在前向传播 5.4、参数更新:计算梯度之后,有了新的参数,我们要将旧的参数更新掉,再前向传播 5.5、梯度清零:由于我们的损失值和参数都已经更新了,所以原来的梯度已经没有意义了,要清零,重新计算 待复习问题: 1、一个是损失函数的选择 2、一个是优化器的选择,我们不知道还有哪些优化器,这些优化器通常在什么情况下用
|