深度学习pytorch学习笔记之自动梯度

上一篇笔记中搭建了一个简单的神经网络模型,前向学习和反向传播都是使用简单的计算,但是随着模型网络的复杂,反向梯度会变得不容易直接计算,因此引入pytorch中的自动梯度降低代码复杂度

1. autograd和variable

torch.autograd包主要功能是完成网络反向传播时的链式求导
过程大致为:先通过输入的tensor数据类型的变量在神经网络的前向传播中生成一张计算图,然后再根据这个计算图和输出结果准确计算出各个参数需要更新的梯度,并通过完成反向传播对参数进行梯度更新。
在实践中使用autograd包中的variable类进行封装,封装之后计算图中每一个节点就是一个variable对象
因此如果用X代表选中的节点,那么X.data 就是tensor数据对象,X.grad就是X的梯度对象,X.grad.data就是X的梯度数据值啦
同样地我们搭建一个简易二层神经网络使用自动梯度方法和上一篇进行对比

import torch
from torch.autograd import Variable
batch_n=100
input_data=1000
hidden_layer=100
output_data=10

x=Variable(torch.randn(batch_n,input_data),requires_grad=False)
y=Variable(torch.randn(hidden_layer,output_data),requires_grad=False)

w1=Variable(torch.randn(input_data,hidden_layer),requires_grad=True)
w2=Variable(torch.randn(hidden_layer,output_data),requires_grad=True)

epoch_n=20
learning_rate=1e-6

for epoch in range(epoch_n):
    pred_y=x.mm(w1).clamp(min=0).mm(w2)
    loss=(pred_y-y).pow(2).sum()
    print("epoch:{},loss:{:.4f}".format(epoch,loss))
    
    loss.backward()
    w1.data-=learning_rate*w1.grad.data
    w2.data-=learning_rate*w2.grad.data
    
    w1.grad.data.zero_()
    w2.grad.data.zero_()

运行结果:
深度学习pytorch学习笔记之自动梯度_第1张图片
可以看到loss逐渐减小,说明网络起到了效果,和之前的代码相比更加简洁,后向传播的计算部分变成了loss.backward()方法,让模型根据计算图自动计算每一个节点的梯度值,并根据variable中指定require_grad的赋值决定是否保留梯度,因为w1,w2均设置保留,因此这一步计算之后,下面就可以直接使用w1.grad.data调用保留的梯度数据,最后通过zero_方法置为零,防止对下一次迭代进行干扰

2.自定义传播函数

其实我们不止可以简化反向传播计算过程,还可以自定义前向学习的函数

import torch
from torch.autograd import Variable
batch_n=100
input_data=1000
hidden_layer=100
output_data=10

class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        
    def forward(self,inputdata,w1,w2):
        x=torch.mm(inputdata,w1)
        x=torch.clamp(x,min=0)
        x=torch.mm(x,w2)
        print('----')
        return x
    def backward(self):
        pass

model=Model()

x=Variable(torch.randn(batch_n,input_data),requires_grad=False)
y=Variable(torch.randn(hidden_layer,output_data),requires_grad=False)

w1=Variable(torch.randn(input_data,hidden_layer),requires_grad=True)
w2=Variable(torch.randn(hidden_layer,output_data),requires_grad=True)

epoch_n=20
learning_rate=1e-6

for epoch in range(epoch_n):
    pred_y=model(x,w1,w2)
    loss=(pred_y-y).pow(2).sum()
    print("epoch:{},loss:{:.4f}".format(epoch,loss))
    
    loss.backward()
    w1.data-=learning_rate*w1.grad.data
    w2.data-=learning_rate*w2.grad.data
    
    w1.grad.data.zero_()
    w2.grad.data.zero_()        

输出结果:
深度学习pytorch学习笔记之自动梯度_第2张图片

首先是创建类model并继承torch.nn.Module,调用父类的初始化函数,重写forward函数,其实就是把之前执行执行的步骤封装在函数里,然后重写backford方法使用pass不改变原操作
随后创建model实例,在前向学习的时候调用model,接受返回值pred

你可能感兴趣的:(深度学习)