示例#1
0
        private IDictionary <string, float[]> GetPredictions(ILearner <TSample> learner)
        {
            var predictions      = new ConcurrentDictionary <string, float[]>();
            var sampleCount      = _positiveSamples.Length + _negativeSamples.Length;
            var samplesProcessed = 0;

            foreach (var config in learner.AllPossibleConfigurations())
            {
                if (config.IndexOfAny(new[] { '>', '?', ':', '\r', '\n' }) > 0)
                {
                    throw new FormatException("Learner configuration cannot contain any of '>', '?', ':', or a line break.");
                }
                predictions.TryAdd(config, new float[sampleCount]);
            }

            Parallel.ForEach(_positiveSamples.Concat(_negativeSamples), s =>
            {
                var localLearner = learner;
                localLearner.SetSample(s.Sample);

                foreach (var config in learner.AllPossibleConfigurations())
                {
                    localLearner = localLearner.WithConfiguration(config);

                    predictions[config][s.Index] = learner.Classify();
                }

                if (_cancellation.IsCancellationRequested)
                {
                    return;
                }
                if (_progress != null)
                {
                    if (Monitor.TryEnter(_progress))
                    {
                        try
                        {
                            samplesProcessed++;
                            _progress.Report(Tuple.Create("Running learner \"" + learner.UniqueId + "\"", samplesProcessed * 100 / sampleCount));
                        }
                        finally
                        {
                            Monitor.Exit(_progress);
                        }
                    }
                }
            });
            return(predictions);
        }
示例#2
0
        private LayerHolder OptimizeCoefficients(ILearner <TSample> learner, float[] outputs)
        {
            var positiveWeights = _positiveSamples.Select(s => s.Weight).ToArray();
            var negativeWeights = _negativeSamples.Select(s => s.Weight).ToArray();

            var positiveCorrect = new bool[_positiveSamples.Length];
            var negativeCorrect = new bool[_negativeSamples.Length];

#if DEBUG
            var perfect = true;
            foreach (var s in _positiveSamples.Concat(_negativeSamples))
            {
                learner.SetSample(s.Sample);
// ReSharper disable CompareOfFloatsByEqualityOperator
                if (learner.Classify() != outputs[s.Index])
                {
                    throw new Exception();
                }
                perfect &= s.Actual == outputs[s.Index];
// ReSharper restore CompareOfFloatsByEqualityOperator
            }
#endif

            //Find best bias point, adding one sample at a time to the predicted target set and updating the cost.
            //Note that -cost is the cost of the inverse of the current hypothesis i.e. "all samples are in the target".
            var bestThres = float.PositiveInfinity;
            var bestCost  = float.PositiveInfinity;
            var bestPos   = float.PositiveInfinity;
            var bestNeg   = float.NegativeInfinity;
            var threshold = float.NegativeInfinity;

            while (threshold < float.PositiveInfinity)
            {
                {
                    var i = 0;
                    foreach (var s in _positiveSamples)
                    {
                        positiveCorrect[i++] = outputs[s.Index] > threshold;
                    }
                    i = 0;
                    foreach (var s in _negativeSamples)
                    {
                        negativeCorrect[i++] = outputs[s.Index] <= threshold;
                    }
                }

                double sumWeightsPosCorrect   = 0;
                double sumWeightsPosIncorrect = 0;
                double sumWeightsNegCorrect   = 0;
                double sumWeightsNegIncorrect = 0;

                SumWeights(positiveWeights, positiveCorrect, ref sumWeightsPosCorrect, ref sumWeightsPosIncorrect);
                SumWeights(negativeWeights, negativeCorrect, ref sumWeightsNegCorrect, ref sumWeightsNegIncorrect);

                var coefPos = (float)Math.Log(sumWeightsPosCorrect / sumWeightsNegIncorrect) / 2;
                var coefNeg = (float)Math.Log(sumWeightsNegCorrect / sumWeightsPosIncorrect) / -2;

                coefPos = float.IsNaN(coefPos) ? 0 : coefPos;
                coefNeg = float.IsNaN(coefNeg) ? 0 : coefNeg;

                var loss = (float)(sumWeightsPosCorrect * Math.Exp(-coefPos) + sumWeightsNegIncorrect * Math.Exp(coefPos));
                loss += (float)(sumWeightsNegCorrect * Math.Exp(coefNeg) + sumWeightsPosIncorrect * Math.Exp(-coefNeg));

#if DEBUG
                if (!ApproxEqual((float)(sumWeightsNegCorrect + sumWeightsNegIncorrect + sumWeightsPosCorrect + sumWeightsPosIncorrect), 1))
                {
// ReSharper disable once EmptyStatement
                    ;
                }
                if (!perfect && (float.IsInfinity(coefNeg) || float.IsInfinity(coefPos)))
                {
                    throw new Exception("Unexpected coefficients");
                }

                //float calcLoss = 0;
                //calcLoss += getLoss(coefPos, coefNeg, positiveSamples.Select(s => s.confidence).Zip(positiveCorrect, (s, c) => new Tuple<float, bool>(s, c)), 1f);
                //calcLoss += getLoss(coefNeg, coefPos, negativeSamples.Select(s => s.confidence).Zip(negativeCorrect, (s, c) => new Tuple<float, bool>(s, c)), -1f);
#endif

                if (!float.IsNaN(loss) && loss < bestCost)
                {
                    bestCost  = loss;
                    bestPos   = coefPos;
                    bestNeg   = coefNeg;
                    bestThres = threshold;
                }


                var next = outputs.Aggregate(float.PositiveInfinity, (min, i) => (i > threshold && i < min) ? i : min);
                threshold = next;
            }

            return(new LayerHolder(bestCost, new Layer <TSample>(learner, bestPos, bestNeg, bestThres), outputs));
        }
示例#3
0
 internal float Classify(TSample s)
 {
     _learner.SetSample(s);
     return(_learner.Classify() > Threshold ? CoefPos : CoefNeg);
 }