专栏首页HansBug's Lab【学习笔记】深度学习 demo2 二次函数回归

【学习笔记】深度学习 demo2 二次函数回归

在本demo中,我们使用的二次函数为

\[\begin{aligned} f(x) &= \left(x - 4 \right) \left(x - 8\right) + rand \\ &= x ^ 2 - 12 x + 32 + rand \end{aligned} \]

其中\(rand\)表示一个满足标准正态分布\(N\left(0, 1\right)\)的随机数(平均值为0,方差为1)

基于Parameter手动构建

我们可以尝试用类似的方式,从参数(Parameter)开始构建一个二次函数。

一个二次函数的基本结构如下

\[g\left(x\right)=ax^2+bx+c \]

其中包含三个参数:\(a\)、\(b\)、\(c\)。

代码如下:

import matplotlib.pyplot as plt
import torch
from torch import nn
from torch.autograd import Variable


class SquareRegression(nn.Module):
    def __init__(self):
        nn.Module.__init__(self)
        self.a = nn.Parameter(torch.randn(1, 1), requires_grad=True)  # 1 x 1
        self.b = nn.Parameter(torch.randn(1, 1), requires_grad=True)  # 1 x 1
        self.c = nn.Parameter(torch.randn(1, 1), requires_grad=True)  # 1 x 1

    def forward(self, x_):
        p_ = (x_ ** 2).mm(self.a)  # n x 1
        q_ = x_.mm(self.b)         # n x 1
        t_ = self.c                # 1 x 1
        return p_ + q_ + t_.expand_as(p_)  # n x 1


if __name__ == "__main__":
    n = 100
    x = torch.linspace(-2, 12, n).resize_((n, 1))  # n x 1 tensor
    y = (x - 4) * (x - 8) + torch.randn(x.size())  # n x 1 tensor

    model = SquareRegression()

    criterion = nn.MSELoss()
    optimizer = torch.optim.SGD(model.parameters(), lr=2e-5)

    num_epochs = 500000
    for epoch in range(num_epochs):
        inputs, targets = Variable(x), Variable(y)

        out = model(inputs)
        loss = criterion(out, targets)

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

        if (epoch + 1) % 100 == 0:
            print('Epoch[{}/{}], loss:{:.6f}'.format(epoch + 1, num_epochs, loss.item()))

    for name, param in model.named_parameters():
        print(name, param.data)

    predict = model(x)

    plt.plot(x.numpy(), y.numpy(), 'ro', label='Original Data')
    plt.plot(x.numpy(), predict.data.numpy(), label='Fitting Line')
    plt.show()

输出结果如下:

Epoch[100/500000], loss:386.833191
Epoch[200/500000], loss:385.401001
Epoch[300/500000], loss:383.982391
Epoch[400/500000], loss:382.576904
Epoch[500/500000], loss:381.184418
Epoch[600/500000], loss:379.804657
Epoch[700/500000], loss:378.437256
Epoch[800/500000], loss:377.082153
Epoch[900/500000], loss:375.738983
Epoch[1000/500000], loss:374.407532
Epoch[1100/500000], loss:373.087585
Epoch[1200/500000], loss:371.778870
Epoch[1300/500000], loss:370.481293
Epoch[1400/500000], loss:369.194580
Epoch[1500/500000], loss:367.918549

... ... ... ...

Epoch[499400/500000], loss:0.985296
Epoch[499500/500000], loss:0.985296
Epoch[499600/500000], loss:0.985296
Epoch[499700/500000], loss:0.985296
Epoch[499800/500000], loss:0.985296
Epoch[499900/500000], loss:0.985296
Epoch[500000/500000], loss:0.985296
a tensor([[1.0048]])
b tensor([[-12.0305]])
c tensor([[31.8826]])

生成图像如下:

可以发现,我们生成的拟合解如下

\[\begin{cases} a &= 1.0048 \\ b &= -12.0305 \\ c &= 31.8826 \end{cases} \]

所得到的函数为

\[\begin{aligned} g\left(x\right) &= a x^2 + b x + c \\ &= 1.0048 x^2 -12.0305 x + 31.8826 \end{aligned} \]

和原公式\(f(x) = x^2 - 12 x + 32\)已经十分接近,图像上的拟合结果也与期望结果基本一致。

基于Linear叠加构建

除此之外,我们还可以通过叠加Linear来构建一个二次函数。

本次使用的公式如下:

\[\begin{aligned} h\left(x\right) &= \left(w_1 x + b_1\right) \left(w_2 x + b_2\right) \\ &= w_1 w_2 x + \left(w_1 b_2 + w_2 b_1\right)x + b_1 b_2 \end{aligned} \]

包含四个参数\(w_1\)、\(b_1\)、\(w_2\)、\(b_2\)。

代码如下:

import matplotlib.pyplot as plt
import torch
from torch import nn
from torch.autograd import Variable


class SquareRegression(nn.Module):
    def __init__(self):
        nn.Module.__init__(self)
        self.linear1 = nn.Linear(1, 1)
        self.linear2 = nn.Linear(1, 1)

    def forward(self, x_):
        return self.linear2(x_) * self.linear1(x_)  # n x 1


if __name__ == "__main__":
    n = 100
    x = torch.linspace(-2, 12, n).resize_((n, 1))  # n x 1 tensor
    y = (x - 4) * (x - 8) + torch.randn(x.size())  # n x 1 tensor

    model = SquareRegression()

    criterion = nn.MSELoss()
    optimizer = torch.optim.SGD(model.parameters(), lr=2e-5)

    num_epochs = 20000
    for epoch in range(num_epochs):
        inputs, targets = Variable(x), Variable(y)

        out = model(inputs)
        loss = criterion(out, targets)

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

        if (epoch + 1) % 100 == 0:
            print('Epoch[{}/{}], loss:{:.6f}'.format(epoch + 1, num_epochs, loss.item()))

    for name, param in model.named_parameters():
        print(name, param.data)

    predict = model(x)

    plt.plot(x.numpy(), y.numpy(), 'ro', label='Original Data')
    plt.plot(x.numpy(), predict.data.numpy(), label='Fitting Line')
    plt.show()

输出结果如下:

Epoch[100/20000], loss:448.569519
Epoch[200/20000], loss:444.616638
Epoch[300/20000], loss:441.241089
Epoch[400/20000], loss:438.343903
Epoch[500/20000], loss:435.845673
Epoch[600/20000], loss:433.682007
Epoch[700/20000], loss:431.799835
Epoch[800/20000], loss:430.154999
Epoch[900/20000], loss:428.709595
Epoch[1000/20000], loss:427.431366
Epoch[1100/20000], loss:426.291718
Epoch[1200/20000], loss:425.265594
Epoch[1300/20000], loss:424.330353
Epoch[1400/20000], loss:423.465973
Epoch[1500/20000], loss:422.654541

... ... ... ...

Epoch[19400/20000], loss:1.044041
Epoch[19500/20000], loss:1.044041
Epoch[19600/20000], loss:1.044041
Epoch[19700/20000], loss:1.044041
Epoch[19800/20000], loss:1.044041
Epoch[19900/20000], loss:1.044041
Epoch[20000/20000], loss:1.044041
linear1.weight tensor([[0.7155]])
linear1.bias tensor([-5.7249])
linear2.weight tensor([[1.4002]])
linear2.bias tensor([-5.6002])

生成图像如下:

可以发现,我们生成的拟合解如下

\[\begin{cases} w_1 &= 0.7155 \\ b_1 &= -5.7249 \\ w_2 &= 1.4002 \\ b_2 &= -5.6002 \end{cases} \]

所得到的函数为

\[\begin{aligned} h(x) &= \left( w_1 x + b_1 \right) \left( w_2 x + b_2 \right) \\ &= \left( 0.7155 x - 5.7249 \right) \left( 1.4002 x - 5.6002 \right) \\ &= 1.0018431 x^2 - 12.02294808 x + 32.06058498 \end{aligned} \]

和原公式\(f(x) = x^2 - 12 x + 32\)已经十分接近,图像上的拟合结果也与期望结果基本一致。而且训练速度还得到了大幅度的提高(原本进行了500000次,这次在使用同样learning rate的情况下,只进行了20000次就达到了类似的效果。

其他

关于Linear

通过阅读源码可以发现,Linear内含两个最为关键的参数:weight和bias。一定程度上可以理解为所构建的线性函数公式为

\[f(x) = wx + b \]

以此类推并扩展,在2输入(in_features == 2)3输出(out_features == 3)的时候,公式为:

\[\begin{cases} f_1(x) &= w_{1, 1} x_1 + w_{1, 2} x_2 + b_1 \\ f_2(x) &= w_{2, 1} x_1 + w_{2, 2} x_2 + b_2 \\ f_3(x) &= w_{3, 1} x_1 + w_{3, 2} x_2 + b_3 \end{cases} \]

其中\(w\)和\(b\)都将以Tensor的格式,作为weight和bias进行存储,前向传播的时候则会进行矩阵运算并生成计算图。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【学习笔记】深度学习 demo1 线性回归

    本人近期开始尝试基于pytorch框架,从原理上理解深度学习。在这几个demo中将会展示一些基本的操作及其效果,并基于个人的一点粗浅理解进行原理描述,如有不当之...

    HansBug
  • 逻辑回归 | TensorFlow深度学习笔记

    课程目标:学习简单的数据展示,训练一个Logistics Classifier,熟悉以后要使用的数据 Install Ipython NoteBook 可以参考...

    用户1332428
  • 【动手学深度学习笔记】之softmax回归

    对于离散值预测问题,我们可以使用诸如softmax回归这样的分类模型。softmax回归模型有多个输出单元。本章以softmax回归模型为例,介绍神经网络中的分...

    树枝990
  • 【动手学深度学习笔记】之线性回归

    线性回归是单层神经网络,设计的概念和技术适用于大多数深度学习模型;因此,我们以线性回归为例,学习深度学习模型的基本要素和表示方法。

    树枝990
  • 吴恩达深度学习笔记2.2 logistic回归

    Dar_Alpha
  • 深度学习笔记1--线性回归模型

    「学习内容总结自 udacity 的深度学习课程,截图来自 udacity 的课件」

    caoqi95
  • TensorFlow 深度学习笔记 逻辑回归 实践篇

    Practical Aspects of Learning Install Ipython NoteBook 可以参考这个教程 可以直接安装anaconda,里...

    梦里茶
  • 【动手学深度学习笔记】之线性回归实现

    这一节不牵扯深度学习框架,仅使用Tensor和autograd库来训练线性回归模型。

    树枝990
  • 【动手学深度学习笔记】之PyTorch实现softmax回归

    由softmax回归模型的定义可知,softmax回归模型只有权重参数和偏差参数。因此可以使用神经网络子模块中的线性模块。

    树枝990
  • 《深度学习》学习笔记二——概率论

    随机变量(random variable)是可以随机地取不同值的变量.随机变量是可以离散的或者连续的,离散随机变量拥有有限或可数无限多的状态,连续随机变量伴随这...

    夜雨飘零
  • 深度学习 || 06 线性回归——参数学习

    ,我 们希望能够学习一个最优的线性回归的模型参数w。下面介绍四种不同的参数估计方法:经验风险最小化、结构风险最小化、 最大似然估计、最大后验估计。

    啤酒单恋小龙虾
  • 层次数据的深度自回归模型学习

    我们提出了一种用于分层结构化数据的模型,作为对随机时间卷积网络(STCN)的扩展。该模型将自回归模型与分层变分自编码器和下采样相结合,以实现较高的计算复杂度。我...

    irin
  • 【动手学深度学习笔记】之实现softmax回归模型

    设置小批量数目为256。这一部分与之前的线性回归的读取数据大同小异,都是转换类型-->生成迭代器。

    树枝990
  • 【动手学深度学习笔记】之Pytorch实现线性回归

    Pytorch提供了大量预定义的层,使用框架时,主要是需要关注使用哪些层来构造模型。

    树枝990
  • 深度学习(二十九)Batch Normalization 学习笔记

    原文地址:http://blog.csdn.net/hjimce/article/details/50866313

    GavinZhou
  • 吴恩达深度学习笔记 2.3 logistic回归损失

    损失函数测量预测(p()和期望输出(y()之间的差异。换句话说。损失函数计算单个培训示例的错误。

    Dar_Alpha
  • 机器学习测试笔记(17)——线性回归函数

    普通最小二乘线性回归。线性回归拟合系数为w=(w1,…,wp)的线性模型,以最小化数据集中观测目标和线性近似预测目标之间差的平方和。

    小老鼠
  • 技术角 | 深度学习之《深度学习入门》学习笔记(二)感知机

    最近学习吴恩达《Machine Learning》课程以及《深度学习入门:基于Python的理论与实现》书,一些东西总结了下。现就后者学习进行笔记总结。本文是本...

    ZNing
  • 机器学习深度学习 笔试面试题目整理(3)

    (2)逻辑回归的基本概念    这个最好从广义线性模型的角度分析,逻辑回归是假设y服从Bernoulli分布。

扫码关注云+社区

领取腾讯云代金券