Deep Learning从0到0.1

以下大部分是根据我自己的学习过程来的,可以算是一种人生经验,也有可能是只适合我的。有好多人问我怎么入门,我自己都没入,所以是不想公开,能不看就不要看了。(陈老师微博转了一下,班门弄斧羞愧难当。小小服务器微卡,请见谅。)

前期准备

  1. 个人认为Linux远远优于Windows(mac 不清楚,貌似也比Windows方便一点),大二之后我没有在Windows上写过跑过代码,不清楚常用的deep learning框架能否顺利在Windows上安装。但我知道在Linux上安装theano就一个命令,GPU cuda 设置也很方便。当然,这是一个安利,可以不吃。
  2. 可以上Google,会用英文搜索。最好少看中文资料,或者粗略看中文资料有个大概印象之后仔细看英文资料。
  3. 基本的优化知识,像梯度下降法,以及随机的梯度下降法(SGD)。另外还有一些加速方法,可以看这篇博文,形象科学。
  4. 基本的机器学习知识,最起码的logistic regression。这个非常重要,可以看作是最最基本的单层神经网络,相当于平房跟金茂的关系。理解里面的sigmoid也很重要,对以后理解为什么要用tanh,relu有帮助。这个最好能自己实现,matlab也行,了解原理就好了。可以使用libsvm的数据集测试分类效果。可以参考coursera上的机器学习不过他的作业貌似封装了优化算法,最好优化算法也自己写。这可能是最艰难无趣的一步,实在不行先跳过。
  5. 一点矩阵知识,感觉知道就行,离真正用到还很远。
  6. 概率知识,只要不搞生成模型啥的如VAE这种就可以先不管。像CNN基本用不到,只要知道softmax是个什么就行了。softmax(敲黑板!)就是多类logistic regression,简单讲就是模型判定输入是属于哪个类的概率。理解了logistic regression就不难了。
  7. 最好能看一本书,能够系统的学习,Ian Goodfellow and Yoshua Bengio and Aaron Courville写的deep learning就不错。

准备这些我觉得需要2周左右,推荐几个框架,边准备边试,看看喜欢哪一个框架。


初步了解

神经网络最初的是多层感知机(MLP),就是多层的Logistic regression,coursera上的机器学习那课里也有讲到。可以跑一下thenao的代码。为什么纯MLP很少用呢?主要因为参数冗余且不符合原理。还有很多其他原因,可以在接触CNN等其他结构的网络之后慢慢理解。当然这个MLP也是很重要的,虽然这里不多谈。

最重要的是尝试,否则就是夸夸其谈不明细节。当然得选择有趣简单的东西玩。deep learning中RBM这类可能有点晦涩而且现在并不流行。我就分别举CNN,RNN,GAN中简单可行的例子。可能现在不知道这些分别是什么,后面慢慢理解。

CNN

CNN的开山鼻祖LeNetAlexNet算是最初级的CNN可以一看,毕竟里面有很多东西都过时了。但它引入的relu,pooling这些精华还一直在,所以务必看一下AlexNet的论文。这篇博文还有一些比较。简单来说,CNN就是下面的架构,很好理解,相比MLP就多了卷积pooling操作。看MLP就出现了,在这里cnn就是在提取特征,而MLP就是在提取的特征上做判别。

simple cnn
From deeplearning.net

知道这些并不有趣,要玩点直观的。我觉得最有趣的肯定是neural style,最近流行的Prisma也基于差不多的原理,如果你都懂原理你就是high level。我们在有限的计算资源下训练一个大型CNN显得非常不划算,但是用别人训练好的CNN做一些有趣的事也算是另辟蹊径来理解什么是CNN。他的paper中介绍的还算清楚。工业界是要让代码跑起来,入门的第一件事就是能跑别人的代码,管他原理不原理。如果不清楚,先跑起来再说,生成一张自己照片的风格图也很值啊,然后再慢慢了解原理。


如果了解了原理,看了源码,可以尝试修改,比如合成两张图片啥的。能做到就算完全了解了neural style的原理了。这算是入门的第二步,修改别人的代码,同时可以学习一个。牛b之后还可以想想能否通过Autoencoder来加快速度。



好像有点跳,不虚慢慢来。当了解CNN工作模式还得靠其他的东西。

还可以看看deep dream,不过看着好像有点恶心。或者看看其他流行的项目。最重要的是阅读源代码,代码是绝对正确的。书本上paper里的都是大概,很少有细节。我没怎么训练过CNN,所以没法给出更多训练时的细节。

RNN

RNN就难多了,理解LSTM花了我很久。下面两个系列帮我了很大的忙。看完绝对能理解RNN,至少知道是RNN个什么,至少知道为什么要用LSTM,GRU这些变种。看不懂可以先看个大概,跑跑代码再说,然后再看,然后再研究代码。我就这么recurrent的入门的。

  1. Recurrent Neural Networks tutorials
  2. Understanding LSTM Networks

然后是搞点有意思的。我觉得对于初学者来说,自动生成Shakespeare风格的文章或者Linux代码算有意思了吧。可以参考这篇博文和这篇paper。Github上有很多代码,如char-rnnblocks-char-rnn。原理非常非常简单,就是根据前一个字符预测下一个字符。如输入一句话”我tm怎么这么diǎo”,输出就是“tm怎么这么diǎo。”,用RNN来拟合这样一个输入输出就行了。就是以下的结构。

from colah.github.io

这篇文章比较n-gram和RNN的结果,可以看出RNN是多么diǎo。简单来说,RNN能捕获前后之间的联系,比如c代码,RNN能生成匹配的括号,而n-gram是做不到的。

这是RNN能做到的最简单的,而且能在自己电脑上轻松跑起来的例子。还有简单的就是曲线拟合,时序分析。如下就是用RNN拟合的,可以自己尝试用RNN来拟合sin(x)



另外还有结合CNN和LSTM生成图片描述音乐合成,很多能玩的例子,而且玩着玩着就懂了。如果没有好奇心,那可能玩了之后还是不懂。反正我玩了之后,就会想:“tmd,怎么做到的?!”,然后就开始学习一个。

GAN

Generative Adversarial Networks算高级一点的内容,也是算简单的很有意思很有前途的一块,看字面意思就知道是生成模型。比其他生成模型VAE,RBM什么的简单多了,而且原理非常简单。总的来说就是一个生成网络,一个判别网络,目标是让生成网络生成判别网络无法区分是生成的还是真实的数据,这是个对抗(adversarial)的训练过程。应用于图片可能会有点问题,因此出了Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks(DCGAN),效果好很多,见github

GAN比较简单,网上没有满意的代码,随便写个mnist的GAN代码,稍微能看到数字。



要玩还是试试DCGAN比较好,毕竟GAN有点不完善。生成数字可能不那么有冲击力,生成人脸够diǎo了吧,详见github。更有冲击力的是结合VAE和GAN的生成网络VAE/GAN

其他

如reinforce learning, deep-Q 还没有接触。以后再谈。


略微高级

我只能说说我熟悉的deep learning的领域。

框架开发

在知道deep learning的基本知识之后就应该回馈社区。参与一些流行的年轻的框架的开发。如mxnetkerasblocks。首先可以锻炼自己阅读代码和写代码的能力,还可以了解实现细节,这对以后实现自己的奇思妙想很有帮助。个人推荐keras,文档完善,社区广泛,同时支持theano和tensorflow。这里的关系是,theano和tensorflow是两种不同类型的砖头,而keras用这两种砖头做成一些通用的部件如墙壁地板对应于deep learning中的如MLP,LSTM网络等。搞deep learning,熟悉一种框架是必须的,可以的话,需要了解其他框架,毕竟要看源码。或者更形象一点,CUDA相当于汇编语言,theano和tensorflow是c语言,keras和blocks这些框架就像Python。

研究方向

deep learning里还有很多可研究的东西。我们不关注性能,毕竟这超出能力范围。我们可以想想deep learning能干嘛。机器翻译diǎo不diǎo,我一头就栽进去了,毫不犹豫,因为这个太tm有意义太tm有意思了。哥以后不用学外语,也能精通八国语言,想想就exciting。不像CNN,机器翻译的性能还没有那么好,始终缺少一点东西,等待开发,可以看看acl的tutorial

生成模型也是非常热门的发展方向。最近出的Pixel Recurrent Neural NetworksDRAW都是很美妙的,可惜没有时间跟进。但了解一下还是可以的。

最后是大牛的最新研究进展,随时可以跟进。


总结

入门实在有点难以定义。我认为能自己写个网络就算入门了,所以要看教程、跑代码、看文档、看代码、改代码反复来。其中跑代码是稍微轻松一点,也能激发兴趣。要尝试简单的,慢慢就会复杂的了,想想现在看的英文文章也是从一个个单词积累的。
所以要尝试啊,别光看光点赞光收藏啊。

最后我们需要帮助:我们正在翻译deep learning这本书,直译版已全部翻完正在校正中,大概2周后公开。希望多多提提意见,帮忙修改修改,目前处于私密状态,在github上。