【问题标题】:Optimizer LBFGS OWLQN implementation优化器 LBFGS OWLQN 实现
【发布时间】:2016-08-02 04:38:07
【问题描述】:

我正在寻找有关在 Spark 1.6 ML 库中实现并行 LBFGS 和 OWLQN 算法的文档。

我找到了这个 1.6 的页面:http://spark.apache.org/docs/1.6.1/ml-advanced.html,但没有关于并行化的内容

对于 2.0:http://spark.apache.org/docs/2.0.0/ml-advanced.html 但仍然没有关于并行化

最后,我阅读了代码 [link1]。方法

def train(dataset: DataFrame): LogisticRegressionModel

似乎使用 Breeze 优化了模型,但我找不到调用 spark 函数的位置(map、flatMap、reduce、...)。

在代码 [link2] 中,map 用于计算子梯度,这些子梯度被简化为计算梯度。

谢谢

【问题讨论】:

标签: apache-spark apache-spark-mllib apache-spark-ml


【解决方案1】:

简而言之,Spark 使用 Breeze LBFGS 和 OWLQN 优化算法,并为它们提供了一种在每次迭代中计算成本函数梯度的方法。

例如,Spark 的 LogisticRegression 类利用了扩展 Breeze 的 DiffFunction 特征的 LogisticCostFun 类。这个成本函数类实现了 calculate 抽象方法,它具有签名:

override def calculate(coefficients: BDV[Double]): (Double, BDV[Double])

calculate 方法使用LogisticAggregator 类,这是完成实际工作的地方。聚合类定义了两个重要的方法:

def add(instance: Instance): this.type // the gradient update equation is hard-coded here
def merge(other: LogisticAggregator): this.type // just adds other's gradient to the current gradient

add 方法定义了在添加单个数据点后更新梯度的方法,merge 方法定义了组合两个单独的聚合器的方法。这个类被运送到执行器,用于聚合每个数据分区,然后用于将所有分区聚合器组合成一个聚合器。最终的聚合器实例保存当前迭代的累积梯度,并用于更新驱动节点上的系数。此过程由对LogisticCostFun 类中的treeAggregate 的调用控制:

val logisticAggregator = {
  val seqOp = (c: LogisticAggregator, instance: Instance) => c.add(instance)
  val combOp = (c1: LogisticAggregator, c2: LogisticAggregator) => c1.merge(c2)

  instances.treeAggregate(
    new LogisticAggregator(coeffs, numClasses, fitIntercept, featuresStd, featuresMean)
  )(seqOp, combOp)
}

你可以把它想得更简单一点:Breeze 实现了几种不同的优化方法(例如 LBFGS、OWLQN),并且只需要你告诉优化方法如何计算梯度。 Spark 告诉 Breeze 算法如何通过 LogisticCostFun 类计算梯度。 LogisticCostFun 只是说将LogisticAggregator 实例发送到每个分区,收集梯度更新,然后将它们发送回以在驱动程序上组合。

【讨论】:

  • 非常感谢。这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2012-11-12
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
  • 2013-11-29
  • 2013-10-10
  • 2019-10-31
相关资源
最近更新 更多