天天看点

【珍藏】CMU大师对软件工程师的系统建议(附书和论文下载)

问题:你对想要学习机器学习的软件工程师有哪些建议?(what would be your advice to a software engineer who wants to learn machine learning?)

alex smola: 这很大程度上取决于软件工程师的背景及其具体想掌握机器学习的哪部分知识。简而言之,我们以一名拥有四年本科学位和一到两年行业经验的初级程序员为例,并假设这位程序员希望学习计算广告学、自然语言处理、图像分析、社交网络以及搜索和排序。那么,我们先说掌握机器学习有哪些基本要求(致学术界同仁的免责声明:下列内容并不完整,如果未列入你的论著,在此提前致歉)。

线性代数

机器学习以及数据统计和优化都需要这方面知识。这也是为什么gpu(图形处理器)远比cpu(中央处理器)适合进行机器学习。作为程序员,至少需要基本掌握以下内容:

标量、向量、矩阵、张量

把它们看作你可以组建并相互转换的零维、一维、二维、三维和更高维物体,有点像乐高玩具,它们使得基本的数据转换成为可能。

特征向量、范数、矩阵近似、分解

这些概念本质上是让你习惯线性代数的用法。如果你希望分析一个矩阵的情况(比如,检查为何循环神经网络中出现梯度消失,为何增强学习算法中控制器出现分歧(diverge)),你就必须要理解在应用矩阵和向量时可能出现的增长和减小范围是多少。如果你希望代码表现出色和稳定,那么低秩等矩阵近似算法或乔列斯基分解就很有用。

数值线性代数

如果你需要做很多最优化计算,那么这部分知识就很有用。对核方法和深度学习来说如此,对图像模型和采样器而言则不那么重要。

书籍

<a target="_blank">serge lang, linearalgebra</a>

线性代数的基本介绍,适合本科生。

<a target="_blank">bela bolobas,linear analysis</a>

比上面这本难很多,但对想做很多数学和泛函分析的人来说更有用。如果你想攻读博士,这本书或许不错。

<a target="_blank">lloyd trefethen anddavid bau, numerical linear algebra</a>

最优化(和基本演算)

在许多情况下,设置要问的问题是相当容易的,但得出答案却没没那么简单。举例来说,如果要对一些数据进行线性回归(即找到一条线),你可能希望尽量减少与观测值的距离平方的总和。同样,如果想获得一个好的点击率预测模型,你就得最大化对于人们点击广告概率预测的准确性。这意味着我们通常会有一些目标、一些参数和大量数据,而我们需要通过一种方式来解决问题。这一点很重要,尤其因为我们常常不会有一个闭合式解决方案。

凸优化

很多时候,在优化问题不存在许多局部解决方案的情况下是不错的。当问题为凸时就会发生这种情况。(若你能在一个集合内任意两点间画出一条直线且这条直线处于该集合内,则这一集合就是凸的。若你能在图上任意两点间画出一条直线且这条直线位于图形上方,则这一函数是凸的。)

也许这一领域的经典书籍是这本由steven boyd和lieven vandenberghe所撰写的 convex optimization 。本书免费且非常棒。(回复041501下载,共730页)此外,boyd的课程里也有许多很不错的幻灯片集。dimitri bertsekas也已经编写了关于最优化、控制等的宝典。这些应该足以供任何人开始了解这个领域了。

随机梯度下降算法

这一算法早期在很大程度上只是凸优化的一种特殊情况(至少早期定理是这样的),但最近发展很大,并且绝非是由于数据的增多。原因是,想象一下你有一些数据要处理,而你的算法需要将所有的数据都浏览一遍后才能继续新的步骤。而如果我故意给你10份同样的数据,那么你就必须重复10次工作,却没有什么实质性用处。显然,现实情况不会如此糟糕,但如果你需要操作多次小的新步骤,而每个小步骤之后都需要观测,它就能帮上忙。这在机器学习领域带来了相当大的变革型影响。此外,许多关联算法都容易得多。

我们面临的挑战是如何将其并行化。也许这个方向的第一步之一就是我们2009年的 slow learners are fast 论文(回复041502下载)。最新版本是无锁变异型,例如niu等于2013年所著的hogwild论文(回复041503下载)。简而言之,这些算法通过人工计算机计算局部梯度并以异步方式更新共识参数集来运作。

另一个挑战是如何应对控制过度拟合的各种方法,例如通过正则化来实现。对于凸罚函数来说,有一种所谓近端梯度算法。一种比较流行的选择是amir beck和marc teboulle的fista算法。部分代码参见francis bach的spam toolbox(http://spams-devel.gforge.inria.fr/)。

非凸方法

许多机器学习问题都是非凸问题。从本质上来说,任何与深度学习相关的问题都是。但聚类、主题模型和几乎任何潜变量方法和当前几乎所有在机器学习领域有意思的问题也都是。部分加速技术可以提供帮助。例如,我的学生 sashank reddy最近展示了在这种情况下如何获得收敛的良好比率。

有许多被称为谱方法的技术可以使用。 anima anandkumar在她最近的quora session中已经非常详尽地回答了这一问题。请参阅她的回复,因为其回复无比详细(https://www.quora.com/profile/anima-anandkumar-1)。概括地说,凸问题并非唯一能够确切解决的问题。在某些情况下,可以得出一个难题的数学表达式以显示只有某一组特定的参数能找到所有的集群、主题、相关比例、神经元或所有数据中的任何东西。这仅在你有能力且愿意花很多数学的功夫时才有效。

在培训深层网络方面(deep networks),最近有许多新技巧。我会在后面的内容中提及这些,但在某些情况下,目标不仅仅是优化,而是制定出一套具体的解决方案(几乎像是那本题为the journey is the goal《旅程即是目的》的书)。

系统

机器学习正在成为大部分有关于人、测量、传感器和数据的关键要素,这与过去十年标度算法(scaling algorithms)的突破密不可分。jeff dean去年出了六套机器学习教程,也并非偶然。如果有人过了十年与世隔绝的生活,在这里给补充一下,他就是mapreduce、谷歌文件系统、bigtable和其他十多项成就了谷歌的关键技术背后的男人。

说笑归说笑,关于系统的研究为解决分布、异步、容错、可扩展和简易问题提供了宝贵的工具。后者是机器学习研究人员常常忽视的一点。简易是一种特性,不是一个错误。一些基本的技巧将带给你很多:

分布式哈希表

这实质上是如分布式缓存(memcached)、dynamo、 pastry和orceph等方法

构建的基础。它们都解决同一个问题——如何在避免访问之前数据输往的中央储存库的情况下向多台机器发布数据。为了达到这一目的,你需要将地址以一种随机又确定的方式编码(也就是哈希)。此外,你需要解决如果任何一台机器出现故障时谁将负责处理。

这就是我们在参数服务器(parameter server)中使用的数据布局。我的学生李沐是这个项目背后的智囊。工具组合参见dmlc(http://dmlc.ml/)。

一致性和信息传送

所有这一切的教父是leslie lamport的paxos 协议。它解决了在不是所有机器任何时候都可用或有些机器出现故障时如何达成共识的问题(是的,我在这儿就一句带过了)。如果你曾经使用过版本控制,你可能靠直觉知道它是如何工作的——大量机器(或开发者)产生更新(或代码段),而你希望将这些都结合成有意义的信息(例如,你不该两次运用微分),但又不需要所有机器与其他所有机器一直传递着信息。

在系统中,解决方案是使用向量时钟(参见例子:谷歌的chubby)。我们在参数服务器中使用它的一种变体。关键的区别在于(均引自李沐)在参数范围内使用向量时钟。这可以确保不会因为时间标识耗尽内存,就像一个文件系统并不需要为每一个字节都记录一个时间标识。

容错、scaling和云

最简单的自学方法就是在亚马逊aws、谷歌gwc、微软azure, 或你可以找到的各个其他平台上运行算法。当你第一次启动1000个服务器,意识到你正在向一个实际上的合法僵尸网络发送大量指令时,还是很令人激动的。我在谷歌工作时,我们控制了欧洲某处了5000个高端机器,用于主题模型中的推理。我们所调用的能源价值如果和一个核电站相比,也要占很大的比重了。我的经理当时把我叫到一旁,说这真是个昂贵的实验……

或许最容易起步的是学习docker。为了让scaling更容易,人们热火朝天地开发了不少工具。docker machine和docker cloud或许是近来最好的新工具,使你能像更换打印机驱动一样方便地连接不同的云端。

硬件

这似乎显而易见,但如果你了解自己算法所运行的硬件,的确会很有帮助。这会让你知道你写的代码是否已经接近峰值性能。初学者可以阅读jeff dean的numbers every engineer should know一书。我在面试时最喜欢问的问题(曾经)是,应聘者的电脑有多快。知道算法的局限大有裨益:是缓存、内存带宽、延迟时间还是硬盘等等。anandtech上有非常棒的介绍性文章,以及对微处理器架构等相关内容的测评。只要英特尔、arm、amd发布新硬件时,都可以去看一看。

统计学

我特意把这点留到最后。因为每个人都知道这是关键(的确如此),然后就忽略了其他所有东西。统计学确保你能问出好问题,同时帮助你理解自己在数据建模时用了多少估算。

从图像模型、核方法到深度学习等等,很多改进其实来自提出对的问题,也即定义了合理的优化目标,从而进行最优化。

statistics proper

larry wasserman的《统计学完全教程》(all of statistics)是不错的入门教材。另外也可以看一下 david mckay 的 machine learning 一书。该书免费(篇幅很长、内容全面,回复041504下载)。其他还有不少好书,比如说 kevin murphy, chris bishop, trevor hastie, robtibshirani 以及 jerome friedman 的著作the elements of statistical learning:data mining, inference, and prediction。是的,bernhard scholkopf 和我也写了一本learning with kernels。

随机算法和概率统计

本质上就是用计算机科学解决一样的问题,关键区别在于他们是设计算法的一种工具,而非用来适配参数的一个问题。我特别喜欢 michael mitzenmacher 和eli upfal 写的书probability and computing: randomized algorithms and probabilistic analysis ,非常易读但同时谈到了许多深刻的问题。如果你想更深入地了解这些工具,还有 rajeev motwani 和 prabhakar raghavan 的书randomized algorithms,写得很好,不过如果你没有较好的统计学背景,可能较难读懂。

我的回答可能已经够长了,很少有人会一直读到这里。所以我接下来说得比较简短。网上有许多非常棒的视频资料。许多教授现在有自己youtube频道,并上传自己的课程视频。如果你在学习比较复杂的工具,这些视频会有所帮助。我的视频在这里(https://www.youtube.com/user/smolix/playlists),nando de freitas的要好很多。

其他还有一些工具。dmlc是好的起点,其中有许多用于分布式可扩展推理的算法,包括基于mxnet的神经网络。

还有很多没谈到的:编程语言、数据源等等。但这个回答已经太长了,我会在其他问题中继续讨论。

附录,alex smola 著书:

g. bakir, t. hofmann, b. schölkopf, a.j. smola, b. taskar, and s.v.n. vishwanathan, editors. predicting structured data. mit press, cambridge, ma, 2006.

s. mendelson and a. j. smola, editors. machine learning, proceedings of the summer school 2002, australian national university, volume 2600 of lecture notes in computer science. springer, 2003.

b. schölkopf and a. j. smola. learning with kernels. mit press, 2002.

b. schölkopf, c. j. c. burges, and a. j. smola, editors. advances in kernel methods--support vector learning. mit press, cambridge, ma, 1999.

a. j. smola, p. l. bartlett, b. schölkopf, and d. schuurmans, editors. advances in large margin classifiers. mit press, cambridge, ma, 2000.

继续阅读