对于进入机器学习领域的年轻研究人员,你有什么建议?(What advise do you have for young researchers entering the field of Machine Learning?)
他回答到:
Make sure you have a strong training in math and computer science (including the practical part, i.e., programming). Read books and (lots of) papers but that is not enough: you need to develop your intuitions by (a) programming a bunch of learning algorithms yourself, e.g., trying to reproduce existing papers, and (b) by learning to tune hyper-parameters and explore variants (in architecture, objective function, etc.), e.g., by participating in competitions or trying to improve on published results once you have been able to reproduce them. Then, find collaborators with whom you can brainstorm about ideas and share the workload involved in exploring and testing new ideas. Working with an existing group is ideal, of course, or recruit your own students to work on this with you, if you are a faculty.
4. 其实很多模型也有很多种解法。拿LR来说,常见的一阶的Gradient Descent、二阶的BFGS/L-BFGS之外(这些是好多库的默认方法),一阶的Back-tracking Line Search方法、Nesterov’s Line Search等方法,实现起来(特别是分布式实现)比较复杂,让没有自己实现过任何机器学习算法的人来写。。。还是算了吧。。。
回复 ( 10 )
之前的评论广告味太浓了,我重新编辑一下写些干货吧.
我想这个题目我还是比较有发言权的,读书时候曾经把PRML所有算法实现过一遍.这个经历对我的帮助大概有以下几个方面:
1) 对算法细节的理解更加深刻了.书中毕竟不会给出所有细节,而自己实现几乎要重新推倒所有公式,把书中未写出的东西补上.这样对每个算法的所有可能变种及影响了然于心.
2) 可以了解很多看书学不到的关于numerical stability的问题.如保证矩阵的正定型,计算机rounding error的影响,numerical underflow和overflow问题
3) 对整个领域各个算法的关联有更深刻的了解.
虽然自己动手实现算法有好处,但是性价比几何还是个仁者见仁智者见智的问题.我并不认为一定有必要自己实现所有算法.毕竟每个人所能关注的领域还是有限的.懂得算法大致原理,具体用的时候在细研究就可以。把精力更多放在自己研究的领域是更有效率的做法.几年过去后,我在回头看自己的代码也很难看的懂,细节还得看公式。
不能免俗还是广告一下这个工具包
GitHub – PRML/PRMLT: Pattern Recognition and Machine Learning Toolbox
这里面实现了几乎所有在PRML里面描述的算法,并且还有另外一些我觉得比较重要但是PRML没讲的算法。读PRML的同学可以参考一下,代码注释给出了重要部分对应的公式在PRML的出处。变量命名也尽量与书做了统一。希望对学习PRML的同学有所帮助.
我也来学习别人,实名反对最高票答案。
该答案反复提到ML使用者应该先注重应用,而不是理论。但是从回答中多处可以看到回答者对他提到的很多ML知识并不很了解。
1. 该答主认为vectorize(使用线性代数来替代循环达到更高效率)很难。但如果真正从线性代数的角度理解了算法,vectorize只是实现公式而已,没什么难的。作为一个研究生如果连自己学习的算法都觉得难,我只能认为你没学到家,毕竟我身边的本科同学实现了vectorize过的ML(机器学习)算法的就有很多。
(而且我也根本不懂python的循环比vectorization慢,有什么好说python不好的。哪个语言不是这样?
2. 该答主觉得svm(支持向量机)只是max。为什么看不到svm背后如何简化decision problem(决定性问题)到quadratic programming(二次规划),使得运算速度大大提升的idea?为什么看不到svm引入的kernel trick(核函数技巧)多么的精巧方便?如果你只是理解到max的程度,怎么能够明白应用中如何通过kernel来实现不同的decision boundary(决策边界)、如何在svm和别的算法中比较得知哪一种更适合你实际应用的问题?
3. 该答主提到的很多知识都不完全对:hinge loss其实是max(x, 0),是从模糊的decision problem到坚实的、可以通过convex optimization实现的quadratic programming的关键;L1 norm (Lasso)和L2 norm (Ridge)的关键区别还有L1会偏向于产生sparse(稀疏)的解、它们代表了bayesian(贝叶斯)观点中参数的不同的prior。还在答案中宣称“这个小孩都能告诉你正确答案”,“都很简单”。如果你真正完全明白,那你这么说我无可反驳,还会认为你很厉害、眼界远大。但是这样半瓶子晃荡就让我觉得很浮躁了。
这些都不懂,就大谈运用,我不觉得会能很好的使用这些算法。ML算法成百上千,每一种都有不同的优劣,每个本身都又经常有几个参数可以调节,几个kernel可以选择。我真的不明白该答主这样对基础的ML算法知识都理解不深的人,在日常研究中是怎么运用、怎么选择算法的、怎么设置不同参数的?
如果你真的是一个合格的研究生,那么你至少要很了解你所运用的东西的优劣。
最后补充一下我个人对这个问题的想法:我并不认为每个使用者都应该去实现一遍算法。如果不是工作/研究使用,只是平时想试试玩玩做些个人小project的,那么直接了解一些算法的idea、用用library挺好的;但是正经用此做研究的学生,请至少深入弄明白算法的特性,而不是凭感觉开口。
edit: 补充最后一段。
我的观点是在开始学习的初期,有必要把经典算法的最基本版都实现一遍。当对经典算法有信心以后,就不需要用这种方式练习了。这就像做数学一样。陶哲轩大神曾在他的博客上发表过一个做数学的三个阶段,概括一下就是:1)只有intuition没有rigorous proof;2)学会了rigorous proof,看到一个mathematical statement就会思考怎么证明;3)回归intuition,但有信心假如别人要一个rigorous proof,自己也能做出来。自己动手实现代码(包括证明convergence之类的相关属性)并仔细观察自己的implementation的表现很重要,这是从第一阶段过渡到第二阶段的必经之路。但想要头脑开阔的做研究,还要从第二阶段跳到第三阶段,这靠的是大量读文献和与比自己强的人讨论,还有在某个小问题上做很多的实验。
最后我粗略列一些我刚开始学习ML时自己实践过的经典算法(全部用MATLAB),大概是:linear regression, regression with gradient descent (logistic, hinge, L1/L2 regularized etc.), SVM, KNN (还有 ball tree等加速算法), GMM, decision tree & random forest (这个或许用python更简单), adaboost, gaussian process & bayesian optimization, feedforward NN, CNN, LSTM。很多经典我还没有涉及到,但做完这些我当时就已经差不多有信心可以开始做研究了。
更新一段话,Quora上对于Yoshua Bengio的最新访谈,关于一个问题:
对于进入机器学习领域的年轻研究人员,你有什么建议?(What advise do you have for young researchers entering the field of Machine Learning?)
他回答到:
Make sure you have a strong training in math and computer science (including the practical part, i.e., programming). Read books and (lots of) papers but that is not enough: you need to develop your intuitions by (a) programming a bunch of learning algorithms yourself, e.g., trying to reproduce existing papers, and (b) by learning to tune hyper-parameters and explore variants (in architecture, objective function, etc.), e.g., by participating in competitions or trying to improve on published results once you have been able to reproduce them. Then, find collaborators with whom you can brainstorm about ideas and share the workload involved in exploring and testing new ideas. Working with an existing group is ideal, of course, or recruit your own students to work on this with you, if you are a faculty.
—————————————原答案——————————————-
实现很有必要,甚至一定要。都实现一遍倒是不必。
1. 在掌握基本的算法流程、加深对算法的理解之外,实现机器学习算法能够帮助我们建立起一种直觉:数据–模型之间的关系。这一点可能有点玄学的味道…稍微往黑了点说,就是调参的直觉、模型选择的直觉、特征选择/设计的直觉等…经验有的时候是事半功倍的效果。
2. 在实际应用场景中,其实经常会遇到需要实现一些特殊设计的算法。比如要实现某篇paper中的算法/或者自己跑实验,一般情况下这些算法并不是(甚至肯定不是)通用算法包提供的算法,一定要自己实现。这样的时候,如果以前有实现过基础的算法的经验,会有很大帮助。
3. 实现基本的算法,帮助掌握算法流程。这样会更容易应对新的编程框架。
4. 其实很多模型也有很多种解法。拿LR来说,常见的一阶的Gradient Descent、二阶的BFGS/L-BFGS之外(这些是好多库的默认方法),一阶的Back-tracking Line Search方法、Nesterov’s Line Search等方法,实现起来(特别是分布式实现)比较复杂,让没有自己实现过任何机器学习算法的人来写。。。还是算了吧。。。
5. 算法的细节:优化、高效计算等(矩阵乘法的加速等)在实际工作中是蛮重要的。因为机器学习在大规模数据下最大的挑战就是如何『算』得更快:收敛速度/计算时间、计算资源/机器开销等。所以得要知道在哪里有优化的空间才行。
6. 但是全部实现一遍确实没必要,不过常用的算法的基本版还是要尽量都写一写的。
。。。
其实第一条是最重要的。。。
说了这么多有没有觉得不写一遍简直有罪?
*随时修正答案,欢迎指出任何不足的地方!
自己实现是很有必要的。
在学校的时候写过给工科生开设的《优化方法》编程作业,线性规划、牛顿法、拉格朗日乘子法等;Coursera《机器学习》课程每周都有编程作业,课程得分100+(最后的考试做了附加题);
刚读研究生那会,几乎看篇文章就会去看作者是否release代码,有的话就跑跑;没有的话就实现以下,low-rank/sparse方面的论文大都是矩阵范数的目标函数,论文给出每一步的迭代公式,matlab写起来很方便。
写过一些之后,心中不慌。
工作之后,差不多平均读20篇实现一篇。
实现一定数量之后,再战不需要长时间的心里建设,想干就干。
有这时间不如刷概率,numerical linear algebra和leetcode…
看我的实现. 有不足的地方欢迎指教.
目前除了SAMME之外,其他的所有的都能用pass test(SAMME 实现的离散情况还有bug,连续的一般没问题)
说明一下实现的目的。很简单,机器学习不仅仅是公式推导。更不是别人说的调调参数就行了。
会对这个rep负责,关于实现细节都欢迎讨论。
下面是某个算法在训练过程中随着迭代次数的增加,训练样本预测准确率随迭代次数的关系图.
jasonleaster/Machine_Learning · GitHub
哈哈哈哈,我觉得很多人都有这个疑问吧。机器学习好高大上,多么牛逼的东西,光是看公式就已经眼花缭乱了,总觉得自己该全部去实现一遍,有的时候太懒,有的时候觉得能力不够。道理虽然明白——任何事情自己亲手做一做还是更好的,但机器学习已经有了大量的库了,SVM-Light,R里面的glm()方程,自己实现一遍,最后又不敢用(因为不知道算法究竟是否正确),或者不能用(一是速度赶不上大神写的库那么快,二是精度没有专业库那么高),耗时耗力的写了一堆后究竟有什么用?
这里很多答案都提供了一些解释,但我想从另一个角度来聊聊这个问题。
我在1年半前(本科阶段)就开始接触计算心理学和机器学习方面的研究,在NAACL(自然语言处理排名第三的论坛)上发表了一篇文章,用的计算机教授写的算法库,跑的是经过AdaGrad优化的向量支持机(SVM)算法。在这种论坛发文章,你是必须去做海报展示的,站在自己的大幅海报面前傻傻的待4个小时,我的两位教授(一位是认知语言学教授,一位是计算机教授)都在那里。我的位置不太好,在最边缘的角落里,本来以为就可以赢得一份清净,Philip Resnik走了过来。直到那一刹那之前,我一直不知道他是谁。但经过教授介绍后,他是马里兰大学的机器学习和自然语言处理教授,在这个领域混了多年,在Google Schoar上的论文引用数高达12,853。
他走过来的第一句话是:“假设我一点也不懂数学,告诉我你这篇论文做的是什么。”我解释后,看到我的计算机教授走了过来和Resnik聊天,Resnik问我的教授:“你用的是不是hinge loss(辛基损失函数)?”我的教授说:“是。但不是全局优化,所以我没有叫这玩意SVM……”(我凭回忆打出来的,可能不完全精确)。当时我站在一旁觉得这他们能这样大聊特聊数学,甚至是向量支持机(我当时认为这是最厉害的算法——除神经网络以外),简直是太厉害了,我一点也听不懂他们在讲什么。
直到现在,我才明白所谓的“辛基损失函数(Hinge loss)”其实就是Max(a,b)函数,就是比较 a 和 b 谁大谁小,然后选大的那个。这玩意究竟有什么难理解的?为什么要那么高大上?你让一个五岁的小孩,问他:“有一堆红球,一堆绿球,哪一堆的球更多啊?”这个小孩都能告诉你正确答案。
当然这说的有点偏题了。后来我非常幸运的考上了研究生,才终于开始了对“高档”算法的学习。第一个学期被Christopher Manning(克里斯多夫·曼宁)的CS224N自然语言处理虐了一番,这个学期开始上Andrej Karpathy(安杰·卡帕西)的神经网络(CS231N),该君是李菲菲教授(音译,Fei-Fei Li)的爱徒,在推特上有14.9K关注者,我越看他那张方块脸,越觉得他长得像贾斯丁·汀布莱克(Justin Timberlake)。这里有篇他的新闻报道:Karpathy打败了Google的超级人工智能,但也许再没有下次了
我其实也是自控能力很差的人,在上安杰·卡帕西的课之前,也从没有萌生过自己去写机器学习算法的想法。原因在文章开头有提过:1. 我的代码运行速度肯定赶不上经过多次迭代的专业库的运行速度;2. 我咋知道我的代码写的就是对的呢??
我直到现在都这样认为:不考虑对方的环境和条件,知识与技能,就一味要求对方把机器学习算法都实现一遍,估计是最无理取闹的行为了吧。前天晚上,我跟另一个研究生Jason Freeman(杰森·弗里曼)聊天,他在微软的西雅图总部工作了4年,在目前越来越有名的TypeScript团队工作了3年(TypeScript是静态的JavaScript语言,正在国内和国外开始流行)——他告诉我他和安德斯·海尔斯伯格(Anders Hejlsberg)一起工作,他还经常顶撞安德斯。我的第一反应是:“他是谁……”(安德斯·海尔斯伯格是Delphi和C#之父,但我不熟悉这两门语言,所以不会崇拜他——小广告:Scala是我目前最喜欢的语言)。
我和杰森讨论的是3月份开始究竟要不要选吴恩达(Andrew Ng)的机器学习课(CS229)。我持的立场是我可能不打算上那门课,因为我已经看过大部分他的视频了,还读了他讲义的一部分(这里是讲义链接: CS 229: Machine Learning (Course handouts) )。因为我已经确定以后要做神经网络方面的研究,所以觉得他课上的一些其他内容比如特征降维(PCA),对我而言用处不大,我只需要会用就行了。我不仅用过特征降维,还用过更好的降维可视化(tSNE算法)。这玩意和我的领域不搭,为什么我要浪费时间去学?
杰森的论点是,如果我学了它们的理论(甚至把它们实现一遍),就能更好的应用它们。我说:你把直觉(intuition)当什么了?在我看来,对算法进行“直观”上的了解,就已经很足够了。什么是向量支持机?就是拿一个平面去分隔一堆点。更术语一点的解释不外乎是拿一个超平面(Hyperplane)在高维空间里去分割。什么是特征降维?就是看如何把高维度的点阵降到两三个维度。什么是alpha值?就是看这个算法学得有多快。什么是正则化(regularization)?就是别让你的算法过度拟合数据(当然L1,L2等等都有区别,但这些区别都很简单,L1让你关注某个值,L2让你利用所有的值)。
为什么我谈这么多关于理论的问题?在我看来,学习机器学习的算法的进度是这样的:应用 -》理论 -》实现。就跟教小孩折射一样,你先让他看看筷子在水中如何弯折(应用),再告诉他光的折射原因(理论),再让他自己用其他物体来试试(实现)。实现,是这个漫长学习过程的最后一步。一开始就来谈实现,实在是很神奇的事情。
让我准确论述一下我的观点:如果你是学界精英,那么去学习那些你将要使用的算法的理论,最后再自己尝试着实现他们,是很有必要的,除非你是只做应用(比如社会科学,心理学,商学等等)。如果是普通的程序员/工程师,不需要强迫自己去实现这些算法。没人会给你一个小奖章,大公司招这类员工的时候,也是更看重学历,而不是看“哦,我把‘所有’的机器学习算法都实现了一遍”。
最后送上一点我觉得实现机器学习算法最好的路径:
最好用Python和Numpy库。这两样宝具会让你非常轻松。安杰·卡帕西(Andrej)推荐用ipython notebook(现在改名叫Jupyter了),来可视化数据,以及实验算法。昨天有一个下午茶会,我们系举办的,也邀请了安杰,我跑去凑热闹,跟安杰谈到了这个问题,他说就算是大公司做研究,也是这种路径,先从ipython notebook开始(这点让我很惊讶)。
机器学习算法最难的部分其实不是写出来,而是高效率的实现,让你的算法跑快一点。其中一个技巧叫做“矢量化”(Vectorization)。矢量化就是说,能做矩阵操作就矩阵操作,最好连一个外循环都不写。
这是我写的Softmax算法的测评:(在500个样本上跑的)
机器学习的背后是很多数学推演和证明,很多工科生说只需要会用库,能做事就行,但这对于数据科学来说显然不够,当然其实如果把算法背后的数学都弄清楚,理解了,其实这些算法实现起来并不困难,而盲目的记住某些代码,不但于理解无益反而有碍思维。
当然并不是说算法实现不重要。
我个人觉得需要看能力!
经典的算法,比如LR,SVM,贝叶斯,k-means等是很有必要自己实现一遍的,也不会以太难!对于加强模型理解是最直接的路径,以后即使调包调参数也会有很不错的直觉!
但是类似于神经网络或者deep learning这样的复杂模型,恕在下愚笨,即使原理公式我看懂了,代码我也写不出来! 我的智商仅仅到此为止~
况且很多复杂模型我写出来的东西和大牛写出来的框架,在效率和准确性上简直就是两回事~