转-关于初学deep learning还没被说烂的那些事

就算你不是在互联网科技相关领域学习工作,这两年也时不时就会接触到DL相关的消息,诸如某家公司又花了多少钱收购某DL创业公司,某学术大牛又加入了哪家公司,或者这项技术又要颠覆人们的生活balabala。其实由于目前DL相关技术在各家公司投入实际应用,你已经实际是这项技术的受益者了,更不要说像Prisma这样直接把Neural Style放在手机上的APP了。

如果你是科技行业相关或者技术人员,那么你应该都快听吐了吧。Andrew的ppt里这张配图,在他自己的报告就不知道看到多少次,其他各种渠道看到能不下50次了:

转-关于初学deep learning还没被说烂的那些事

大一点的公司都弄了一个自己的deep learning的框架证明自己的实力,小的公司都宣传使用了deep learning达成了怎样的功能。每年都有无数的和DL相关的paper,数量庞大且良莠不齐。每每在各种论坛和群里也经常看到鲁莽的人儿对这个问题的看法:”不就是堆个网络,给多点数据就行了嘛。效果不好就加几层加多点数据”,然后看到其他人扎实的工作就变成:“WC,大神啊”,他们最热衷和关心的事情似乎不是学术技术本身,而是去戏说和神化部分人和事。

收起按捺不住的吐槽心,那么除开听了1000遍的CNN入门和21分钟搞懂深度学习,还有什么事情是你在其他文章里没见过的呢?希望本文能为严肃的初学者提供一些其他地方没有覆盖全但是小编又觉得比较重要的信息。

系统的选择
转-关于初学deep learning还没被说烂的那些事

当然是Linux。每每看到群里入门的小朋友们总是为了caffe配置几个库上串下跳,嚷着大神问遍全群的镜头,都让人心烦不已。就算现在微软官方都发布了windows下的caffe,最主流的平台依然是Linux。我们列几点原因:

◆我们通常都不会孤立的使用一种工具,考虑到如今DL日新月异的发展,我们往往需要研究或者使用别人发布的模型和代码,而其他人发布的代码通常都是基于Linux的(用个时髦的词,这也生态圈啊)。这种时候尽快再现模型的效果才是第一位的,把时间花在port代码到windows上面多可惜。

◆对大部分的工具来说,在Linux上都是优先更新的。比如Mxnet吧,cudnn v5在linux上是已经可以用了的,windows还不行。caffe又有了个新layer吧,但是微软的版本可没更新那么快,你得自己手动去merge,诸如此类。

◆使用方便。不得不说大量文件操作的时候,GUN命令结合管道符处理起来非常轻松,而做DL时候很多情况都在倒腾数据。安装时解决各种依赖只需要命令行轻轻一敲搞定,毕竟每个发行版都有自己的包管理器,其实很多GNU工具都是这么玩的。windows呢?先去找对应软件的官网,然后要么下载源代码自己编译,要么下载预编译的版本,那么这又取决于你是32位还是64位系统,你的vs版本是10,12还是15……何况开机损失30%内存。

◆就不把平时系统选择时大家争论的时候其他linux的优点列举在这里了(虽然那有优点也是很重要滴),这些仅仅是要实际做一些DL实验时会遇到的问题。当然很多问题你花上半天也都是能解决或者找到合适的替代品,但是那些时间还不如拿来熟悉Linux一劳永逸,这样的投入绝对是划算的。另外关于各种符合找不到或者链接库路径设置的事情也不要在社区麻烦大家了,自己google或者好好补习基础。

框架的选择

转-关于初学deep learning还没被说烂的那些事

如果把所有的DL框架列出来,这会是个长长的名单,网上也有很多关于不同框架的详尽对比。可是初学者面临如此多的选择的时候也还是犹豫不决,那么到底怎样选择才是比较合适呢?

◆如果你现有的团队很多工作已经是基于该框架,尤其是很多实验室还有一些祖传的代码,那么接着使用和发展也许是最合适的。这种情况也包括:你感兴趣的工作是使用该种框架开源,或者小组有其他的考虑不得不使用某种框架,又或者你青睐或者反感某种编程语言,总之这些都是外部的一些因素。

◆接下去我作为mxnet的脑残粉,要向大家隆重安利一下mxnet了。现代的框架设计,超省内存,多机多卡以及快速的发展都是我们选择它的理由。主要的开发人员很良心地把很多设计思路都贴出来(还有中文版),配合代码顺便还可以学习代码。提供了各种语言的借口(python、c++、R、Julia、Go……)和各种花式例子,并且现在已经可以非常方便的使用torch和caffe的接口。example里面增加的非常快,建议大家有时间可以多看看,而且很多地方其实是展示了mxnet好hack的特点。

例如fast r-cnn的例子,你就算不做检测也可以看看怎么构建自己的数据迭代器,multi-task和数据并行,LSTM的例子可以知道怎么共享内存等等。好多在文档里看起来不是很明白的东西,有了例子的示例会理解的更加透彻。实在不行,出门右转可以在社区上抓到8001号首席客服刘老师(微博:phunter_lau)。希望有能力的同学最后能多多贡献代码或者文档。

◆当然也可以参考cs231n上Justin(lecture 12)的推荐,尤其是当需要大量RNN的时候,也许Theano或者Tensorflow可能会更加方便。 如果你想新加一个layer,可能Torch是最简单的,前提是你已经比较熟悉Lua语言。mxnet在这方面提供了好几种方式,如果需要最大化效率可能要比较熟悉mshadow这个底层库,相比caffe的代码来说,可读性可能差一点(使用了比较多c++的新特性,其实是不错的学习资料哦!)。

学习的姿势

转-关于初学deep learning还没被说烂的那些事

接下来就跑几个模型,走上人生巅峰了?也不太可能。没有machine learning的同学们还是需要补充一些ml的知识的。虽然现在模型框架到处都是自己跑跑很简单,可是实际中总是要处理各种奇奇怪的问题,不知道原理原则就不会变通,也不知道调整的方向。那种“DL不就是堆个模型,数据不够久堆数据,模型不好就加几层”的简单看法,不仅天真,也对这领域里奋战多年的研究者们太不敬了(事实上多数“xx不就是xx”这样的论断,都是在强行安慰自己的浅薄)。

◆真的没有接触过machine learning的同学还得去补充一下知识,说到底DL也还是在这个范畴内,这方面网上的教程资料也非常多。然后再把DL里面经典的论文已经自己最感兴趣具体任务的论文都具体仔细看看。这里不太推荐以看别人博客笔记的方式代替论文原文,这个可以作为一些补充或者帮助,但是一定要看看原文。如果觉得英文不喜欢看或者看不懂,那习惯看懂英文本身比你学习DL可能还重要,强行习惯吧。入门的课程有大家都熟悉的Andrew Ng的公开课,cs231n,cs224d等等,这样的资料很容易找到。总之至少要对ML的基础知识都比较熟悉,否则后续遇到问题一点头绪都没有。毕竟,你总不能连overfitting都没听过就猛加layer吧。

◆经典的论文看过之后要理解它们之前的联系,看似简单的东西也要知道所以然。dropout都知道是随机丢弃一部分的响应,可以防止网络过拟合,但是多少人知道这和ML中的bagging有关系。vgg刚出来的时候大家只看到深,但是其实这种3x3的小filter其实对后面的工作影响更大:两个3x3叠加于一个5x5相比,同等的receptive field但是增加了非线性的表达能力还降低了参数个数抑制了过拟合。inception使用了这个设计,并且把不同大小的filter组合使用,考虑更多多尺度的信息等等,很多设计都是有迹可循和以前的知识能对应上的。但是堆积了太多的layer,优化又成了问题。所以接下去BN的出现克服covariate shift,使得较深的网络得以训练。当然还有一些从其它角度解读BN的工作也很有意思。

所以一部分研究沿着怎么使网络拥有更好的表达能力,一部分工作在研究在网络变得复杂时依然能够训练,当然还有其它研究压缩模型(SqueezeNet),或者加速模型(二值化或者分解网络权重)等等。总之读完论文要善于总结,有一条明晰的线路。

◆沿着大牛们的论文细读。以凯明大神为例:检测框一路过来,其实都是在深挖feature map而不是和分类一样只关注网络的输出。大家把目光放在网络中间的feature map上,发现这个东西已经蕴含了相当多的信息,既可以用来做识别,还可以用来做检测甚至是分割等等。

对于DL来说增加模型的复杂度很简单,所以大量的工作都集中在增加了复杂度之后怎么防治过拟合以及怎么才能有效训练上了,笃定网络增加网络深度一定可以带来提升的念头,先是从初始化参数和**函数入手(prelu+init),后来又从结构上提出了resnet。这些工作之前都已经有人做过类似的实验(xaiver, highway network)。但是从不能用到可用,这之间的距离还是很远的,就不要老想着resnet有150多层,而应该想想为啥这150多层可以训练的好。很多优秀的工作也许最后体现出来的结论很简单,但是这之间的思考也是非常重要滴。

◆社区上的大牛们其实是非常愿意解答大家的问题的。前提是,自己得把问题问好。什么配置框架这种要自己去google搞定,大多社区论坛大家关注的目标还是算法和理论居多。另外类似“我这个模型怎么准确率那么低,你们有遇到过吗”这种无厘头的问法,实在是让人吐槽都懒得吐槽。通常来说,如果你连自己的问题都描述的不清楚的时候,你应该做的是理解自己的模型和问题去。
转-关于初学deep learning还没被说烂的那些事

接下来就愉快的跑模型和慢慢调试自己的网络吧,现实问题都是数据、计算量和算法的综合考虑,自己做一些实验踩踩坑才能学到更多。DL的出现使的人们从特征构建这个最麻烦的地方解脱出来,使的我们能在更高的层面上去研究和解决问题:够好的构建模型(网络结构,问题流程)和描述问题(合适的loss,multitask等等)本身。很多以前觉得复杂的问题现在甚至可以做到end2end的训练,想想这之间的进步真是令人激动。

当然很多地方都是细节决定成败,举个开心的例子,之前有人在回归人脸特征点的时候用了tanh的**函数,而特征点的坐标又没做过归一化,痛苦了很久loss为什么一直非常大,后来才想起tanh的输出都在[-1,1]之间,然而接下去又发现直接除以人脸宽高归一化之后,似乎输出总是个平均脸……所以多动动手,每次善于总结才会让自己成长的更快,也就不会觉得深度学习就是一言不合加layer了。

希望大家在DL的世界里玩的愉快

转载于:http://www.sohu.com/a/112656155_266711