2013年8月18日星期日

Deep learning:四十三(用Hessian Free方法训练Deep Network) - tornadomeet

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Deep learning:四十三(用Hessian Free方法训练Deep Network) - tornadomeet  阅读原文»

  目前,深度网络(Deep Nets)权值训练的主流方法还是梯度下降法(结合BP算法),当然在此之前可以用无监督的方法(比如说RBM,Autoencoder)来预训练参数的权值,而梯度下降法应用在深度网络中的一个缺点是权值的迭代变化值会很小,很容易收敛到的局部最优点;另一个缺点是梯度下降法不能很好的处理有病态的曲率(比如Rosenbrock函数)的误差函数。而本文中所介绍的Hessian Free方法(以下简称HF)可以不用预训练网络的权值,效果也还不错,且其适用范围更广(可以用于RNN等网络的学习),同时克服了上面梯度下降法的那2个缺点。HF的主要思想类似于牛顿迭代法,只是并没有显示的去计算误差曲面函数某点的Hessian矩阵H,而是通过某种技巧直接算出H和任意向量v的乘积Hv(该矩阵-向量的乘积形式在后面的优化过程中需要用到),因此叫做”Hessian Free”。本文主要是读完Martens的论文Deep learning via Hessian-free optimization记下的一些笔记(具体内容请参考论文部分)。

  Hessian Free方法其实在多年前就已经被使用,但为什么Martens论文又重提这个方法呢?其实它们的不同在于H矩阵”free”的方式不同,因为隐式计算H的方法可以有很多种,而算法的名字都可以叫做HF,因此不能简单的认为Martens文章中在Deep Learning中的HF方法就是很久以前存在的方法了(如果真是如此,Deep Learning在N年前就火了!),只能说明它们的思想类似。将HF思想应用于DL网络时,需要用到各种技巧,而数学优化本身就是各种技巧、近似的组合。Matrens主要使用2个大思想+5个小技巧(论文给出的大概是5个,但是其code里面还有不少技巧论文中没有提到)来完成DL网络的训练。

  idea 1:利用某种方法计算Hv的值(v任意),比如说常见的对误差导函数用有限差分法来高精度近似计算Hv(见下面公式),这比以前只是用一个对角矩阵近似Hessian矩阵保留下来的信息要多很多。通过计算隐式计算Hv,可以避免直接求H的逆,一是因为H太大,二是H的逆有可能根本不存在。

  

  idea 2:用下面二次项公式来近似得到θ值附近的函数值。且最佳搜索方向p由CG迭代法(该算法简单介绍见前面博文:机器学习&数据挖掘笔记_12(对Conjugate Gradient 优化的简单理解))求得。

  

  技巧1:计算Hv时并不是直接用有限差分法,而是利用Pearlmutter的R-operator方法(没看懂,但是该方法优点有很多)。

  技巧2:用Gauss-Newton矩阵G来代替Hessian矩阵H,所以最终隐式计算的是Gv.

  技巧3:作者给出了用CG算法(有预条件的CG,即先对参数θ进行了一次线性坐标变换)求解θ搜索方向p时的迭代终止条件,即:

  

  技巧4:在进行处理大数据学习时,用CG算法进行线性搜索时并没有用到所有样本,而是采用的mini-batch,因为从一些mini-batch样本已经可以获得关于曲面的一些有效曲率信息。

  技巧5:用启发式的方法(Levenburg-Marquardt)求得系统的阻尼系数λ,该系数在预条件的CG算法中有用到,预条件矩阵M的计算公式为:

  

  上面的7点需要详细阅读Martens的paper,且结合其paper对应的code来读(code见他的个人主页http://www.cs.toronto.edu/~jmartens/research.html).

  下面来简单看看HF的流程图:

  

  流程图说明的是:定义好系统的目标函数,见本博客中的第2个公式,接着定义一个最大权值更新次数max-epochs,每次循环时首先用BP算法求出目标函数的梯度值,接着用启发式的方法取得λ值,然后预条件CG方法来优化参数搜索方向p(此过程需要用到Hv形式的求解函数),最后更新参数进入下一轮。

  关于code部分,简单说以下几点:

  运行该程序,迭代到170次,共用了差不多20个小时,程序的输出如下:  

maxiters = 250; miniters = 1
CG steps used:
250, total is: 28170
ch magnitude :
7.7864
Chose iters :
152
rho
= 0.50606
Number of reductions :
0, chosen rate: 1
New lambda:
0.0001043
epoch:
169, Log likelihood: -54.7121, error rate: 0.25552
TEST Log likelihood:
-87.9114, error rate: 3.5457
Error rate difference (test
- train): 3.2901

  code完成的是CURVES数据库的分类,用的是Autoencoder网络,网络的层次结构为:[784 400 200 100 50 25 6 25 50 100 200 400 784]。

  conjgrad_1(): 完成的是预条件的CG优化算法,函数求出了CG所迭代的步数以及优化的结果(搜索方向)。

  computeGV(): 完成的是矩阵Gv的计算,结合了R操作和Gauss-Newton方法。

  computeLL(): 计算样本输出值的log似然以及误差(不同激发函数的输出节点其误差公式各异)。

  nnet_train_2():该函数当然是核心函数了,直接用来训练一个DL网络,里面当少不了要调用conjgrad_1(),computeGV(),computeLL(),另外关于误差曲面函数导数的求法也是用的经典BP算法。

  参考资料:

  Martens, J. (2010). Deep learning via Hessian-free optimization. Proceedings of the 27th International Conference on Machine Learning (ICML-10).

机器学习&数据挖掘笔记_12(对Conjugate Gradient 优化的简单理解)

http://www.cs.toronto.edu/~jmartens/research.html

http://pillowlab.wordpress.com/2013/06/11/lab-meeting-6102013-hessian-free-optimization/


本文链接:http://www.cnblogs.com/tornadomeet/p/3267454.html,转载请注明。

杂谈---LZ的编程之路以及十点建议 - 左潇龙  阅读原文»

LZ本人是09年毕业的,在某二流本科院校学的非计算机专业,在兴趣的驱使之下,最终毅然决然的走上了编程这一条“不归路”。

说起LZ的经历虽不算是跌宕起伏,但也真正算是人生无常。

当初09年7月回到家里,由于LZ学习的数学专业,除了考教师之外几乎没有合适的工作可选,而LZ当时玩心未退,没有立即寻找工作,而是先去驾校考了个至今没用过的驾照(LZ驾龄四年,几乎没开过车,你敢信吗)。

考驾照只是找个事干,LZ还是十分不耻的当起了啃老族,每天在家闭门不出,沉浸在游戏的世界中。这件事一直持续了半年多,尽管这半年多吃穿不愁,但其实LZ压力可是前所未有的山大。不管是亲戚,朋友,同学等等,所有人见你面第一句话指定是,“在哪工作呢?”。 

说起来惭愧,LZ自小学习也算是佼佼者,虽说现在说起来那时候的任何荣誉都是浮云,但毕竟在家人和亲戚们的眼中,还是寄予了很大希望的。虽说最终还是只考了个二流院校,但21岁就大学毕业的战绩也算是颇为不凡了,结果最终还是落得一个在家待业的结局。

半年后,LZ不甘寂寞,毅然决然的跑到了一家工地,当起了工人。那段时间,可谓是尝尽了苦头,由于是夏天,工地上虫子特别多,每天晚上都是和一堆小家伙们一起睡觉,甚至有时候你正睡着呢,一个不明物体就能从你脸上爬过。当时工地是包吃包住,一个月给LZ1000块工钱,LZ每天的工作大多就是顶着火热的太阳,搬着仪器陪着各种工程师们,到工地上的各个地方测量与检测。

如此坚持了四个月,LZ最终还是忍受不了了,不仅仅是身体上的折磨,最重要的是学了十几二十年,竟然最终沦落到这步田地,每天上班的感觉就像是在混日子一般,实在让LZ无法接受。

回到家中,经过一番商量,LZ还是无奈之下,决定尝试一下子承父业。由于父母都是做的农业相关的生意,LZ就跑到一家农药生产公司,去的时候说是要做销售的,也可以积攒销路,以便以后接手家里的生意。可是谁能料到,LZ刚到了公司,就被派到厂里再次当起了工人。LZ的待遇与在工地上一模一样,包吃包住,一个月1000块,而LZ每天的工作就是在生产间里,包装一包又一包的农药,从早上七点到晚上六点,有时候如果客户急着要货,干到晚上九点多也是常有的事。工作的时候,经常会有原材料运送到厂里,LZ还要帮着卸货,那些原材料估计每一袋都有200斤左右。

当时天已经变冷了,接近冬天,而厂里也没有热水,每天洗手洗脸都是冰冷的凉水,再加上每天呆在充满农药味的车间里,LZ自我感觉身体一下子差了许多。如此坚持到过年,LZ还是决定不去了,原因也很简单,身体吃不消是一个原因,最重要的还是因为感觉每天都在混日子,学不到任何东西。

由于两次工作碰壁,LZ也只能放手一搏了,打算去追寻自己的梦想。自从LZ进入大学,一直到毕业以后,LZ从来没有忘记一件事,那就是LZ的编程梦。LZ中间也找过几次相关的工作,但是苦于不是计算机毕业,都被面试的人带着略微鄙视的目光给干掉了。LZ也越来越意识到,要想真正的进入这个行业,必须有点真才实料才行。

其实LZ一直对培训机构是抱着怀疑的态度的,觉得承诺的那些东西都太虚,而且价格也十分昂贵。但是没办法,要想进入这个门槛,就必须掌握点东西才行,而且当时母亲大人说,他有一个朋友以前是在我们县某学校当老师,后来去了培训机构,结果现在工资一个月都七八千呢。LZ听完,当时的第一反应就是,“怎么可能?”。

各位仔细想想其实可以理解,LZ当时就是井底之蛙,唯一两份工作,每天累的要死不说,一个月才1000块。而现在突然有人告诉你,进一下那传说中不可信的培训机构,出来就能这么多钱,而这个人还是你的亲生母亲,不由得你不信。LZ当时的震惊可想而知,也对自己的编程之路更加的有信心了。

说干就干,事已至此,LZ已无路可选。11年过完年没多少天,LZ就与LZ的母亲大人踏上了前往魔都的旅程。当时走的那条高速刚开不久,整个高速就我们一辆车,而我们从家到北京大约需要六个小时,中途为了让母亲大人休息一下,LZ第一次开车就踏上了高速。其实也就是路上没车LZ才敢开,不过第一次LZ开车就挂着150码的速度,朝着梦想之都疾驰而去。

到了魔都之后,母亲大人就把我扔给了那个传说中的原某学校老师,自己去办自己的事去了。之后LZ顺利的进入了一家培训机构,而母亲大人也在办完公事之后,在三天后踏上归途。当时LZ就下定决心,为了不辜负母亲大人的信任与支持,也为了LZ自己,这次一定要成功。

之后LZ苦逼的学习之路就开始了。说起来,报名的时候,学校老师给了LZ两条路,一个是点奶它,一个是加哇,而LZ之前在网络上了解过,加哇可以做游戏,再加之加哇也算如雷贯耳,所以就毫不犹豫的选择了加哇。现在想想,当时是LZ幼稚加无知了啊,指导老师所说的游戏可是手机游戏,LZ所说的可是大型的网络游戏啊。

学习之路持续了半年,LZ敢说,这半年LZ的努力程度,远远超过当年高考时的刻苦。当时LZ住在一个表弟的大学宿舍当中,倒是省了不少钱,由于大学每晚11点熄灯,所以LZ每晚都借助手提的电池,继续学习到晚上12点左右才意犹未尽的睡觉。之所以这么努力,一个是自然是因为兴趣所致,另外一个也是因为巨大的压力,这已经是LZ最后一条路了。如果这一次再失败回家,那LZ就真的废了。

终于,功夫不负有心人,LZ半年的努力终于换来了收获,而且由于有着数学的功底,加之在大学的时候也算接触过C语言,所以LZ学习起来也算颇为顺利。半年后,LZ顺利的进入了一家小型的互联网公司,当上了梦想多年的软件工程师。

虽然只是一家小公司,但是干净的办公环境,自己喜爱的工作,不菲的收入,LZ上班的第一天恨不得给自己两个耳光,看看是不是在做梦。这与之前的工作相比,LZ只能说两个字,“呵呵!”。

不过这与LZ半年以来每天十几个小时的学习是分不开的,经过这次,LZ也越来越相信努力才会有收获这句话。编程工作以来的两年多,除了刚开始天天加班以外,LZ从未间断过学习,各种书籍也看了不少,各种源码也研究了不少,各种博文也写了不少,LZ只有一个目的,就是要把以前失去的时间全部补回来。想到以前毕业后荒废的一年,还有在大学里的四年,LZ肠子都悔青了。

之后LZ的工作之路也算一路平坦,工作一年后LZ跳过一次槽,原因很简单,就是因为感觉小公司的上升空间太少,LZ需要一个平台把自己提升上去,也就是现在LZ所呆的公司,直到现在仍然继续着,至此,LZ的编程之路也算是稳步前进了。

由于之前一年苦逼的工作经历,LZ非常珍惜现在的工作,也非常的喜爱编程,就像之前在设计模式总结一章中说的一样,编程对于LZ来说不仅仅是一份工作,而是LZ的事业。

在这里,LZ给各位打算走上或者已经走在编程之路的猿友们或者学弟们一些建议,其实也算不得是建议,应该算是LZ自己走过的弯路吧。

1、如果你是在大学当中,请一定要努力学习。至于网上经常讨论的,到底是基础知识重要(也就是一些大学课程),还是应用知识重要(注重应用的实际编程技巧,比如框架与API),LZ不参与讨论,但是无论是什么,请一定要努力学习,否则工作之后,学习就只能是挤时间了,很难有大把的时间让你安心去看一本书,或是研究一个问题。

2、培训机构是否可信。其实是好是坏,都取决于自己。说到底,无论是自学还是计算机专业,还是培训机构,差的都只是起跑的那几十米,最终决定谁跑的更远的,是你这几十米之后的速度。

3、尽可能的多学习几种语言,具体的学习哪几种LZ不给出建议,但主要可以按照兴趣和类型去学习,比如脚本语言,汇编语言,高级程序设计语言这些类型,都可以选择一两种学习一下。

4、第一份工作是很重要,但只要大方向不错,所学有所用,其它的其实也不必太过在意。

5、刚毕业不久不要看重工资纯属老板们给的糖衣炮弹,如果第一份工作可以不看重,那么多则两年,少则一年,一定要看重。工资在一定程度上代表着你的重要性,如果公司有两个程序猿,一个3K,一个6K,假设有组长或者项目经理的位置,公司培养的多数情况下都会是6K的那个。

6、技术的学习与众多学科一样,讲究循序渐进,千万不要连static和final的作用都没搞清楚,就抱着一本设计模式大读特读。

7、JAVA当中相对来说开源的项目比较多,挑一两个,深入的研究一下吧。

8、编程语言学哪个更好,LZ的建议是学哪个都好。第一个学习的语言只是引你入门,当技术这条路走到一定程度,语言其实已经变成了工具,而且大多数语言都是通一则通百,可能到了最后,遇到报表相关的,你可以几天搞定perl,遇到高并发相关的,你也可以几天搞定erlang。

9、工作太闲怎么办,对于这种问题,LZ只能说呵呵。太闲还不好,到京东或淘宝拍下十本书,看你还闲吗?

10、最重要的一条,也是听起来最虚的一条,活到老,学到老。

好了,10个建议,都是LZ的亲身体会,不敢说都是对的,请各位自行判断。判断力也是能力的一种,能否领悟到LZ所说的精华,去除糟粕,就看各位各自的本事了。


本文链接:http://www.cnblogs.com/zuoxiaolong/p/life1.html,转载请注明。

阅读更多内容

没有评论:

发表评论