在 mllib 中使用 L2 正则化的 SGD
SGD with L2 regularization in mllib
我很难阅读带有 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 库有解释 :*= 运算符的文档
/** 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 正则化的情况下找到的梯度公式是
本次更新中代码是如何表示这个渐变的?有人可以帮忙吗
好的,我明白了。更新方程式是
重新排列项给出
认识到最后一项只是梯度
这相当于
的代码
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
现在代码和等式在归一化因子内匹配,我相信在下一行中会处理。
我很难阅读带有 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 库有解释 :*= 运算符的文档
/** 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 正则化的情况下找到的梯度公式是
本次更新中代码是如何表示这个渐变的?有人可以帮忙吗
好的,我明白了。更新方程式是
重新排列项给出
认识到最后一项只是梯度
这相当于
的代码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
现在代码和等式在归一化因子内匹配,我相信在下一行中会处理。