コード例 #1
0
        /// <summary>
        /// The gradient being used by the optimizer
        /// </summary>
        protected virtual float DifferentiableFunction(ref VBuffer <float> x, ref VBuffer <float> gradient,
                                                       IProgressChannelProvider progress)
        {
            Contracts.Assert((_numChunks == 0) != (_data == null));
            Contracts.Assert((_cursorFactory == null) == (_data == null));
            Contracts.Assert(x.Length == BiasCount + WeightCount);
            Contracts.Assert(gradient.Length == BiasCount + WeightCount);
            // REVIEW: if/when LBFGS test code is removed, the progress provider needs to become required.
            Contracts.AssertValueOrNull(progress);

            float           scaleFactor = 1 / (float)WeightSum;
            VBuffer <float> xDense      = default(VBuffer <float>);

            if (x.IsDense)
            {
                xDense = x;
            }
            else
            {
                x.CopyToDense(ref xDense);
            }

            IProgressChannel pch = progress != null?progress.StartProgressChannel("Gradient") : null;

            float loss;

            using (pch)
            {
                loss = _data == null
                    ? DifferentiableFunctionMultithreaded(ref xDense, ref gradient, pch)
                    : DifferentiableFunctionStream(_cursorFactory, ref xDense, ref gradient, pch);
            }
            float regLoss = 0;

            if (L2Weight > 0)
            {
                Contracts.Assert(xDense.IsDense);
                var    values = xDense.Values;
                Double r      = 0;
                for (int i = BiasCount; i < values.Length; i++)
                {
                    var xx = values[i];
                    r += xx * xx;
                }
                regLoss = (float)(r * L2Weight * 0.5);

                // Here we probably want to use sparse x
                VBufferUtils.ApplyWithEitherDefined(ref x, ref gradient,
                                                    (int ind, float v1, ref float v2) => { if (ind >= BiasCount)
                                                                                           {
                                                                                               v2 += L2Weight * v1;
                                                                                           }
                                                    });
            }
            VectorUtils.ScaleBy(ref gradient, scaleFactor);

            // REVIEW: The regularization component of the loss is being scaled as well,
            // but it's unclear that it should be scaled.
            return((loss + regLoss) * scaleFactor);
        }
コード例 #2
0
 protected void FixDirZeros()
 {
     VBufferUtils.ApplyWithEitherDefined(ref _steepestDescDir, ref _dir,
                                         (int i, Float sdVal, ref Float dirVal) =>
     {
         if (sdVal == 0)
         {
             dirVal = 0;
         }
     });
 }
コード例 #3
0
        /// <summary>
        /// Multiplies arrays Dst *= A element by element and returns the result in <paramref name="dst"/> (Hadamard product).
        /// </summary>
        public static void MulElementWise(ref VBuffer <Float> a, ref VBuffer <Float> dst)
        {
            Contracts.Check(a.Length == dst.Length, "Vectors must have the same dimensionality.");

            if (a.IsDense && dst.IsDense)
            {
                CpuMathUtils.MulElementWise(a.Values, dst.Values, dst.Values, a.Length);
            }
            else
            {
                VBufferUtils.ApplyWithEitherDefined(ref a, ref dst, (int ind, Float v1, ref Float v2) => { v2 *= v1; });
            }
        }