当前位置:   article > 正文

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述
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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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

net = Net(1,10,1)
print(net)
print(net.parameters())    
  • 1
  • 2
  • 3

结果:

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>
  • 1
  • 2
  • 3
  • 4
  • 5

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

para = list(net.parameters())
print(para)
  • 1
  • 2

结果:


[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)]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

关于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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
SGD (
Parameter Group 0
    dampening: 0
    lr: 0.2
    momentum: 0
    nesterov: False
    weight_decay: 0
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

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

optimizer.zero_grad()
loss.backward() 
optimizer.step()
  • 1
  • 2
  • 3

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

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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这里插入图片描述

完整代码

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)


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/123513
推荐阅读
相关标签
  

闽ICP备14008679号