Пример #1
0
        /// <summary>
        /// Gets the negative log-likelihood at the given input vector.
        /// </summary>
        /// <param name="x">The input vector.</param>
        /// <returns>The negative log-likelihood.</returns>
        /// <exception cref="ArgumentException">The <paramref name="x"/> is invalid, its dimension is not equal to domain dimension.</exception>
        public virtual double ValueAt(double[] x)
        {
            if (x.Length != dimension)
            {
                throw new ArgumentException("x is invalid, its dimension is not equal to domain dimension.", nameof(x));
            }

            int    ci;
            double negLogLikelihood = 0;

            for (ci = 0; ci < numContexts; ci++)
            {
                int oi;
                for (oi = 0; oi < numOutcomes; oi++)
                {
                    tempSums[oi] = 0;
                    int ai;
                    for (ai = 0; ai < contexts[ci].Length; ai++)
                    {
                        var vectorIndex = IndexOf(oi, contexts[ci][ai]);
                        var predValue   = values != null ? values[ci][ai] : 1.0;
                        tempSums[oi] += predValue * x[vectorIndex];
                    }
                }

                var logSumOfExps = ArrayMath.LogSumOfExps(tempSums);

                negLogLikelihood -= (tempSums[outcomeList[ci]] - logSumOfExps) * numTimesEventsSeen[ci];
            }

            return(negLogLikelihood);
        }
        private void NegLLCompute(int threadIndex, int startIndex, int length, double[] x)
        {
            negLogLikelihoodThread[threadIndex] = 0;

            // Knuppe: In parallel we can't use the tempSums variable ;)
            var temp = new double[numOutcomes];

            for (var ci = startIndex; ci < startIndex + length; ci++)
            {
                for (var oi = 0; oi < numOutcomes; oi++)
                {
                    temp[oi] = 0;
                    for (var ai = 0; ai < contexts[ci].Length; ai++)
                    {
                        var vectorIndex = IndexOf(oi, contexts[ci][ai]);
                        var predValue   = values != null ? values[ci][ai] : 1.0;
                        temp[oi] += predValue * x[vectorIndex];
                    }
                }

                var logSumOfExps = ArrayMath.LogSumOfExps(temp);

                var outcome = outcomeList[ci];

                negLogLikelihoodThread[threadIndex] -= (temp[outcome] - logSumOfExps) * numTimesEventsSeen[ci];
            }
        }
Пример #3
0
        /// <summary>
        /// Gets the gradient at the given input vector.
        /// </summary>
        /// <param name="x">The input vector.</param>
        /// <returns>The gradient value.</returns>
        /// <exception cref="System.ArgumentException">x is invalid, its dimension is not equal to domain dimension.;x</exception>
        /// <exception cref="ArgumentException">The <paramref name="x" /> is invalid, its dimension is not equal to domain dimension.</exception>
        public virtual double[] GradientAt(double[] x)
        {
            if (x.Length != dimension)
            {
                throw new ArgumentException("x is invalid, its dimension is not equal to domain dimension.", nameof(x));
            }

            int ci;

            // Reset gradient
            for (var i = 0; i < gradient.Length; i++)
            {
                gradient[i] = 0;
            }

            for (ci = 0; ci < numContexts; ci++)
            {
                int    oi;
                double predValue;
                int    vectorIndex;
                int    ai;
                for (oi = 0; oi < numOutcomes; oi++)
                {
                    expectation[oi] = 0;
                    for (ai = 0; ai < contexts[ci].Length; ai++)
                    {
                        vectorIndex      = IndexOf(oi, contexts[ci][ai]);
                        predValue        = values != null ? values[ci][ai] : 1.0;
                        expectation[oi] += predValue * x[vectorIndex];
                    }
                }

                var logSumOfExps = ArrayMath.LogSumOfExps(expectation);

                for (oi = 0; oi < numOutcomes; oi++)
                {
                    expectation[oi] = Math.Exp(expectation[oi] - logSumOfExps);
                }

                for (oi = 0; oi < numOutcomes; oi++)
                {
                    var empirical = outcomeList[ci] == oi ? 1 : 0;
                    for (ai = 0; ai < contexts[ci].Length; ai++)
                    {
                        vectorIndex            = IndexOf(oi, contexts[ci][ai]);
                        predValue              = values != null ? values[ci][ai] : 1.0;
                        gradient[vectorIndex] +=
                            predValue * (expectation[oi] - empirical) * numTimesEventsSeen[ci];
                    }
                }
            }

            return(gradient);
        }
        private void GradientCompute(int threadIndex, int startIndex, int length, double[] x)
        {
            var exp = new double[numOutcomes];

            // Reset gradientThread
            Array.Clear(gradientThread[threadIndex], 0, gradientThread[threadIndex].Length);

            for (var ci = startIndex; ci < startIndex + length; ci++)
            {
                double predValue;
                int    vectorIndex;
                for (var oi = 0; oi < numOutcomes; oi++)
                {
                    exp[oi] = 0;
                    for (var ai = 0; ai < contexts[ci].Length; ai++)
                    {
                        vectorIndex = IndexOf(oi, contexts[ci][ai]);
                        predValue   = values != null ? values[ci][ai] : 1.0;
                        exp[oi]    += predValue * x[vectorIndex];
                    }
                }

                var logSumOfExps = ArrayMath.LogSumOfExps(exp);

                for (var oi = 0; oi < numOutcomes; oi++)
                {
                    exp[oi] = Math.Exp(exp[oi] - logSumOfExps);
                }

                for (var oi = 0; oi < numOutcomes; oi++)
                {
                    var empirical = outcomeList[ci] == oi ? 1 : 0;
                    for (var ai = 0; ai < contexts[ci].Length; ai++)
                    {
                        vectorIndex = IndexOf(oi, contexts[ci][ai]);
                        predValue   = values != null ? values[ci][ai] : 1.0;
                        gradientThread[threadIndex][vectorIndex] += predValue * (exp[oi] - empirical) *
                                                                    numTimesEventsSeen[ci];
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Model evaluation which should be used during training to report model accuracy.
        /// </summary>
        /// <param name="context">Indices of the predicates which have been observed at the present decision point.</param>
        /// <param name="values">The weights of the predicates which have been observed at the present decision point.</param>
        /// <param name="probs">The probability for outcomes.</param>
        /// <param name="nOutcomes">The number of outcomes.</param>
        /// <param name="nPredLabels">The number of unique predicates.</param>
        /// <param name="parameters">The model parameters.</param>
        /// <returns>The normalized probabilities for the outcomes given the context.</returns>
        public static double[] Eval(int[] context, float[] values, double[] probs, int nOutcomes, int nPredLabels, double[] parameters)
        {
            for (var i = 0; i < context.Length; i++)
            {
                var predIdx   = context[i];
                var predValue = values != null ? values[i] : 1d;

                for (var oi = 0; oi < nOutcomes; oi++)
                {
                    probs[oi] += predValue * parameters[oi * nPredLabels + predIdx];
                }
            }

            var logSumExp = ArrayMath.LogSumOfExps(probs);

            for (var oi = 0; oi < nOutcomes; oi++)
            {
                probs[oi] = Math.Exp(probs[oi] - logSumExp);
            }


            return(probs);
        }
Пример #6
0
        /// <summary>
        /// Model evaluation which should be used during inference.
        /// </summary>
        /// <param name="context">The predicates which have been observed at the present decision point.</param>
        /// <param name="values">The weights of the predicates which have been observed at the present decision point.</param>
        /// <param name="probs">The probability for outcomes.</param>
        /// <returns>The normalized probabilities for the outcomes given the context.</returns>
        public double[] Eval(string[] context, float[] values, double[] probs)
        {
            var ep = evalParameters.Parameters;

            for (var ci = 0; ci < context.Length; ci++)
            {
                var predIdx = GetPredIndex(context[ci]);

                if (predIdx < 0)
                {
                    continue;
                }

                var predValue = 1d;

                if (values != null)
                {
                    predValue = values[ci];
                }

                var outcomes   = ep[predIdx].Outcomes;
                var parameters = ep[predIdx].Parameters;
                for (var i = 0; i < outcomes.Length; i++)
                {
                    probs[outcomes[i]] += predValue * parameters[i];
                }
            }

            var logSumExp = ArrayMath.LogSumOfExps(probs);

            for (var oi = 0; oi < outcomeNames.Length; oi++)
            {
                probs[oi] = Math.Exp(probs[oi] - logSumExp);
            }

            return(probs);
        }