优化器 LBFGS OWLQN 实现
Optimizer LBFGS OWLQN implementation
我正在寻找有关在 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 用于计算子梯度,这些子梯度被减少以计算梯度。
谢谢
简而言之,Spark 使用 Breeze LBFGS 和 OWLQN 优化算法,并为它们提供了一种在每次迭代时计算成本函数梯度的方法。
例如,Spark 的 LogisticRegression
class 利用 LogisticCostFun
class 扩展了 Breeze 的 DiffFunction
特征。此成本函数 class 实现 calculate
具有签名的抽象方法:
override def calculate(coefficients: BDV[Double]): (Double, BDV[Double])
计算方法使用 LogisticAggregator
class,这是真正完成工作的地方。聚合 class 定义了两个重要的方法:
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 方法定义了一种合并两个独立聚合器的方法。这个 class 被传送到执行器,用于聚合每个数据分区,然后用于将所有分区聚合器组合成一个聚合器。最终聚合器实例保存当前迭代的累积梯度,并用于更新驱动节点上的系数。此过程由 LogisticCostFun
class:
中对 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
class 计算梯度。 LogisticCostFun
只是说向每个分区发送一个 LogisticAggregator
实例,收集梯度更新,然后将它们发送回以在驱动程序上组合。
我正在寻找有关在 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 用于计算子梯度,这些子梯度被减少以计算梯度。
谢谢
简而言之,Spark 使用 Breeze LBFGS 和 OWLQN 优化算法,并为它们提供了一种在每次迭代时计算成本函数梯度的方法。
例如,Spark 的 LogisticRegression
class 利用 LogisticCostFun
class 扩展了 Breeze 的 DiffFunction
特征。此成本函数 class 实现 calculate
具有签名的抽象方法:
override def calculate(coefficients: BDV[Double]): (Double, BDV[Double])
计算方法使用 LogisticAggregator
class,这是真正完成工作的地方。聚合 class 定义了两个重要的方法:
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 方法定义了一种合并两个独立聚合器的方法。这个 class 被传送到执行器,用于聚合每个数据分区,然后用于将所有分区聚合器组合成一个聚合器。最终聚合器实例保存当前迭代的累积梯度,并用于更新驱动节点上的系数。此过程由 LogisticCostFun
class:
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
class 计算梯度。 LogisticCostFun
只是说向每个分区发送一个 LogisticAggregator
实例,收集梯度更新,然后将它们发送回以在驱动程序上组合。