博文

目前显示的是 六月, 2015的博文

java处理大数组真是让人头疼

我在spark中创建了一个长度为10亿,类型为double[]的accumlator。结果,发现函数send不出去,driver无法把这个函数send给worker 15/06/23 04:57:52 ERROR yarn.ApplicationMaster: User class threw exception: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
  at java.util.Arrays.copyOf(Arrays.java:2271)
  at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:113)
  at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
  at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:140)
  at java.io.ObjectOutputStream¥BlockDataOutputStream.drain(ObjectOutputStream.java:1870)
  at java.io.ObjectOutputStream¥BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1779)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1186)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
  at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer…

关于win 10升级的一些....

图片
呃,最近媒体上关于win 10如何免费升级的消息满天飞,我不知道我周围有多少人关心这个,也不知道哪些可以讲哪些不能讲……先放些图吧。这是我在win 8.1上收到的升级通知只有家庭版和专业版才会接到这样的升级通知,企业版不会。它主要有这样两点考虑:企业版有单独的销售策略,企业版并不能免费升级。企业版要想升级到win 10,企业是要因此而花钱的(可能已经以年费的方式掏过了) 企业内不应该允许个人随便升级操作系统。企业应该有自己的版本管理策略,由企业自己决定什么时候升,怎么升。理论来说,只有正版才能升级,盗版不能升级。 因为升级的过程中要连接微软的服务器进行激活。然后高潮来了。360/qq版的win 10是怎么回事。会不会有删不掉的内置应用?
360/qq版的win 10是这两个公司委托微软做的一个特别版。安装文件是微软做的,带有微软的数字签名,装完后里面不会有删不掉的东西。不像Android,定制版总是搞一些卸不掉的应用。盗版能激活吗?
不能。微软并没有提供key给360/qq。安装过程中所连接的激活服务器,依然是微软的服务器。另外,安装360/qq定制版的过程中遇到任何问题,微软不管,由这两家中国公司负责技术支持。所以,在我看来,奇虎和腾讯只是windows的两条推广渠道,而不是销售渠道。win 10并不是完全免费了,它也是有定价的,该卖还是要卖的。对个人用户来说,正版windows的销售渠道只有一个:微软的在线商店。没有代理商、分销商之类的。也没有实物。能买到的就是一个key和一个iso下载链接。一年内免费是说催促大家在一年内赶紧升级。并不是说装了win 10以后还要再掏钱。win 10的一个重大的改变是:会在开始菜单旁边内置cortana。cortana是一个类似于siri/google now的东西。cortana的中文识别做的挺不错的,比siri好。

Spark 1.1中下载jar包时的一个小错误

图片
我在用yarn中跑spark时,总是遇见一个这样的错误:java.io.FileNotFoundException: D:\data\yarnnm\local\usercache\chasun\appcache\application_1434537262045_0033\container_1434537262045_0033_01_000054\netlib-native\_ref-win-x86\_64-1.1-natives.jar (Access is denied)
  at java.io.FileOutputStream.open(Native Method)
  at java.io.FileOutputStream.(FileOutputStream.java:221)
  at org.spark-project.guava.common.io.Files¥FileByteSink.openStream(Files.java:223)
  at org.spark-project.guava.common.io.Files¥FileByteSink.openStream(Files.java:211)
  at org.spark-project.guava.common.io.ByteSource.copyTo(ByteSource.java:203)
  at org.spark-project.guava.common.io.Files.copy(Files.java:436)
  at org.spark-project.guava.common.io.Files.move(Files.java:651)
  at org.apache.spark.util.Utils¥.fetchFile(Utils.scala:437)
  at org.apache.spark.executor.Executor¥¥anonfun¥org¥apache¥spark¥executor¥Executor¥¥updateDependencies¥6.apply(Executor.scala:372)
  at org.apache.spark.executor.Executor¥¥anonfun¥org¥apache¥spark¥…

Rosenbrock Function

图片
Rosenbrock function是最优化课本中经常出现的函数。stanfordnlp的代码中也经常拿它测试各种最优化方法的正确性和性能。Rosenbrock function定义如下:$$ f(x,y)=100(y-x^2)^2+(1-x)^2 $$函数图像如下:它的一阶导数为:$$ \frac {\partial }{\partial y} f (x,y) = -200{x}^{2}+200y $$$$ \frac {\partial }{\partial x}f (x,y) =-400(-{x}^{2}+y)x-2+2x $$它的二阶导数(Hessian Matrix)为:$$ \left[ \begin {array}{cc} 1200{x}^{2}-400y+2 & -400x \\ -400x & 200\end {array} \right] $$当它取极值的时候它的一阶导数等于0。所以由\( \frac {\partial }{\partial y} f (x,y) =0 \) 可得 \( y=x^2 \)。代入\( \frac {\partial }{\partial x} f (x,y) =0 \)的式子中可解得它只有唯一解x=1,y=1。把(1,1)代入Hessian矩阵中得到$$ \left[ \begin {array}{cc} 802&-400 \\ -400&200 \end {array} \right] $$它是正定的。所以f(x,y)在(1,1)这一点取得极小值。等高线图如下:> with(plots); > contourplot(100*(-x^2+y)^2+(1-x)^2, x = -3 .. 3, y = -20 .. 20, contours = 20);当使用牛顿迭代法的时候需要用到Hessian矩阵的逆:> LinearAlgebra:-MatrixInverse( VectorCalculus:-Hessian(100*(-x^2+y)^2+(1-x)^2, [x, y]) );$$ H^{-1} = \left[ \begin {array}{cc} \frac{1}{2(200{x}^{2}-200y+1)}&{\frac {x}{2…

Spark的速度快是以丧失计算结果正确性为代价的

是的,Spark很快。但是它不保证它算出的值是对的,哪怕你要做的只是简单的整数累加。Spark最著名的一篇论文是:《Spark: Cluster Computing with Working Sets》。当你读它的时候你需要明白:文中代码不保证计算结果是正确的。具体来说,它的Logistic Regression的代码在map阶段用到了accumulator。下面解释为什么这么做是错误的。假设有这样一个简单的任务:input file的每一行是100个整数,要求竖着加下来例如:输入1 2 3 4 5 ... 100
1 2 3 4 5 ... 200
1 3 3 4 5 ... 100输出3 7 9 12 15 ... 400很简单,对吧?是个猪都会算。 在hadoop上这个问题可以通过Map reduce来解决。首先把输入文件分成N个大小相等的块。然后每个块输出一行100个整数,如 2 4 6 8 10 ... 200
然后reducer接收每个mapper的输出结果,累加起来得到最终结果。缺点是: 从mapper到reducer是需要DISK-IO及网络传输的。那么需要传输N*100个整数。当输入集的维数很大(每行有上百万个字节)的时候,很浪费。spark很巧妙的引入了accumulator的概念。同一台机器上所有的task的输出,会先在这个机器上进行本地汇总,然后再发给reducer。这样就不再是task数量*维数,而是机器数量*维数。会节省不少。具体来说,在做机器学习的时候,大家很习惯的用accumulator来做这样的计算。accumulator是被很careful设计的。比如,只有master节点能读取accumulator的值,worker节点不能。在“Performance and Scalability of Broadcast in Spark
”一文中,作者写到:“Accumulators can be defined for any type that has an “add” operation and a “zero” value. Due to their “add-only” semantics, they are easy to make fault-tolerant.” 。但真的是这样吗?并不是。accumulator如…

BFGS的笔记

Hessian矩阵:$$ G = \begin{bmatrix} \dfrac{\partial^2 f}{\partial x1^2} & \dfrac{\partial^2 f}{\partial x1,\partial x2} & \cdots & \dfrac{\partial^2 f}{\partial x1,\partial xn} \ \dfrac{\partial^2 f}{\partial x2,\partial x1} & \dfrac{\partial^2 f}{\partial x2^2} & \cdots & \dfrac{\partial^2 f}{\partial x2,\partial xn} \ \vdots & \vdots & \ddots & \vdots \ \dfrac{\partial^2 f}{\partial xn,\partial x1} & \dfrac{\partial^2 f}{\partial xn,\partial x2} & \cdots & \dfrac{\partial^2 f}{\partial x_n^2} \end{bmatrix} $$最优化中的Quasi-Newton method是当f的二阶偏导矩阵Hessian matrix难以求出来的时候,用另一个矩阵B来代替Hessian矩阵。主要有两种方法:SR1和BFGS。这两种方法的主要区别是:SR1产生的是rank 1的矩阵,而BFGS产生的是rank 2的矩阵。SR1的全称是symmetric-rank-one。DFP令\( Bk \) 是Hessian矩阵\( Gk\) 的近似。那么BFP计算\( B_k \)的公式是$$ B{k+1} = (I - \frac{yk sk^T}{yk^T sk}Bk\frac{sk yk^T}{yk^T sk} + \frac{yk yk^T}{yk^T sk})$$它的逆矩阵\( Hk = Bk^{-1} \) 的递推公式是$$ H{k+1} = Hk - \frac{Hk yk yk^T Hk}{yk^T Hk yk} + \frac{sk sk^T}{yk^T s_k}$$BFG…