【第20期】实践深度学习?先接住这三板斧再说
作者:木羊同学
来源:华章计算机(hzbook_jsj)
深度学习发展到现在,已经不是红不红的问题,真的是那种谈项目做课题不扯两句深度学习,别人就要来怀疑你用的技术是不是落后于时代。可是,深度学习的书和论文看起来好像都很难,就算删掉那些明摆着欺负人的数学公式,剩下又是图又是表的,照样看得人无从下手,怎么动手实践呢?今天我们就来聊聊深度学习实践的三把板斧。
要手撸深度学习模型的代码,首先得选一把趁手的工具。业内现在基本都是推荐使用Python语言来实现深度学习模型,不过,这还没到第一步。想必你已经听过很多Python简单易用、十分好学的说法。不过,真要使用Python从零开始实现产品级的深度学习模型,那相当于要自己从挖地基开始,盖一栋房子,简直是一件地狱难度的任务。
不过好在,Python除了简单易用,另一大优势就是出了名的库多——没什么工作是不能import一个库来完成的,如果有,那就import两个库。在深度学习方面也不例外,现在市面上最最常用的Python深度学习库有两个,一个叫Tensorflow——Google出品,另一个叫Pytorch——Facebook出品。这里先说一点,既然Python是出了名的库多,深度学习库自然也不只是这俩,很多大公司都推出了自己的深度学习库,譬如Amazon出了Mxnet,百度出了PaddlePaddle,而且很难说哪家的就技高一筹,别人难以望其项背,只能说各具特色。不过,玩编程的同学应该知道,生态这玩意有很多时候比技术本身更重要。在深度学习方面,目前占据“头部”的就是Tensorflow和Pytorch。那么你的第一个工作,就是在这俩之中选择一款来用。
Tensorflow和Pytorch要怎么选这个问题,现在是道送命题——两边阵营吵得不可开交:按一般的说法,学界偏好Pytorch,写法更加干净清爽,而工业界则更喜欢Tensorflow。Tensorflow推出更早,可以说是紧紧跟随这一波深度学习浪潮一同崛起,生态更为完整,同时有着Google强大的工程应用能力加持,在产品化方面做得更为成熟。
Tensorflow有一个重要的特点,也是重要的槽点,就是计算图。Tensorflow的计算图写法总让人有一种难以言传的别扭,有一批对此深恶痛绝的用户最后成了Pytorch的铁杆粉丝。不过,单就技术来说,要使用深度学习,计算图是无法避免的,Pytorch也同样依赖计算图。不过,计算图有两种,一种是必须先搭后用的静态图,一种是更为灵活但运行效率低一些的动态图。究竟是选择效率更高的静态图,还是牺牲效率选择写法更友好的动态图,只能说尺有所短寸有所长,和具体的应用场景有关,没有一个绝对的定论。
Tensorflow刚推出时选择的是静态图,没想成了劝退神器,相当部分的深度学习开发者纷纷表示各种不适应,连“这不Python”之类的话都喊出来了。我自己的感想是:写法这东西,每个人的接受程度不同,我相对来说没那么反感,但静态图的引入,确实对调试带来了一些不便。
但Tensorflow一直在迭代升级,很快也支持了动态图,称为“Eager Execution”。不仅如此,目前Tensorflw已经进入2.0时代,不但支持动态图,而且进行了大规模的优化,Eager Execution也成了默认的执行方式。Google一直在推Tensorflow与Keras深度融合,现在的Tensorflow早比1.0时代友善多了。
选好了工具,第二步就是搭建深度神经网络模型。很多初学者会担心,现在市面上的深度学习库这么多,每一个学起来也都不见得太容易,如果第一步选的工具后面发现不合适,决定要换,是不是还得重头再学一遍?
不用担心,实际情况比想象得要好一些。在我看来,使用这些不同的深度学习库来搭建深度神经网络模型,就好比使用不同的编程语言来实现同一套算法,虽然具体的某些细节总会有一些不同,但思路是完全一样的,大体上来说是大同小异,有了一种深度学习库的使用经验,完全可以很快迁移到另一种深度学习库上去,在这一点上大可放心。所以,学习的关键还是在于深度神经网络模型本身,而非深度学习库的使用细节。
首先自然就是如何搭建深度神经网络。这个问题可以分成两个部分,第一个部分,我们先来说说深度神经网络的历史传承。深度学习是近年红起来的,但并不是凭空蹦出来的技术。
深度学习和机器学习一脉相承,具体来说,机器学习是一批智能算法的集合,其中有一种历史悠久的算法,叫神经网络算法,这套算法至少有60年的历史,但许多东西一直沿用到了深度学习模型里面。我们说的深度学习,其实都知道指的是深度神经网络,意思就是层数加深了的神经网络,所以,搭建神经网络也好,搭建深度神经网络也好,首先需要考虑的就是拿什么来构建这个“网络”。
答案是神经元。神经网络嘛,最小的构成单位自然是神经元,得先了解神经元的结构,实现了神经元,然后才能再谈构建神经网络。
那神经元是怎样的结构呢?我在《机器学习算法的数学解析与Python实现》中专门介绍了神经网络,说到神经元,书里说“就像一只爆炸头的蝌蚪”,头发就是输入,有很多的输入,所以是爆炸头。尾巴是输出,一个神经元只有一项输出,所以是蝌蚪。
既然有很多的输入,那是直接输入的吗?不是,加权输入,如果你了解线性回归,或者翻过《机器学习算法的数学解析与Python实现》这本书,一定会马上反应过来:这不就是线性方程嘛!
没错,神经元的输入就是一个线性方程,唯一的区别在于,这条线性方程的结果在最终输出时,需要先经过一个特殊的函数,叫激活函数,所以,对于神经元的结构,我们可以简单地理解为:线性方程+激活函数=神经元。
线性方程好说,你可能会担心:这个激活函数该如何实现?其实,在搭建模型时,深度学习库一般都会提供各类常用的激活函数,你只要选择需要的激活函数即可。譬如说你在论文上看到Relu函数作为激活函数效果很好,你甚至不需要知道Relu函数的表达式,只要在深度学习库中选取Relu,然后把线性方程套进去,神经元的构建就完成了。
那神经元怎么构成神经网络呢?那就更简单了,只要将这一个个小蝌蚪们头尾相衔,前一位的输出作为后一位的输入,这就构成了最基本的前馈神经网络。前馈是什么意思呢?就是输入由前至后地传递,一级一级向后传的意思。
那,还有不基本的神经网络?
正是。深度学习的兴起,并不是单纯靠加深神经网络的层数这么简单粗暴,还添加了许多“魔改”的神经元组件,譬如说深度学习的龙兴之地——深度卷积神经网络(CNN),要实现这个,首先就需要使用卷积核这个组件。
卷积核的功能比较复杂,小蝌蚪们是指望不上了,那如何是好呢?非常简单,深度学
习库里一定都准备好了,只要找到对应的API,譬如说深度卷积网络所必须的卷积层和池化层,像搭乐高积木一样,把这些组件装配起来,深度神经网络也就搭建好了。其它的“魔改”深度学习组件,譬如循环神经网络(包括RNN、LSTM和GRU),也可以按同样方式处理。
这里多说一句。深度学习的许多大牛都说过一句话:“搭建深度学习模型像装配乐高积木,十分有意思。”这在深度学习库推出之前,相关的工作其实并没有那么美好,有不少繁琐的细节,但现在有了成熟的深度学习库,搭建深度学习模型就真的像“搭积木”了。
现在,深度神经网络模型搭建好了,是不是就大功告成了呢?很可惜,接下来的第三步才是整个流程中最费时费力,当然也是最费电的环境——模型训练环节。
深度学习模型的训练,有一点像我们玩的《愤怒的小鸟》。这个游戏怎么玩呢?首先你得瞄准一头绿色哼哼叫的猪,然后用手指控制弹弓,带动小鸟拉出一条弹道,最后放手,小鸟就飞了出去。怎么算训练成功呢?直接命中了那头猪,训练就成功了。但在一般情况下,“一发入魂”的可能性非常低,这就需要调整,不断修正弹道,以求最终击中那头绿猪。
这个不断修正弹道的过程,就是模型的训练过程。这里有几个要素,首先是损失函数,在模型训练中,最终目标是让损失函数最小。
然后是误差传递,误差传递这个概念按教材讲起来很容易让人昏昏欲睡,不过其实非常简单,前面我们不是说要调整弹道嘛,那怎么调整呢?是上一点还是右一点?总要有个依据。误差传递就是传递这个依据,把误差告诉你,也就是把偏了多少告诉你,你就根据这个调整去吧。
不过实际工作要复杂一点,在多层神经网络中,误差传递是一项颇具挑战的工作,研究人员尝试了很久,最终才懂得,使用有名的反向传播机制(BP)来训练多层网络。因此,反向传播机制也就成了神经网络、包括深度神经网络必不可少的组成部分。要实现反向传播机制并不太容易,不过深度学习库都已经隐式实现了后向传播机制,只要我们将误差放入其中,就可自动完成误差的后向传播。
最后,当然是权值更新了,上一步只是将误差传递过来,告诉你偏了多少,要真正弹道得到修正,还需要通过调整权值来完成。当所有神经元的权值都完成了调整更新,一轮训练也就结束了。
听起来很简单,但权值更新里面也是别有洞天。你就这么想:现在你手上已经拿到了“旧权值”和“当前误差”,你怎么决定“新权值”该是多少呢?最简单最容易想到的做法,是直接相减,用“旧权值”直接减去“误差”。这当然能到结果。但后来,有人觉得“直接相减”太粗暴了,缺乏弹性,就加了个学习率,先用学习率和误差相乘,然后再相减。通过调整学习率,能控制这一轮权值更新的幅度。
那现在更常用的做法是什么呢?直接用优化器,我们训练模型的目标,前面已经说了,就是让损失函数最小化,那有没有一种数学工具能到达这样的效果呢?有,就是梯度下降法,用来求极值效果特别好,唯一的问题,就是实现比较复杂。不过,你肯定已经猜到了,这么好用的优化器,深度学习库里肯定已经内置了,不但有经典的随机梯度下降,现在主流的优化器,譬如 Adam,库里都有现成的,只要按照语法直接使用就好。
好了,抡完上面三把板斧,一套由你定制的深度学习模型也就闪亮登场了,当然,深度学习远不止这三道工序,譬如说模型效果调优,不但有传统的各种正则,还有Dropout和Early Stopping等新潮玩法,这里我推荐一本书,《深度学习:基于案例理解深度神经网络》,讲的是用Tensorflow搭建深度学习模型,包括介绍Tensorflow在上述三步中的一些具体用法。想从实践角度了解深度学习的同学,相信读完这本书会有收获。这本书的姊妹篇——《深度学习进阶:卷积神经网络和对象检测》也刚刚出版,非常适合深度学习从业者掌握更高级的技术。
作者简介:
莫凡,娱乐向机器学习解说选手,《机器学习算法的数学解析与Python实现》作者,前沿技术发展观潮者,擅长高冷技术的“白菜化”解说,微信公众号“睡前机器学习”,个人知乎号“木羊”。
《机器学习算法的数学解析与Python实现》
作者:莫凡
ISBN:978-7-111-64260-2
卖点:
生动——语言生动幽默,通过分析大量生活案例,帮助读者理解机器学习的算法。
简单——让很多听起来高大上的名词更实用。
实用——精选了最主要的机器学习算法,如线性回归算法、Logistic回归算法、KNN算法、朴素贝叶斯算法、决策树算法、支持向量机算法、K-means聚类算法、神经网络、集成学习方法等。
系统——从概念、原理、Python实现、应用场景几个方面,详细剖析机器学习中主要的算法。
推荐语:
有趣、易懂、不枯燥,看得懂、学得会的机器学习入门书。全书用白话讲解,帮你从生活案例中理解算法,发现算法的乐趣,再把算法应用到机器学习中,让你零基础掌握算法精髓,快速进入人工智能开发领域。
《深度学习:基于案例理解深度神经网络》
作者:[瑞士] 翁贝托·米凯卢奇(Umberto Michelucci)
译者:陶阳 邓红平
ISBN:978-7-111-63710-3
卖点:
完善的知识体系,适合各层次学生及从业人员。
1)包含正则化、学习率衰减技术和不同的优化器的完整概述及示例;
2)介绍Dropout和超参数调优等高级技术;
3)包含构建卷积神经网络和递归神经网络模块的概述;
4)额外含有优化Python代码的技巧。
推荐语:
基于实例,手把手教你理解并使用Python和TensorFlow构建自己的深度神经网络,并传授实践中会用到的一些高级技术。
《深度学习进阶:卷积神经网络和对象检测》
作者:[瑞士] 翁贝托·米凯卢奇(Umberto Michelucci)
译者:陶阳 李亚楠
ISBN:978-7-111-66092-7
卖点:
1)包含CNN在内的高阶深度学习技术的广泛示例;
2)所有高阶技术的应用示例均使用真实的数据集;
3)本书为《深度学习:基于案例理解神经网络》的姊妹篇,指导你从简单的例子到更高级的技术,一步步提升难度直至熟悉高级方法;
推荐语:
为深度学习进阶读者提供完善的知识体系,包含基于Keras和TensorFlow的YOLO算法完整实现。
第019期赠书活动中奖名单公布
赠书规则
送书规则:感谢大家对华章图书的信任与支持。以上3本好书你最想要哪本?围绕深度学习,留言谈谈你的想法。小编会随机挑取2条最用心的留言,分别包邮送出1本正版书籍(以上2本任选)。
截止日期:9月11日下午17:00
特别注意:请按规则留言。阅读最多、分享最多者优先。
书讯 |9月书讯(下)| 开学季,读新书书讯 |9月书讯(上)| 开学季,读新书
上新 | 一本书带你吃透Nginx应用与运维
书单 | 开学季——计算机专业学生必读的10本畅销经典干货 | 巨详细!使用OpenCV和OpenVINO轻松创建深度学习应用收藏 | 开学季——想打好数学基础?这些经典教材你最需要!视频 | 4min视频带你了解阿里B2B电商算法