零基础入门深度学习(2) - 线性单元和梯度下降

无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的技术,会不会感觉马上就out了?现在救命稻草来了,《零基础入门深度学习》系列文章旨在讲帮助爱编程的你从零基础达到入门级水平。零基础意味着你不需要太多的数学知识,只要会写程序就行了,没错,这是专门为程序员写的文章。虽然文中会有很多公式你也许看不懂,但同时也会有更多的代码,程序员的你一定能看懂的(我周围是一群狂热的Clean Code程序员,所以我写的代码也不会很差)。

文章列表

零基础入门深度学习(1) - 感知器 
零基础入门深度学习(2) - 线性单元和梯度下降 
零基础入门深度学习(3) - 神经网络和反向传播算法 
零基础入门深度学习(4) - 卷积神经网络 
零基础入门深度学习(5) - 循环神经网络 
零基础入门深度学习(6) - 长短时记忆网络(LSTM) 
零基础入门深度学习(7) - 递归神经网络

往期回顾

在上一篇文章中,我们已经学会了编写一个简单的感知器,并用它来实现一个线性分类器。你应该还记得用来训练感知器的『感知器规则』。然而,我们并没有关心这个规则是怎么得到的。本文通过介绍另外一种『感知器』,也就是『线性单元』,来说明关于机器学习一些基本的概念,比如模型、目标函数、优化算法等等。这些概念对于所有的机器学习算法来说都是通用的,掌握了这些概念,就掌握了机器学习的基本套路。

线性单元是啥

感知器有一个问题,当面对的数据集不是线性可分的时候,『感知器规则』可能无法收敛,这意味着我们永远也无法完成一个感知器的训练。为了解决这个问题,我们使用一个可导线性函数来替代感知器的阶跃函数,这种感知器就叫做线性单元。线性单元在面对线性不可分的数据集时,会收敛到一个最佳的近似上。

为了简单起见,我们可以设置线性单元的激活函数 f 为 f(x)=x

这样的线性单元如下图所示

对比此前我们讲过的感知器

这样替换了激活函数 f 之后,线性单元将返回一个实数值而不是0,1分类。因此线性单元用来解决回归问题而不是分类问题。

线性单元的模型

监督学习和无监督学习

接下来,我们需要关心的是这个模型如何训练,也就是参数 w 取什么值最合适。

机器学习有一类学习方法叫做监督学习,它是说为了训练一个模型,我们要提供这样一堆训练样本:每个训练样本既包括输入特征 x ,也包括对应的输出 y ( y 也叫做标记,label)。也就是说,我们要找到很多人,我们既知道他们的特征(工作年限,行业...),也知道他们的收入。我们用这样的样本去训练模型,让模型既看到我们提出的每个问题(输入特征 x ),也看到对应问题的答案(标记 y )。当模型看到足够多的样本之后,它就能总结出其中的一些规律。然后,就可以预测那些它没看过的输入所对应的答案了。

另外一类学习方法叫做无监督学习,这种方法的训练样本中只有 x 而没有 y 。模型可以总结出特征 x 的一些规律,但是无法知道其对应的答案 y 。

很多时候,既有 x 又有 y 的训练样本是很少的,大部分样本都只有 x 。比如在语音到文本(STT)的识别任务中,x 是语音,y 是这段语音对应的文本。我们很容易获取大量的语音录音,然而把语音一段一段切分好并标注上对应文字则是非常费力气的事情。这种情况下,为了弥补带标注样本的不足,我们可以用无监督学习方法先做一些聚类,让模型总结出哪些音节是相似的,然后再用少量的带标注的训练样本,告诉模型其中一些音节对应的文字。这样模型就可以把相似的音节都对应到相应文字上,完成模型的训练。

线性单元的目标函数

现在,让我们只考虑监督学习

梯度下降优化算法

随机梯度下降算法(Stochastic Gradient Descent, SGD)

如果我们根据(式3)来训练模型,那么我们每次更新 w 的迭代,要遍历训练数据中所有的样本进行计算,我们称这种算法叫做批梯度下降(Batch Gradient Descent)。如果我们的样本非常大,比如数百万到数亿,那么计算量异常巨大。因此,实用的算法是SGD算法。在SGD算法中,每次更新 w 的迭代,只计算一个样本。这样对于一个具有数百万样本的训练数据,完成一次遍历就会对更新 w 数百万次,效率大大提升。由于样本的噪音和随机性,每次更新 w 并不一定按照减少 E 的方向。然而,虽然存在一定随机性,大量的更新总体上沿着减少的方向前进的,因此最后也能收敛到最小值附近。下图展示了SGD和BGD的区别

如上图,椭圆表示的是函数值的等高线,椭圆中心是函数的最小值点。红色是BGD的逼近曲线,而紫色是SGD的逼近曲线。我们可以看到BGD是一直向着最低点前进的,而SGD明显躁动了许多,但总体上仍然是向最低点逼近的。

最后需要说明的是,SGD不仅仅效率高,而且随机性有时候反而是好事。今天的目标函数是一个『凸函数』,沿着梯度反方向就能找到全局唯一的最小值。然而对于非凸函数来说,存在许多局部最小值。随机性有助于我们逃离某些很糟糕的局部最小值,从而获得一个更好的模型。

实现线性单元

完整代码请参考GitHub: https://github.com/hanbt/learn_dl/blob/master/linear_unit.py (python2.7)

接下来,让我们撸一把代码。

因为我们已经写了感知器的代码,因此我们先比较一下感知器模型和线性单元模型,看看哪些代码能够复用。

比较的结果令人震惊,原来除了激活函数 f 不同之外,两者的模型和训练规则是一样的(在上表中,线性单元的优化算法是SGD算法)。那么,我们只需要把感知器的激活函数进行替换即可。感知器的代码请参考上一篇文章零基础入门深度学习(1) - 感知器,这里就不再重复了。对于一个养成良好习惯的程序员来说,重复代码是不可忍受的。大家应该把代码保存在一个代码库中(比如git)。

from perceptron import Perceptron
#定义激活函数f
f = lambda x: x
class LinearUnit(Perceptron):
    def __init__(self, input_num):
        '''初始化线性单元,设置输入参数的个数'''
        Perceptron.__init__(self, input_num, f)

通过继承Perceptron,我们仅用几行代码就实现了线性单元。这再次证明了面向对象编程范式的强大。

接下来,我们用简单的数据进行一下测试。

def get_training_dataset():
    '''
    捏造5个人的收入数据
    '''
    # 构建训练数据
    # 输入向量列表,每一项是工作年限
    input_vecs = [[5], [3], [8], [1.4], [10.1]]
    # 期望的输出列表,月薪,注意要与输入一一对应
    labels = [5500, 2300, 7600, 1800, 11400]
    return input_vecs, labels    
def train_linear_unit():
    '''
    使用数据训练线性单元
    '''
    # 创建感知器,输入参数的特征数为1(工作年限)
    lu = LinearUnit(1)
    # 训练,迭代10轮, 学习速率为0.01
    input_vecs, labels = get_training_dataset()
    lu.train(input_vecs, labels, 10, 0.01)
    #返回训练好的线性单元
    return lu
if __name__ == '__main__': 
    '''训练线性单元'''
    linear_unit = train_linear_unit()
    # 打印训练获得的权重
    print linear_unit
    # 测试
    print 'Work 3.4 years, monthly salary = %.2f' % linear_unit.predict([3.4])
    print 'Work 15 years, monthly salary = %.2f' % linear_unit.predict([15])
    print 'Work 1.5 years, monthly salary = %.2f' % linear_unit.predict([1.5])
    print 'Work 6.3 years, monthly salary = %.2f' % linear_unit.predict([6.3])

程序运行结果如下图

拟合的直线如下图

小结

事实上,一个机器学习算法其实只有两部分

  • 模型 从输入特征 x 预测输入 y 的那个函数 h(x)
  • 目标函数 目标函数取最小(最大)值时所对应的参数值,就是模型的参数的最优值。很多时候我们只能获得目标函数的局部最小(最大)值,因此也只能得到模型参数的局部最优值

因此,如果你想最简洁的介绍一个算法,列出这两个函数就行了。

接下来,你会用优化算法去求取目标函数的最小(最大)值。[随机]梯度{下降|上升}算法就是一个优化算法。针对同一个目标函数,不同的优化算法会推导出不同的训练规则。我们后面还会讲其它的优化算法。

其实在机器学习中,算法往往并不是关键,真正的关键之处在于选取特征。选取特征需要我们人类对问题的深刻理解,经验、以及思考。而神经网络算法的一个优势,就在于它能够自动学习到应该提取什么特征,从而使算法不再那么依赖人类,而这也是神经网络之所以吸引人的一个方面。

现在,经过漫长的烧脑,你已经具备了学习神经网络的必备知识。下一篇文章,我们将介绍本系列文章的主角:神经网络,以及用来训练神经网络的大名鼎鼎的算法:反向传播算法。至于现在,我们应该暂时忘记一切,尽情奖励自己一下吧。

参考资料

  1. Tom M. Mitchell, "机器学习", 曾华军等译, 机械工业出版社

原文地址:https://www.zybuluo.com/hanbingtao/note/448086 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值