欢迎转载,转载请注明出处,徽沪一郎。

概要

本文就拟牛顿法L-BFGS的由来做一个简要的回顾,然后就其在spark mllib中的实现进行源码走读。

拟牛顿法

数学原理

代码实现

L-BFGS算法中使用到的正则化方法是SquaredL2Updater。

算法实现上使用到了由scalanlp的成员项目breeze库中的BreezeLBFGS函数,mllib中自定义了BreezeLBFGS所需要的DiffFunctions.

runLBFGS函数的源码实现如下

def runLBFGS(
data: RDD[(Double, Vector)],
gradient: Gradient,
updater: Updater,
numCorrections: Int,
convergenceTol: Double,
maxNumIterations: Int,
regParam: Double,
initialWeights: Vector): (Vector, Array[Double]) = { val lossHistory = new ArrayBuffer[Double](maxNumIterations) val numExamples = data.count() val costFun =
new CostFun(data, gradient, updater, regParam, numExamples) val lbfgs = new BreezeLBFGS[BDV[Double]](maxNumIterations, numCorrections, convergenceTol) val states =
lbfgs.iterations(new CachedDiffFunction(costFun), initialWeights.toBreeze.toDenseVector) /**
* NOTE: lossSum and loss is computed using the weights from the previous iteration
* and regVal is the regularization value computed in the previous iteration as well.
*/
var state = states.next()
while(states.hasNext) {
lossHistory.append(state.value)
state = states.next()
}
lossHistory.append(state.value)
val weights = Vectors.fromBreeze(state.x) logInfo("LBFGS.runLBFGS finished. Last 10 losses %s".format(
lossHistory.takeRight(10).mkString(", "))) (weights, lossHistory.toArray)
}

costFun函数是算法实现中的重点

private class CostFun(
data: RDD[(Double, Vector)],
gradient: Gradient,
updater: Updater,
regParam: Double,
numExamples: Long) extends DiffFunction[BDV[Double]] { private var i = 0 override def calculate(weights: BDV[Double]) = {
// Have a local copy to avoid the serialization of CostFun object which is not serializable.
val localData = data
val localGradient = gradient val (gradientSum, lossSum) = localData.aggregate((BDV.zeros[Double](weights.size), 0.0))(
seqOp = (c, v) => (c, v) match { case ((grad, loss), (label, features)) =>
val l = localGradient.compute(
features, label, Vectors.fromBreeze(weights), Vectors.fromBreeze(grad))
(grad, loss + l)
},
combOp = (c1, c2) => (c1, c2) match { case ((grad1, loss1), (grad2, loss2)) =>
(grad1 += grad2, loss1 + loss2)
}) /**
* regVal is sum of weight squares if it's L2 updater;
* for other updater, the same logic is followed.
*/
val regVal = updater.compute(
Vectors.fromBreeze(weights),
Vectors.dense(new Array[Double](weights.size)), 0, 1, regParam)._2 val loss = lossSum / numExamples + regVal
/**
* It will return the gradient part of regularization using updater.
*
* Given the input parameters, the updater basically does the following,
*
* w' = w - thisIterStepSize * (gradient + regGradient(w))
* Note that regGradient is function of w
*
* If we set gradient = 0, thisIterStepSize = 1, then
*
* regGradient(w) = w - w'
*
* TODO: We need to clean it up by separating the logic of regularization out
* from updater to regularizer.
*/
// The following gradientTotal is actually the regularization part of gradient.
// Will add the gradientSum computed from the data with weights in the next step.
val gradientTotal = weights - updater.compute(
Vectors.fromBreeze(weights),
Vectors.dense(new Array[Double](weights.size)), 1, 1, regParam)._1.toBreeze // gradientTotal = gradientSum / numExamples + gradientTotal
axpy(1.0 / numExamples, gradientSum, gradientTotal) i += 1 (loss, gradientTotal)
}
} }

Apache Spark源码走读之23 -- Spark MLLib中拟牛顿法L-BFGS的源码实现的更多相关文章

  1. Apache Spark源码走读之16 -- spark repl实现详解

    欢迎转载,转载请注明出处,徽沪一郎. 概要 之所以对spark shell的内部实现产生兴趣全部缘于好奇代码的编译加载过程,scala是需要编译才能执行的语言,但提供的scala repl可以实现代码 ...

  2. Apache Spark源码走读之9 -- Spark源码编译

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本来源码编译没有什么可说的,对于java项目来说,只要会点maven或ant的简单命令,依葫芦画瓢,一下子就ok了.但到了Spark上面,事情似乎不这么简单 ...

  3. Apache Spark源码走读之8 -- Spark on Yarn

    欢迎转载,转载请注明出处,徽沪一郎. 概要 Hadoop2中的Yarn是一个分布式计算资源的管理平台,由于其有极好的模型抽象,非常有可能成为分布式计算资源管理的事实标准.其主要职责将是分布式计算集群的 ...

  4. Apache Spark源码走读之1 -- Spark论文阅读笔记

    欢迎转载,转载请注明出处,徽沪一郎. 楔子 源码阅读是一件非常容易的事,也是一件非常难的事.容易的是代码就在那里,一打开就可以看到.难的是要通过代码明白作者当初为什么要这样设计,设计之初要解决的主要问 ...

  5. twitter storm源码走读之4 -- worker进程中线程的分类及用途

    欢迎转载,转载请注明出版,徽沪一郎. 本文重点分析storm的worker进程在正常启动之后有哪些类型的线程,针对每种类型的线程,剖析其用途及消息的接收与发送流程. 概述 worker进程启动过程中最 ...

  6. Apache Spark源码走读之7 -- Standalone部署方式分析

    欢迎转载,转载请注明出处,徽沪一郎. 楔子 在Spark源码走读系列之2中曾经提到Spark能以Standalone的方式来运行cluster,但没有对Application的提交与具体运行流程做详细 ...

  7. Apache Spark源码走读之13 -- hiveql on spark实现详解

    欢迎转载,转载请注明出处,徽沪一郎 概要 在新近发布的spark 1.0中新加了sql的模块,更为引人注意的是对hive中的hiveql也提供了良好的支持,作为一个源码分析控,了解一下spark是如何 ...

  8. Apache Spark源码走读之22 -- 浅谈mllib中线性回归的算法实现

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文简要描述线性回归算法在Spark MLLib中的具体实现,涉及线性回归算法本身及线性回归并行处理的理论基础,然后对代码实现部分进行走读. 线性回归模型 ...

  9. Apache Spark源码走读之15 -- Standalone部署模式下的容错性分析

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就standalone部署方式下的容错性问题做比较细致的分析,主要回答standalone部署方式下的包含哪些主要节点,当某一类节点出现问题时,系统是如 ...

随机推荐

  1. 20145223《Java程序设计》第6周学习总结

    20145223 <Java程序设计>第6周学习总结 教材学习内容总结 ·Java中将数据从来源取出或是将数据写入目的地,使用输入.输出串流,其分别的代表对象为java.io.InputS ...

  2. wpf,ListBox,ScrollViewer内容向左向右偏移指定位置

    public partial class Example : UserControl { private ScrollViewer myScrollViewer; public Example() { ...

  3. oracle过程中动态语句实现

    oracle过程中动态语句实现 一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DD ...

  4. 疯狂java笔记(七) - Java集合之Map

    Map是以键值对(key-value)的形式来存储数据的.而且Map不允许key的重复,通过Map存储key-value对时,只需要考虑key的存储就可以,key存储后value就会跟着key(完全可 ...

  5. php 从myslql里导出到excel

    //导出excel 只wps可以打开public function takexcelAction(){ $name = $this->input->get_post('name'); $i ...

  6. 解决HttpServletResponse输出的中文乱码问题

    http://blog.csdn.net/simon_1/article/details/9092747 首先,response返回有两种,一种是字节流outputstream,一种是字符流print ...

  7. 【转】移动web页面使用字体的思考

    回想2年前刚开始接触手机项目,接到PSD稿后,发现视觉设计师们喜欢用微软雅黑作为中文字体进行设计,于是我写页面的时候也定义 font-family 为微软雅黑,后来发到线上后,细心的产品经理发现页面的 ...

  8. 20145304 Java第六周学习报告

    20145304<Java程序设计>第六周学习总结 教材学习内容总结 1.InputStream与OutputStream: 在Java中,输入串流的代表对象为java.io.InputS ...

  9. 20145308刘昊阳 《Java程序设计》实验四 Android环境搭建 实验报告

    20145308刘昊阳 <Java程序设计>实验四 Android环境搭建 实验报告 实验名称 Android环境搭建 实验内容 搭建Android环境 运行Android 修改代码,能输 ...

  10. topcoder SRM 623 DIV2 CatAndRat

    解决本题的一个关键点就是当Cat进入时,此时Rat在哪个位置? 注意移动方向可以随时改变,由于是圆环,故离入口最远点的距离是pi*R,即圆的一半, 当cat进入时(cat的速度大于rat的速度,否则不 ...