[ch04-03] 用神经网络处理线性回归问题_腾讯云双十一,腾讯云

  • [ch04-03] 用神经网络处理线性回归问题_腾讯云双十一,腾讯云已关闭评论
  • 105 人浏览
  • A+
所属分类:首页

系列博客,原文在笔者所保护的github上:https://aka.ms/beginnerAI
点击star加星不要悭吝,星越多笔者越勤奋。

4.3 神经收集法

在梯度下落法中,我们简朴报告了一下神经收集做线性拟合的道理,即:

  1. 初始化权重值
  2. 依据权重值放出一个解
  3. 依据均方差函数求偏差
  4. 偏差反向流传给线性盘算部份以调解权重值
  5. 是不是满足停止前提?不满足的话跳回2

一个不适当的比方就是穿糖葫芦:桌子上放了一溜儿12个红果,给你一个充足长的竹签子,选定一个角度,在不挪动红果的前提下,想办法用竹签子穿起最多的红果。

最入手下手你可能会恣意选一个方向,用竹签子比划一下,数数能穿到几个红果,发明是5个;然后调解一下竹签子在桌面上的程度角度,发明能穿到6个......终究你找到了能穿10个红果的的角度。

4.3.1 定义神经收集结构

我们是初次尝试竖立神经收集,先用一个最简朴的单层单点神经元,如图4-4所示。

[ch04-03] 用神经网络处理线性回归问题_腾讯云双十一,腾讯云

图4-4 单层单点神经元

下面,我们用这个最简朴的线性回归的例子,来讲明神经收集中最主要的反向流传和梯度下落的观点、历程以及代码完成。

输入层

此神经元在输入层只接收一个输入特性,经由参数w,b的盘算后,直接输出结果。如许一个简朴的“收集”,只能处理简朴的一元线性回归问题,而且由因而线性的,我们不须要定义激活函数,这就大大简化了顺序,而且便于人人循规蹈矩地明白种种知识点。

严格来讲输入层在神经收集中并不能称为一个层。

权重w/b

因为是一元线性问题,所以w/b都是一个标量。

输出层

输出层1个神经元,线性展望公式是:

\[z_i = x_i \cdot w + b\]

z是模子的展望输出,y是现实的样本标签值,下标 \(i\) 为样本。

丧失函数

因为是线性回归问题,所以丧失函数运用均方差函数。

\[loss(w,b) = \frac{1}{2} (z_i-y_i)^2\]

4.3.2 反向流传

因为我们运用了和上一节中的梯度下落法一样的数学道理,所以反向流传的算法也是一样的,细节请检察4.2.2。

盘算w的梯度

\[ {\partial{loss} \over \partial{w}} = \frac{\partial{loss}}{\partial{z_i}}\frac{\partial{z_i}}{\partial{w}}=(z_i-y_i)x_i \]

盘算b的梯度

\[ \frac{\partial{loss}}{\partial{b}} = \frac{\partial{loss}}{\partial{z_i}}\frac{\partial{z_i}}{\partial{b}}=z_i-y_i \]

为了简化问题,在本小节中,反向流传运用单样本体式格局,鄙人一小节中,我们将引见多样本体式格局。

4.3.3 代码完成

实在神经收集法和梯度下落法在本质上是一样的,只不过神经收集法运用一个极新的编程模子,即以神经元为中心的代码结构设想,如许便于今后的功用扩大。

在Python中能够运用面向对象的手艺,经由过程建立一个类来形貌神经收集的属性和行动,下面我们将会建立一个叫做NeuralNet的class,然后经由过程逐渐向此类中增加要领,来完成神经收集的演习和推理历程。

定义类

class NeuralNet(object):
    def __init__(self, eta):
        self.eta = eta
        self.w = 0
        self.b = 0

NeuralNet类从object类派生,并具有初始化函数,其参数是eta,也就是进修率,须要挪用者指定。别的两个成员变量是w和b,初始化为0。

前向盘算

    def __forward(self, x):
        z = x * self.w + self.b
        return z

这是一个私有要领,所以前面有两个下划线,只在NeuralNet类中被挪用,不对外公然。

反向流传

下面的代码是经由过程梯度下落法中的公式推导而得的,也设想成私有要领:

    def __backward(self, x,y,z):
        dz = z - y
        db = dz
        dw = x * dz
        return dw, db

dz是中心变量,防止反复盘算。dz又能够写成delta_Z,是当前层神经收集的反向偏差输入。

梯度更新

    def __update(self, dw, db):
        self.w = self.w - self.eta * dw
        self.b = self.b - self.eta * db

每次更新好新的w和b的值今后,直接存储在成员变量中,轻易下次迭代时直接运用,不须要在全局局限看成参数内传来传去的。

演习历程

只演习一轮的算法是:

for 轮回,直到一切样本数据运用终了:

  1. 读取一个样本数据
  2. 前向盘算
  3. 反向流传
  4. 更新梯度
    def train(self, dataReader):
        for i in range(dataReader.num_train):
            # get x and y value for one sample
            x,y = dataReader.GetSingleTrainSample(i)
            # get z from x,y
            z = self.__forward(x)
            # calculate gradient of w and b
            dw, db = self.__backward(x, y, z)
            # update w,b
            self.__update(dw, db)
        # end for

推理展望

    def inference(self, x):
        return self.__forward(x)

推理历程,现实上就是一个前向盘算历程,我们把它零丁拿出来,轻易对外接口的设想,所以这个要领被设想成了公然的要领。

主顺序

if __name__ == '__main__':
    # read data
    sdr = SimpleDataReader()
    sdr.ReadData()
    # create net
    eta = 0.1
    net = NeuralNet(eta)
    net.train(sdr)
    # result
    print("w=%f,b=%f" %(net.w, net.b))
    # predication
    result = net.inference(0.346)
    print("result=", result)
    ShowResult(net, sdr)

4.3.4 运转结果可视化

打印输出结果:

w=1.716290,b=3.196841
result= [3.79067723]

终究我们取得了W和B的值,对应的直线方程是\(y=1.71629x+3.196841\)。推理展望时,已知有346台服务器,先要除以1000,因为横坐标是以K(千台)服务器为单元的,代入前向盘算函数,取得的结果是3.74千瓦。

结果显现函数:

def ShowResult(net, dataReader):
    ......

关于初学神经收集的人来讲,可视化的演习历程及结果,能够极大地协助明白神经收集的道理,Python的Matplotlib库供应了非常丰富的画图功用。

在上面的函数中,先取得一切样本点数据,把它们绘制出来。然后在[0,1]之间等距设定10个点做为x值,用x值经由过程收集推理要领net.inference()取得每一个点的y值,末了把这些点连起来,就能够画出图4-5中的拟合直线。

[ch04-03] 用神经网络处理线性回归问题_腾讯云双十一,腾讯云

图4-5 拟合结果

能够看到赤色直线虽然穿过了蓝色点阵,然则彷佛不是处于正中央的位置,应该再逆时针扭转几度才会到达最好的位置。我们背面小节中会讲到怎样进步演习结果的精度问题。

4.3.5 事情道理

就纯真地对待这个线性回归问题,其道理就是先假定样本点是呈线性散布的,注重这里的线性有多是高维空间的,而不仅仅是二维平面上的。然则高维空间人类没法设想,所以我们无妨用二维平面上的问题来举例。

在4.2的梯度下落法中,起首假定这个问题是个线性问题,因而有了公式\(z=xw+b\),用梯度下落的体式格局求解最好的\(w、b\)的值。

在本节中,用神经元的编程模子把梯度下落法包装了一下,如许就进入了神经收集的天下,从而能够有成熟的要领论能够处理更庞杂的问题,比方多个神经元协同事情、多层神经收集的协同事情等等。

如图4-5所示,样本点摆在那边,位置都是牢固的了,神经收集的使命就是找到一根直线(注重我们起首假定这是线性问题),让该直线穿过样本点阵,而且一切样本点到该直线的间隔的平方的和最小。

能够设想成每一个样本点都有一根橡皮筋连接到直线上,连接点间隔该样本点近来,一切的橡皮筋构成一个协力,不断地调解该直线的位置。该协力具有两种调治体式格局:

  1. 假如上方的拉力大一些,直线就会向上平移一些,这相当于调治b值;
  2. 假如侧方的拉力大一些,直线就会向侧方扭转一些,这相当于调治w值。

直到该直线处于平衡位置时,也就是线性拟合的最好位置了。

假如样本点不是呈线性散布的,能够用直线拟合吗?

答案是“能够的”,只是终究的结果不太抱负,偏差能够做到在线性前提下的最小,然则偏差值自身照样比较大的。比方一个半圆形的样本点阵,用直线拟合能够到达偏差值最小为1.2(无妨假定这个值的单元是厘米),已全力了但才能有限。假如用弧线去拟合,能够到达偏差值最小为0.3。

所以,当运用线性回归的结果不好时,即推断出一个问题不是线性问题时,我们会用第9章的要领来处理。

代码位置

ch04, Level3

思索和演习

  1. 请把上述代码中的dw和db也改成私有属性,然后试着运转顺序。
腾讯云双十一活动