Fork me on GitHub 0

简易神经网络

torch.autogard包的主要功能是完成神经网络后向传播中的链式求导。

实现自动梯度功能的过程大致为:先通过输入的Tensor数据类型的变量在神经网络的前向传播过程中生成一张计算图,然后根据这个计算图和输出结果准确计算出每个参数需要更新的梯度,并通过完成后向传播完成对参数的梯度更新。

Variable类对变量类型进行封装,计算图中的各个节点就是一个Variable对象,这样才能自动梯度的功能。

X.data是Tensor数据类型的变量,X.grad是一个Variable对象,表示的是X的梯度,访问梯度值时使用X.grad.data

 

Variable中的requires_grad的值是False,那么表示该变量在进行 自动梯度计算的过程中不会保留梯度值。

代码中的loss.backward()函数功能是让模型根据计算图自动计算每个节点的梯度值并根据需求进行保留。

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

x=Variable(torch.randn(batch_n,input_data),requires_grad=False)
y=Variable(torch.randn(batch_n,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):
    y_pred=x.mm(w1).clamp(min=0).mm(w2)

    loss=(y_pred-y).pow(2).sum()
    print("Epoch:{},Loss:{:.4f}".format(epoch,loss.item()))

    loss.backward()

    w1.data-=learning_rate*w1.grad.data
    w2.data-=learning_rate*w2.grad.data

    w1.grad.data.zero_()
    w2.grad.data.zero_()

  运行结果:

Epoch:0,Loss:42224004.0000
Epoch:1,Loss:77058104.0000
Epoch:2,Loss:308114176.0000
Epoch:3,Loss:817516032.0000
Epoch:4,Loss:156063712.0000
Epoch:5,Loss:25557000.0000
Epoch:6,Loss:14585559.0000
Epoch:7,Loss:9787973.0000
Epoch:8,Loss:7119412.0000
Epoch:9,Loss:5440572.0000
Epoch:10,Loss:4302151.0000
Epoch:11,Loss:3491998.2500
Epoch:12,Loss:2891954.7500
Epoch:13,Loss:2434416.7500
Epoch:14,Loss:2077421.0000
Epoch:15,Loss:1793414.0000
Epoch:16,Loss:1564289.0000
Epoch:17,Loss:1376933.2500
Epoch:18,Loss:1221765.5000
Epoch:19,Loss:1092128.5000

  

模型搭建和参数优化

 

torch.nn.Sequential类是torch.nn中的一种 序列容器,通过在容器中嵌套各种实现神经网络中具体功能相关的类, 来完成对神经网络模型的搭建,最主要的是,参数会按照我们定义好的 序列自动传递下去。

下面代码中

optimzer.zero_grad来完成对模型参数 梯度的归零。

optimzer.step,它的主要功能是 使用计算得到的梯度值对各个节点的参数进行梯度更新。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
batch_n=64
hidden_layer=100
input_data=1000
output_data=10


models=nn.Sequential(
    nn.Linear(input_data,hidden_layer),
    nn.ReLU(),
    nn.Linear(hidden_layer,output_data)
)

x=Variable(torch.randn(batch_n,input_data),requires_grad=False)
y=Variable(torch.randn(batch_n,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=1000
learning_rate=1e-4
loss_fn=nn.MSELoss()
optimzer=optim.Adam(models.parameters(),lr=learning_rate)

for epoch in range(epoch_n):
    y_pred=models(x)

    loss=loss_fn(y_pred,y)
    print("Epoch:{},Loss:{:.4f}".format(epoch,loss.item()))

    optimzer.zero_grad()
    loss.backward()
    optimzer.step()

  运行结果:

Epoch:255,Loss:0.0002
Epoch:256,Loss:0.0002
Epoch:257,Loss:0.0002
Epoch:258,Loss:0.0002
Epoch:259,Loss:0.0001
Epoch:260,Loss:0.0001
Epoch:261,Loss:0.0001
Epoch:262,Loss:0.0001
Epoch:263,Loss:0.0001
Epoch:264,Loss:0.0001
Epoch:265,Loss:0.0001
Epoch:266,Loss:0.0001
Epoch:267,Loss:0.0001
Epoch:268,Loss:0.0001
Epoch:269,Loss:0.0001
Epoch:270,Loss:0.0001
Epoch:271,Loss:0.0001
Epoch:272,Loss:0.0001
Epoch:273,Loss:0.0001
Epoch:274,Loss:0.0001
Epoch:275,Loss:0.0001
Epoch:276,Loss:0.0001
Epoch:277,Loss:0.0001
Epoch:278,Loss:0.0001
Epoch:279,Loss:0.0001
Epoch:280,Loss:0.0000
Epoch:281,Loss:0.0000
Epoch:282,Loss:0.0000
Epoch:283,Loss:0.0000
Epoch:284,Loss:0.0000

  

torch.nn中包含的损失函数:

torch.nn.MSELoss:torch.nn.MSELoss类使用均方误差函数对 损失值进行计算

torch.nn.L1Loss:torch.nn.L1Loss类使用平均绝对误差函数对 损失值进行计算

torch.nn.CrossEntropyLoss:torch.nn.CrossEntropyLoss类用 于计算交叉熵

 

优化函数,torch.optim中包含很多可实现参数自动优化的类,如SGD、RMSProp、AdaGrad、Adam等。

 

posted @ 2020-04-07 18:21  amazingcode  阅读(282)  评论(0编辑  收藏  举报