protected float DifferentiableFunctionStream(FloatLabelCursor.Factory cursorFactory, ref VBuffer <float> xDense, ref VBuffer <float> grad, IProgressChannel pch)
        {
            Contracts.AssertValue(cursorFactory);

            VBufferUtils.Clear(ref grad);
            VBufferUtils.Densify(ref grad);

            float[] scratch = null;
            double  loss    = 0;
            long    count   = 0;

            if (pch != null)
            {
                pch.SetHeader(new ProgressHeader(null, new[] { "examples" }), e => e.SetProgress(0, count));
            }
            using (var cursor = cursorFactory.Create())
            {
                while (cursor.MoveNext())
                {
                    loss += AccumulateOneGradient(ref cursor.Features, cursor.Label, cursor.Weight,
                                                  ref xDense, ref grad, ref scratch);
                    count++;
                }
            }

            // we need use double type to accumulate loss to avoid roundoff error
            // please see http://mathworld.wolfram.com/RoundoffError.html for roundoff error definition
            // finally we need to convert double type to float for function definition
            return((float)loss);
        }
        protected float DifferentiableFunctionComputeChunk(int ichk, ref VBuffer <float> xDense, ref VBuffer <float> grad, IProgressChannel pch)
        {
            Contracts.Assert(0 <= ichk && ichk < _numChunks);
            Contracts.AssertValueOrNull(pch);

            VBufferUtils.Clear(ref grad);
            VBufferUtils.Densify(ref grad);

            float[] scratch = null;
            double  loss    = 0;
            int     ivMin   = _ranges[ichk];
            int     ivLim   = _ranges[ichk + 1];
            int     iv      = ivMin;

            if (pch != null)
            {
                pch.SetHeader(new ProgressHeader(null, new[] { "examples" }), e => e.SetProgress(0, iv - ivMin, ivLim - ivMin));
            }
            for (iv = ivMin; iv < ivLim; iv++)
            {
                float weight = _weights != null ? _weights[iv] : 1;
                loss += AccumulateOneGradient(ref _features[iv], _labels[iv], weight, ref xDense, ref grad, ref scratch);
            }
            // we need use double type to accumulate loss to avoid roundoff error
            // please see http://mathworld.wolfram.com/RoundoffError.html for roundoff error definition
            // finally we need to convert double type to float for function definition
            return((float)loss);
        }
Ejemplo n.º 3
0
        //Project the covariance matrix A on to Omega: Y <- A * Omega
        //A = X' * X / n, where X = data - mean
        //Note that the covariance matrix is not computed explicitly
        private static void Project(IHost host, FeatureFloatVectorCursor.Factory cursorFactory, ref VBuffer <Float> mean, VBuffer <Float>[] omega, VBuffer <Float>[] y, out long numBad)
        {
            Contracts.AssertValue(host, "host");
            host.AssertNonEmpty(omega);
            host.Assert(Utils.Size(y) == omega.Length); // Size of Y and Omega: dimension x oversampled rank
            int numCols = omega.Length;

            for (int i = 0; i < y.Length; ++i)
            {
                VBufferUtils.Clear(ref y[i]);
            }

            bool  center = mean.IsDense;
            Float n      = 0;
            long  count  = 0;

            using (var pch = host.StartProgressChannel("Project covariance matrix"))
                using (var cursor = cursorFactory.Create())
                {
                    pch.SetHeader(new ProgressHeader(new[] { "rows" }), e => e.SetProgress(0, count));
                    while (cursor.MoveNext())
                    {
                        if (center)
                        {
                            VectorUtils.AddMult(ref cursor.Features, cursor.Weight, ref mean);
                        }
                        for (int i = 0; i < numCols; i++)
                        {
                            VectorUtils.AddMult(
                                ref cursor.Features,
                                cursor.Weight * VectorUtils.DotProduct(ref omega[i], ref cursor.Features),
                                ref y[i]);
                        }
                        n += cursor.Weight;
                        count++;
                    }
                    pch.Checkpoint(count);
                    numBad = cursor.SkippedRowCount;
                }

            Contracts.Check(n > 0, "Empty training data");
            Float invn = 1 / n;

            for (var i = 0; i < numCols; ++i)
            {
                VectorUtils.ScaleBy(ref y[i], invn);
            }

            if (center)
            {
                VectorUtils.ScaleBy(ref mean, invn);
                for (int i = 0; i < numCols; i++)
                {
                    VectorUtils.AddMult(ref mean, -VectorUtils.DotProduct(ref omega[i], ref mean), ref y[i]);
                }
            }
        }