zoukankan      html  css  js  c++  java
  • 神经网络学习--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_()
  • 相关阅读:
    MyEclipse 常用快捷键
    javaEE基础08
    MySql卸载重新安装出现Start service没有响应的解决办法(64位)
    javaSE基础07
    为WAMP中的mysql设置密码(默认为空)
    javaSE基础06
    javaSE基础05
    vue框架构建项目流程
    阿里云或本地部署服务器(一)---nginx本地和服务器代理
    修改vue element Transfer 穿梭框里内容区的宽度
  • 原文地址:https://www.cnblogs.com/zuhaoran/p/11454722.html
Copyright © 2011-2022 走看看