我是Spark的新手,想知道如果在StreamingLinearAlgorithm上调用trainOn方法,会在集群中的RDD方面发生什么,例如
val regression = new StreamingLinearRegressionWithSGD()
regression.trainOn(someStream)
StreamingLinearRegressionWithSGD包含实际模型(LinearRegressionModel)以及作为受保护成员的学习算法(LinearRegressionWithSGD)。在方法trainOn中,发生以下情况:
data.foreachRDD { (rdd, time) =>
if (!rdd.isEmpty) {
model = Some(algorithm.run(rdd, model.get.weights))
}
根据我的理解,每隔x秒就会对流数据进行分块,并将分块数据放入RDD中。因此,每x秒将学习算法应用于新的RDD。实际的学习魔法发生在GradientDescent的某处,其中RDD数据和先前的模型权重向量是输入,更新的权重向量是输出。
val bcWeights = data.context.broadcast(weights)
// Sample a subset (fraction miniBatchFraction) of the total data
// compute and sum up the subgradients on this subset (this is one map-reduce)
val (gradientSum, lossSum, miniBatchSize) = data.sample(false, miniBatchFraction, 42 + i)
.treeAggregate((BDV.zeros[Double](n), 0.0, 0L))(
seqOp = (c, v) => {
// c: (grad, loss, count), v: (label, features)
val l = gradient.compute(v._2, v._1, bcWeights.value, Vectors.fromBreeze(c._1))
(c._1, c._2 + l, c._3 + 1)
},
combOp = (c1, c2) => {
// c: (grad, loss, count)
(c1._1 += c2._1, c1._2 + c2._2, c1._3 + c2._3)
})
...
val update = updater.compute(
weights, Vectors.fromBreeze(gradientSum / miniBatchSize.toDouble),
stepSize, i, regParam)
weights = update._1
regVal = update._2
如何更新权重向量?它是否并行工作?我以为RDD分为分区和分布式。我可以看到输入权重在spark上下文中广播并且使用了treeAggregate,总结了渐变但我仍然无法掌握哪个实际的map-reduce任务正在发生以及哪个部分发生在驱动程序中以及哪个部分发生在平行的方式。任何人都可以详细解释发生的事情吗?