0

I am having difficulty reading open source mllib code for SGD with L2 regularization.

The code is

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)
}

The part I am having trouble with is

brzWeights :*= (1.0 - thisIterStepSize * regParam)

the breeze lib has documentation that explains the :*= operator

/** 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
}

it looks like its just multiplication of a vector by a scalar.

The formula I found for gradient in case of L2 regularization is

L2 gradient

How does the code represent this gradient in this update? Can someone help please.

4

1 回答 1

0

好的,我想通了。更新方程是

在此处输入图像描述

重新排列术语给出

在此处输入图像描述

认识到最后一项只是梯度

在此处输入图像描述

这等效于具有

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

现在代码和方程在归一化因子内匹配,我相信这在下一行中得到了处理。

于 2015-09-08T23:05:45.087 回答