pytorch 神经网络 关系拟合 (回归)

要点

这次会来见证神经网络是如何通过简单的形式将一群数据用一条线条来表示. 或者说, 是如何在数据当中找到他们的关系, 然后用神经网络模型来建立一个可以代表他们关系的线条.
在这里插入图片描述

建立数据集

我们创建一些假数据来模拟真实的情况. 比如一个一元二次函数: y = a x 2 + b y = ax^2+b y=ax2+b, 我们给 y 数据加上一点噪声来更加真实的展示它.

import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F # 激励函数都在这

#torch.unsqueeze,torch.squeeze,torch.linspace我的之前文章有讲解
#在torch中,只会处理2维的数据,
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
#x.pow(2)的意思是x的平方
y=x.pow(2)+0.2*torch.rand(x.size())

#画图
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()

在这里插入图片描述
pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法

建立神经网络

建立一个神经网络我们可以直接运用 torch 中的体系. 先定义所有的层属性( __init__() ), 然后再一层层搭建(forward(x))层于层的关系链接. 建立关系的时候, 我们会用到激励函数.

class Net(torch.nn.Module):#继承torch的module
    def __init__(self,n_feature,n_hidden,n_output):
        super(Net,self).__init__() #继承__init__功能
        #定义每一层用什么样的样式
        self.hidden = torch.nn.Linear(n_feature,n_hidden) #隐藏层线性输出
        self.predict = torch.nn.Linear(n_hidden,n_output) #输出层线性输出
    def forward(self,x):
        # 激励函数(隐藏层的线性值)
        x=F.relu(self.hidden(x))
        x=self.predict(x) #输出值
        return x

我们定义一个1->10->1的网络结构

net = Net(1,10,1)
print(net)
print(net.parameters())    

结果:

Net(
  (hidden): Linear(in_features=1, out_features=10, bias=True)
  (predict): Linear(in_features=10, out_features=1, bias=True)
)
<generator object Module.parameters at 0x7f4f1116c650>

可以看到Net的内部结构,net.parameters()是表示net模块里的参数,但是这样print看不到内容,我们在net.parameters()外面加上list,就可以打印出里面的内容了

para = list(net.parameters())
print(para)

结果:


[Parameter containing:
tensor([[-0.8071],
        [-0.0896],
        [-0.2232],
        [-0.0489],
        [-0.0234],
        [ 0.7099],
        [ 0.0146],
        [-0.3764],
        [-0.4424],
        [ 0.0315]], requires_grad=True), Parameter containing:
tensor([ 0.2949,  0.8472, -0.2594, -0.8014, -0.9749,  0.2688, -0.0868, -0.8369,
         0.7273, -0.9676], requires_grad=True), Parameter containing:
tensor([[-0.1560,  0.2062,  0.1508,  0.1066,  0.2852,  0.0929,  0.0903,  0.2248,
          0.0319, -0.2936]], requires_grad=True), Parameter containing:
tensor([0.2569], requires_grad=True)]

关于parameters可以看我之前写的博客:
Pytorch之parameters

训练网络

训练的步骤很简单, 如下:

#optimizer是训练的工具
#传入net的所有参数和学习率
optimizer = torch.optim.SGD(net.parameters(),lr=0.2)
print(optimizer)

#预测值和真实值的误差计算公式(均方差)
loss_func = torch.nn.MSELoss()

for t in range(100):
    #喂给net训练数据x,输出预测值
    prediction = net(x)
    #计算两者的误差
    loss = loss_func(prediction,y)

    #先把梯度全部降为0,防止梯度爆炸
    #梯度清0
    optimizer.zero_grad()
    #误差反向传播,计算参数更新
    loss.backward() 
    #更新权重参数
    optimizer.step()

SGD (
Parameter Group 0
    dampening: 0
    lr: 0.2
    momentum: 0
    nesterov: False
    weight_decay: 0
)

这里的内容有点多,先解释optimizer = torch.optim.SGD,这是一个优化器,在我之前的文章有讲解

optimizer.zero_grad():
由于pytorch的动态计算图,当我们使用loss.backward()opimizer.step()进行梯度下降更新参数的时候,梯度并不会自动清零,所以需要optimizer.zero_grad()把梯度归0。并且这两个操作是独立操作

optimizer.zero_grad()
loss.backward() 
optimizer.step()

这三步是搭建神经网络经常会用到的

PyTorch中在反向传播前为什么要手动将梯度清零?optimizer.zero_grad()的意义

可视化训练过程

plt.ion()   # 画图
plt.show()
for t in range(100):
    print(x.shape)
    #喂给net训练数据x,输出预测值
    prediction = net(x)
    #计算两者的误差
    loss = loss_func(prediction,y)
    
    #先把梯度全部降为0,防止梯度爆炸
    #梯度清0
    optimizer.zero_grad()
    #误差反向传播,计算参数更新
    loss.backward() 
    #更新权重参数
    optimizer.step()
    if t % 5 == 0:
        # plot and show learning process
        plt.cla()
        plt.scatter(x.data.numpy(), y.data.numpy())
        plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
        plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color':  'red'})
        plt.pause(0.1)

在这里插入图片描述

完整代码

import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F

#torch.unsqueeze,torch.squeeze,torch.linspace有文章讲解
#在torch中,只会处理2维的数据
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
#x.pow(2)的意思是x的平方
y=x.pow(2)+0.2*torch.rand(x.size())

#画图
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()

class Net(torch.nn.Module):#继承torch的module
    def __init__(self,n_feature,n_hidden,n_output):
        super(Net,self).__init__() #继承__init__功能
        #定义每一层用什么样的样式
        self.hidden = torch.nn.Linear(n_feature,n_hidden) #隐藏层线性输出
        self.predict = torch.nn.Linear(n_hidden,n_output) #输出层线性输出
    def forward(self,x):
        # 激励函数(隐藏层的线性值)
        x=F.relu(self.hidden(x))
#         x=F.relu(self.hidden(x))
        x=self.predict(x) #输出值
        return x
net = Net(1,10,1)
para = list(net.parameters())

#optimizer是训练的工具
#传入net的所有参数和学习率
optimizer = torch.optim.SGD(net.parameters(),lr=0.2)

#预测值和真实值的误差计算公式(均方差)
loss_func = torch.nn.MSELoss()

plt.ion()   # 画图
plt.show()
for t in range(100):
    print(x.shape)
    #喂给net训练数据x,输出预测值
    prediction = net(x)
    #计算两者的误差
    loss = loss_func(prediction,y)
    
    #先把梯度全部降为0,防止梯度爆炸
    #梯度清0
    optimizer.zero_grad()
    #误差反向传播,计算参数更新
    loss.backward() 
    #更新权重参数
    optimizer.step()
    if t % 5 == 0:
        # plot and show learning process
        plt.cla()
        plt.scatter(x.data.numpy(), y.data.numpy())
        plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
        plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color':  'red'})
        plt.pause(0.1)


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值