神经网络学习--PyTorch学习02 简单神经网络

使用基本的函数搭建一个两层神经网络(输入层不算做一层)

import torch
batch_n = 100
hidden_layer = 100
input_data = 1000
output_data = 10

x = torch.randn(batch_n, input_data)  # 输入的样本特征
y = torch.randn(batch_n, output_data)  # 输入的样本值
w1 = torch.randn(input_data, hidden_layer)  # 参数1
w2 = torch.randn(hidden_layer, output_data)  # 参数2

epoch_n = 20
learning_rate = 0.1**6
for epoch in range(epoch_n):
    h1 = x.mm(w1)  # 100*100 # 进行前向传播第一层,x*w1 求出 h1(batch_n ,input_date)
    h1 = h1.clamp(min=0)  # 裁剪结果h1 相当于使用ReLu 激活函数
    y_pred = h1.mm(w2)  # 100*10 #前向传播第二层,h1*w2 求出 y_pred(batch_n,output_data)

    loss = (y_pred - y).pow(2).sum()  # 计算损失 求(y_pred - y)的平方的和,y_pred ,y是大小为(batch_n,output_data)的矩阵
    print("Epoch:{},Loss:{:.4f}".format(epoch,loss))  # 输出批次和损失

    grad_y_pred = 2*(y_pred - y)
    grad_w2 = h1.t().mm(grad_y_pred)  # 第二层网络求导 第一层结果的转置乘预测结果,得到梯度

    grad_h = grad_y_pred.clone()  # 克隆
    grad_h = grad_h.mm(w2.t())  # 链式求导1 预测结果乘第二层网络的系数,得到导数
    grad_h.clamp_(min=0)  # ReLu
    grad_w1 = x.t().mm(grad_h)  # 链式求导2 x的转置乘求导1的结果 得到梯度

    w1 -= learning_rate*grad_w1  # 修改参数,学习率乘梯度
    w2 -= learning_rate*grad_w2

 

torch.autograd包

主要用于完成神经网络后向传播中的链式求导

Variable类

torch.autograd包中的Variable类,将Tensor数据类型变量进行封装。计算图中的每个节点变为一个Variable对象,来应用自动梯度。

Variable对象X中, X.data为Tensor数据类型变量,X.grad代表X的梯度,梯度的值为X.grad.data。

loss.backward()

让模型根据计算图自动计算每个节点的梯度值。

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


class Model(torch.nn.Module):  # 继承torch.nn.Module  重写网络的前向传播和后向传播
    def __init__(self):
        super(Model,self).__init__()

    def forward(self, input, w1, w2):  # 前项传播
        x = torch.mm(input, w1)
        x = torch.clamp(x, min=0)
        x = torch.mm(x, w2)
        return x

    def backward(self):  # 跳过,主函数中用loss.backward()进行反向求导
        pass


model = Model()
x = Variable(torch.randn(batch_n, input_data), requires_grad=False)  # x封装为节点,设置为不自动求导
y = Variable(torch.randn(batch_n, output_data), requires_grad=False)
w1 = Variable(torch.randn(input_data, hidden_layer), requires_grad=True)  # w1封装为节点,设置为自动求导
w2 = Variable(torch.randn(hidden_layer, output_data), requires_grad=True)

epoch_n = 20
learning_rate = 0.1**6
for epoch in range(epoch_n):
    y_pred = model(x, w1, w2)  # 通过模型计算得到预测结果
    loss = (y_pred - y).pow(2).sum()  # 计算损失
    print("Epoch:{},Loss:{:.4f}".format(epoch, loss.data[0]))
    loss.backward()  # 反向传播

    w1.data -= learning_rate*w1.grad.data  # 进行学习,更新参数
    w2.data -= learning_rate*w2.grad.data

    w1.grad.data.zero_()  # 梯度重置
    w2.grad.data.zero_()

 

posted @ 2019-09-03 18:26  键盘已坏  阅读(398)  评论(0编辑  收藏  举报