在mllib中使用L2正则化的SGD

时间:2015-09-04 17:54:46

标签: apache-spark apache-spark-mllib gradient-descent scala-breeze

我很难通过L2正规化读取SGD的开源mllib代码。

代码是

class SquaredL2Updater extends Updater {
override def compute(
  weightsOld: Vector,
  gradient: Vector,
  stepSize: Double,
  iter: Int,
  regParam: Double): (Vector, Double) = {
// add up both updates from the gradient of the loss (= step) as well as
// the gradient of the regularizer (= regParam * weightsOld)
// w' = w - thisIterStepSize * (gradient + regParam * w)
// w' = (1 - thisIterStepSize * regParam) * w - thisIterStepSize * gradient
val thisIterStepSize = stepSize / math.sqrt(iter)
val brzWeights: BV[Double] = weightsOld.toBreeze.toDenseVector
brzWeights :*= (1.0 - thisIterStepSize * regParam)
brzAxpy(-thisIterStepSize, gradient.toBreeze, brzWeights)
val norm = brzNorm(brzWeights, 2.0)

(Vectors.fromBreeze(brzWeights), 0.5 * regParam * norm * norm)
}

我遇到问题的部分是

brzWeights :*= (1.0 - thisIterStepSize * regParam)

breeze lib包含解释:* =运算符

的文档
/** Mutates this by element-wise multiplication of b into this. */
final def :*=[TT >: This, B](b: B)(implicit op: OpMulScalar.InPlaceImpl2[TT, B]): This = {
 op(repr, b)
 repr
}

看起来它只是将一个向量乘以标量。

在L2正则化的情况下我发现的梯度公式是

L2 gradient

此更新中的代码如何表示此渐变?有人可以帮忙吗。

1 个答案:

答案 0 :(得分:0)

好的,我明白了。更新程序是

enter image description here

重新安排条款

enter image description here

识别最后一个术语只是渐变

enter image description here

这相当于具有

的代码
brzAxpy(-thisIterStepSize, gradient.toBreeze, brzWeights)

打破了

brzWeights = brzWeights + -thisIterStepSize * gradient.toBreeze

在上一行中,brzWeights:* =(1.0 - thisIterStepSize * regParam)

这意味着     brzWeights = brzWeights *(1.0 - thisIterStepSize * regParam)

所以,最后

brzWeights = brzWeights * (1.0 - thisIterStepSize * regParam) + (-thisIterStepSize) * gradient.toBreeze

现在代码和方程在一个归一化因子内匹配,我相信在下面的行中处理。