// 根据正则化方法计算偏导数向量需要添加正则化项 func ComputeRegularization(weights *util.Matrix, options OptimizerOptions) *util.Matrix { reg := weights.Populate() if options.RegularizationScheme == 1 { // L-1正则化 for iLabel := 0; iLabel < weights.NumLabels(); iLabel++ { for _, k := range weights.GetValues(iLabel).Keys() { if weights.Get(iLabel, k) > 0 { reg.Set(iLabel, k, options.RegularizationFactor) } else { reg.Set(iLabel, k, -options.RegularizationFactor) } } } } else if options.RegularizationScheme == 2 { // L-2正则化 for iLabel := 0; iLabel < weights.NumLabels(); iLabel++ { for _, k := range weights.GetValues(iLabel).Keys() { reg.Set(iLabel, k, options.RegularizationFactor*float64(2)*weights.Get(iLabel, k)) } } } return reg }
// 计算 z = 1 + sum(exp(sum(w_i * x_i))) // // 在temp中保存 exp(sum(w_i * x_i)) func ComputeZ(weights *util.Matrix, features *util.Vector, label int, temp *util.Matrix) float64 { result := float64(1.0) numLabels := weights.NumLabels() + 1 for iLabel := 1; iLabel < numLabels; iLabel++ { exp := math.Exp(util.VecDotProduct(features, weights.GetValues(iLabel-1))) result += exp tempVec := temp.GetValues(iLabel - 1) if tempVec.IsSparse() { for _, k := range features.Keys() { tempVec.Set(k, exp) } } else { tempVec.SetAll(exp) } } return result }
func MaxEntComputeInstanceDerivative( weights *util.Matrix, instance *data.Instance, instanceDerivative *util.Matrix) { // 定义偏导和特征向量 features := instance.Features // 得到维度信息 numLabels := weights.NumLabels() + 1 // 计算 z = 1 + exp(sum(w_i * x_i)) label := instance.Output.Label z := ComputeZ(weights, features, label, instanceDerivative) inverseZ := float64(1) / z for iLabel := 1; iLabel < numLabels; iLabel++ { vec := instanceDerivative.GetValues(iLabel - 1) if label == 0 || label != iLabel { vec.Multiply(inverseZ, 0, features) } else { vec.Multiply(inverseZ, -1, features) } } }