pytorch深度学习笔记(二)- pytorch框架搭建一个简单的神经网络模型

通过pytorch框架搭建一个简单的神经网络模型

如何基于pytorch深度学习框架用简单快捷的方式搭建出复杂的神经网络模型,同时让模型参数的优化方法趋于高效。

如何使用pytorch中的自动梯度方法,在搭建复杂的神经网络模型的时候,我们也可以使用pytorch中已定义的类和方法,这些类和方法覆盖了神经网络中的线性变换、激活函数、全连接层、池化层等常用的神经网络结构的实现。

在完成模型的搭建之后,我们还可以使用pytorch提供的类型丰富的优化函数来完成对模型的优化。

(一)模型初始化 - 导包、设置参数

import torch
from torch.autograd import variable

batch_n = 50
hidden_layer = 50
input_data = 500
output_data = 5

x = variable(torch.randn(batch_n,input_data),requires_grad = False)   #(50,500)
y = variable(torch.randn(batch_n,output_data),requires_grad = False)  #(50,5)

batch_n:在一个批次中输入数据的数量,值是50,这意味着我们在一个批次中输入50个数据。
input_data:每个数据包含的数据特征有input_data个,因为值是500,所以每个数据的数据特征就是500个。
hidden_layer:用于定义经过隐藏层后保留的数据特征的个数,这里有50个,因为我们的模型只考虑一层隐藏层,所以在代码中仅定义了一个隐藏层的参数。
output_data:输出的数据,值是5,我们可以将输出的数据看作一个分类结果值的数量,个数5表示我们最后要得到5个分类结果值。

Variable(torch.randn(batch_n,input_data),requires_grad = False):这段代码就是用variable类对Tensor数据类型变量进行封装的操作。
在以上代码中还使用了一个requires_grad参数,这个参数的赋值类型是Boolean类型,如果requires_grad的值是False,那么表示该变量在进行自动梯度计算的过程中不会保留梯度值。
我们将输入的数据 × 和输出的数据 y 的requires_grad参数均设置为False,这是因为这两个变量并不是我们的模型需要优化的参数,而两个权重 w1 和 w2 的requires_grad参数的值为True。

(二)模型搭建

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

pytorch中的 torch.nn 包提供了很多与实现神经网络中的具体功能相关的类,这些类涵盖了深度神经网络模型在搭建和参数优化过程中的常用内容,比如神经网络中的卷积层、池化层、全连接层这类层次构造的方法、防止过拟合的参数归一化方法、Dropout方法,还有激活函数部分的线性激活函数、非线性激活函数相关的方法等。
torch. nn. Sequential括号内的内容就是我们搭建的神经网络模型的具体结构,这里:1.首先通过 torch. nn.Linear (input data, hidden_layer)完成从输入层到隐藏层的线性变换。2.然后经过激活函数 ReLU 及 torch. nn. Linear (hidden_layer , output_ data)完成从隐藏层到输出层的线性变换。

torch.nn.Sequential( )

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

torch.nn.Linear( )

torch. nn.Linear 类用于定义模型的线性层,即完成前面提到的不同的层之间的线性变换。torch. nn.Linear 类接收的参数有三个,分别是:1.输入特征数 2.输出特征数 3.是否使用偏置(设置是否使用偏置的参数是一个布尔值,默认为True,即使用偏置)
在本文中自定义的输入输出层来看:它的输入是一个批次中包含50个特征数为500的数据,最后得到50个特征数为5的输出数据,中间需要经过两次线性变换,所以要使用两个线性层,两个线性层的代码分别是
●torch. nn. Linear(input_ data, hidden_ layer)
●torch. nn. Li near(hidden_ layer, output_ data)

torch.nn.ReLU( )

torch. nn. ReLU 类属于非线性激活函数,在定义时默认不需要传入参数。当然,在 torch. nn 包中还有许多非线性激活函数类可供选择,比如 PReLU、LeakyReLU、 Tanh、 Sigmoid、 Softmax。

基本的神经网络模型构架好了之后,接下来我们要定义损失函数,学习率,迭代次数,为训练我们的神经网络模型做基础。

(三)设置损失函数

epoch_n = 200
lr = 1e-4
loss_n = torch.nn.MSELoss()
torch.nn.MSELoss( )

在使用torch.nn . MSELoss 函数前必须先进行实例化->创建一个对象 = torch. nn. MSELoss 类使用均方误差函数对损失值进行计算,在定义类的对象时不用传入任何参数,但在使用实例时需要输入两个维度一样的参数方可进行计算。

torch.optim

到这里有深度学习基础的小伙伴可能就发现了,神经网络的模型已经构架完成了,接下来就是对模型进行训练?不对,我们还要对模型进行优化,这里的优化其实就是对模型的参数进行优化。这也就引出接下来神经网络的优化器。
在PyTorch的 torch. optim 包中提供了非常多的可实现参数自动优化的类,比如 SGD、AdaGrad、RMSProp、Adam等, 这些类都可以被直接调用,使用起来也非常方便。

(四)模型优化器

#优化器
optimization = torch.optim.Adam(models.parameters(),lr = lr)

这里使用了 torch. optim 包中的 torch. optim . Adam 类作为我们的模型参数的优化函数,在 torch. optim. Adam 类中输入的是被优化的参数和学习速率的初始值,如果没有输入学习速率的初始值,那么默认使用0.001这个值。因为我们需要优化的是模型中的全部参数,所以传递给 torch. optim.Adam 类的参数是 models.parameters。另外,Adam 优化函数还有一个强大的功能,就是可以对梯度更新使用到的学习速率进行自适应调节,所以最后得到的结果自然会比之前的代码更理想。

接下来就要训练我们的模型了~~

(五)模型训练

#对神经网络模型进行训练
for epoch in range(epoch_n):
    y_pred = models(x)
    loss = loss_n(y_pred,y)
    if epoch %2 == 0:
        print("epoch:{},loss:{:.4f}".format(epoch,loss.data))
    optimization.zero_grad()   #每次迭代梯度都要清零
    loss.backward()            #反向传播,计算梯度
    optimization.step()        #参数更新
optimization.step( )

声明这里的 optimization 函数不是内部函数,而是自己在优化器代码块中,自己实例化的一个函数。
optimization.zero_grad( ) 先将梯度清零
loss.backward() 然后反向传播计算得到每个参数的梯度值
optimization.step() 通过梯度下降执行一步参数更新

到这里我们用pytorch框架就已经学会构建一个简单的深度学习框架了~~下面是完整的代码以及实验的结果

import torch
from torch.autograd import variable

batch_n = 50
hidden_layer = 50
input_data = 500
output_data = 5

x = variable(torch.randn(batch_n,input_data),requires_grad = False)   #(50,500)
y = variable(torch.randn(batch_n,output_data),requires_grad = False)  #(50,5)

#神经网路结构
models = torch.nn.Sequential(torch.nn.Linear(input_data,hidden_layer),
                             torch.nn.ReLU(),
                             torch.nn.Linear(hidden_layer,output_data))

#对搭建的神经网络模型定义损失函数,迭代次数,学习率
epoch_n = 200
lr = 1e-4
loss_n = torch.nn.MSELoss()

#优化器
optimization = torch.optim.Adam(models.parameters(),lr = lr)

#对神经网络模型进行训练
for epoch in range(epoch_n):
    y_pred = models(x)
    loss = loss_n(y_pred,y)
    if epoch %2 == 0:
        print("epoch:{},loss:{:.4f}".format(epoch,loss.data))
    optimization.zero_grad()   #每次迭代梯度都要清零
    loss.backward()            #反向传播,计算梯度
    optimization.step()        #参数更新

实验结果:
epoch:0,loss:0.9471
epoch:2,loss:0.9201
epoch:4,loss:0.8939
epoch:6,loss:0.8684
epoch:8,loss:0.8438
epoch:10,loss:0.8202
epoch:12,loss:0.7972
epoch:14,loss:0.7750
epoch:16,loss:0.7534
epoch:18,loss:0.7327
epoch:20,loss:0.7127
(省略)
epoch:190,loss:0.0339
epoch:192,loss:0.0323
epoch:194,loss:0.0307
epoch:196,loss:0.0293
epoch:198,loss:0.0278

从结果上可以初始的损失值就不是很大,一方面取决于我们的模型简单,模型参数本身就没设置很大的数值,另一方面就是优化器的作用,感兴趣的小伙伴可以把初始化的值变得大一些,然后去掉优化器,在进行训练,得到的损失值一定会比这个损失大很多~

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇敢牛牛@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值