/// <summary>
        /// Constructs with the details of the function regression problem to be visualized.
        /// </summary>
        /// <param name="fn">The function being regressed.</param>
        /// <param name="generativeMode">Indicates that blacbox has no inputs; it will generate a waveform as a function of time.</param>
        /// <param name="paramSamplingInfo">Parameter sampling info.</param>
        /// <param name="genomeDecoder">Genome decoder.</param>
        public FnRegressionView2D(IFunction fn, ParamSamplingInfo paramSamplingInfo, bool generativeMode, IGenomeDecoder <NeatGenome, IBlackBox> genomeDecoder)
        {
            InitializeComponent();
            InitGraph(string.Empty, string.Empty, string.Empty);

            _fn = fn;
            _paramSamplingInfo = paramSamplingInfo;
            _generativeMode    = generativeMode;
            _genomeDecoder     = genomeDecoder;

            // Determine the mid output value of the function (over the specified sample points) and a scaling factor
            // to apply the to neural netwkrk response for it to be able to recreate the function (because the neural net
            // output range is [0,1] when using the logistic function as the neurn activation function).
            double mid, scale;

            FnRegressionUtils.CalcFunctionMidAndScale(fn, paramSamplingInfo, out mid, out scale);
            if (generativeMode)
            {
                _blackBoxProbe = new GenerativeBlackBoxProbe(paramSamplingInfo, mid, scale);
            }
            else
            {
                _blackBoxProbe = new BlackBoxProbe(paramSamplingInfo, mid, scale);
            }

            _yArrTarget = new double[paramSamplingInfo._sampleCount];

            // Pre-build plot point objects.
            _plotPointListTarget   = new PointPairList();
            _plotPointListResponse = new PointPairList();

            double[] xArr = paramSamplingInfo._xArr;
            for (int i = 0; i < xArr.Length; i++)
            {
                double x = xArr[i];
                _plotPointListTarget.Add(x, _fn.GetValue(x));
                _plotPointListResponse.Add(x, 0.0);
            }

            // Bind plot points to graph.
            zed.GraphPane.AddCurve("Target", _plotPointListTarget, Color.Black, SymbolType.None);
            zed.GraphPane.AddCurve("Network Response", _plotPointListResponse, Color.Red, SymbolType.None);
        }
Esempio n. 2
0
        /// <summary>
        /// Evaluate the provided IBlackBox against the XOR problem domain and return its fitness score.
        /// </summary>
        public FitnessInfo Evaluate(IBlackBox box)
        {
            int sampleCount = _paramSamplingInfo._sampleCount;

            // TODO: We can avoid a memory allocation here by allocating at construction time, but this requires modification of
            // ParallelGenomeListEvaluator to utilise multiple evaluators (one per thread).
            double[] yArr        = new double[sampleCount];
            double[] gradientArr = new double[sampleCount];

            // Probe the black box over the full range of the input parameter.
            _blackBoxProbe.Probe(box, yArr);

            // Calc gradients.
            FnRegressionUtils.CalcGradients(_paramSamplingInfo, yArr, gradientArr);

            // Calc y position mean squared error (MSE), and apply weighting.
            double yMse = FnRegressionUtils.CalcMeanSquaredError(yArr, _yArrTarget);

            yMse *= _yMseWeight;

            // Calc gradient mean squared error.
            double gradientMse = FnRegressionUtils.CalcMeanSquaredError(gradientArr, _gradientArrTarget);

            gradientMse *= _gradientMseWeight;

            // Calc fitness as the inverse of MSE (higher value is fitter).
            // Add a constant to avoid divide by zero, and to constrain the fitness range between bad and good solutions;
            // this allows the selection strategy to select solutions that are mediocre and therefore helps preserve diversity.
            double fitness = 20.0 / (yMse + gradientMse + 0.02);

            // Test for stopping condition (near perfect response).
            if (fitness >= 100000.0)
            {
                _stopConditionSatisfied = true;
            }
            _evalCount++;
            return(new FitnessInfo(fitness, fitness));
        }