Exemplo n.º 1
0
 internal OptimizerException(OptimizerState state, string message)
     : base(message)
 {
     State = state;
 }
Exemplo n.º 2
0
 /// <summary>
 /// Makes a PrematureConvergenceException with the supplied message
 /// </summary>
 /// <param name="state">The OptimizerState when the exception was thrown</param>
 /// <param name="message">message for exception</param>
 public PrematureConvergenceException(OptimizerState state, string message) : base(state, message)
 {
 }
Exemplo n.º 3
0
        static float Optimize(
            float currentTime,
            float value,
            float previousValue,
            float optimizedValue,
            float maxValue,
            float minValue,
            float optimizerDelta,
            float countDelta,
            float smallStep,
            float largeStep,
            bool reversed)
        {
            float delta = previousValue - value;

            SWConsole.Debug($"=========================Optimize=================================");
            SWConsole.Debug($"previousValue={previousValue}");
            SWConsole.Debug($"value={value}");
            SWConsole.Debug($"delta={delta}");
            OptimizerState optimizerState = OptimizerState.Constant;

            if (delta > optimizerDelta)
            {
                optimizerState = OptimizerState.Decreasing;
            }
            else if (delta < -optimizerDelta)
            {
                optimizerState = OptimizerState.Increasing;
            }

            float deltaToOptimized = optimizedValue - value;

            OptimizerCountState countState = OptimizerCountState.Optimized;

            if (deltaToOptimized > countDelta)
            {
                countState = OptimizerCountState.NotEnough;
            }
            else if (deltaToOptimized < -countDelta)
            {
                countState = OptimizerCountState.TooMany;
            }

            bool shouldSlowDown      = false;
            bool shouldSlowDownSmall = false;
            bool shouldSpeedUpSmall  = false;
            bool shouldSpeedUp       = false;

            if (reversed)
            {
                shouldSpeedUp  = (countState == OptimizerCountState.NotEnough && optimizerState == OptimizerState.Decreasing);
                shouldSpeedUp |= (countState == OptimizerCountState.Optimized && optimizerState == OptimizerState.Decreasing);

                shouldSlowDown  = (countState == OptimizerCountState.TooMany && optimizerState == OptimizerState.Increasing);
                shouldSlowDown |= (countState == OptimizerCountState.Optimized && optimizerState == OptimizerState.Increasing);

                shouldSpeedUpSmall  = (optimizerState == OptimizerState.Constant && countState == OptimizerCountState.NotEnough);
                shouldSlowDownSmall = (optimizerState == OptimizerState.Constant && countState == OptimizerCountState.TooMany);
            }
            else
            {
                shouldSlowDown  = (countState == OptimizerCountState.NotEnough && optimizerState == OptimizerState.Decreasing);
                shouldSlowDown |= (countState == OptimizerCountState.Optimized && optimizerState == OptimizerState.Decreasing);

                shouldSpeedUp  = (countState == OptimizerCountState.TooMany && optimizerState == OptimizerState.Increasing);
                shouldSpeedUp |= (countState == OptimizerCountState.Optimized && optimizerState == OptimizerState.Increasing);

                shouldSlowDownSmall = (optimizerState == OptimizerState.Constant && countState == OptimizerCountState.NotEnough);
                shouldSpeedUpSmall  = (optimizerState == OptimizerState.Constant && countState == OptimizerCountState.TooMany);
            }

            SWConsole.Debug($"optimizerState={optimizerState}");
            SWConsole.Debug($"countState={countState}");

            float result = currentTime;

            if (shouldSpeedUp)
            {
                result = currentTime * largeStep;
                if (result < minValue)
                {
                    result = minValue;
                }
                SWConsole.Debug($"shouldSpeedUp");
            }
            else if (shouldSpeedUpSmall)
            {
                result = currentTime * smallStep;
                if (result < minValue)
                {
                    result = minValue;
                }
                SWConsole.Debug($"shouldSpeedUpSmall");
            }
            else if (shouldSlowDown)
            {
                result = currentTime / largeStep;
                if (result > maxValue)
                {
                    result = maxValue;
                }
                SWConsole.Debug($"shouldSlowDown");
            }
            else if (shouldSlowDownSmall)
            {
                result = currentTime / smallStep;
                if (result > maxValue)
                {
                    result = maxValue;
                }
                SWConsole.Debug($"shouldSlowDownSmall");
            }

            SWConsole.Debug($"result={result}");

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Minimize a function using the supplied termination criterion
        /// </summary>
        /// <param name="function">The function to minimize</param>
        /// <param name="initial">The initial point</param>
        /// <param name="term">termination criterion to use</param>
        /// <param name="result">The point at the optimum</param>
        /// <param name="optimum">The optimum function value</param>
        /// <exception cref="PrematureConvergenceException">Thrown if successive points are within numeric precision of each other, but termination condition is still unsatisfied.</exception>
        public void Minimize(DifferentiableFunction function, ref VBuffer <Float> initial, ITerminationCriterion term, ref VBuffer <Float> result, out Float optimum)
        {
            const string computationName = "LBFGS Optimizer";

            using (var pch = Env.StartProgressChannel(computationName))
                using (var ch = Env.Start(computationName))
                {
                    ch.Info("Beginning optimization");
                    ch.Info("num vars: {0}", initial.Length);
                    ch.Info("improvement criterion: {0}", term.FriendlyName);

                    OptimizerState state = MakeState(ch, pch, function, ref initial);
                    term.Reset();

                    var header = new ProgressHeader(new[] { "Loss", "Improvement" }, new[] { "iterations", "gradients" });
                    pch.SetHeader(header,
                                  (Action <IProgressEntry>)(e =>
                    {
                        e.SetProgress(0, (double)(state.Iter - 1));
                        e.SetProgress(1, state.GradientCalculations);
                    }));

                    bool finished = false;
                    pch.Checkpoint(state.Value, null, 0);
                    state.UpdateDir();
                    while (!finished)
                    {
                        bool success = state.LineSearch(ch, false);
                        if (!success)
                        {
                            // problem may be numerical errors in previous gradients
                            // try to save state of optimization by discarding them
                            // and starting over with gradient descent.

                            state.DiscardOldVectors();

                            state.UpdateDir();

                            state.LineSearch(ch, true);
                        }

                        string message;
                        finished = term.Terminate(state, out message);

                        double?improvement = null;
                        double x;
                        int    end;
                        if (message != null && DoubleParser.TryParse(out x, message, 0, message.Length, out end))
                        {
                            improvement = x;
                        }

                        pch.Checkpoint(state.Value, improvement, state.Iter);

                        if (!finished)
                        {
                            state.Shift();
                            state.UpdateDir();
                        }
                    }

                    state.X.CopyTo(ref result);
                    optimum = state.Value;
                    ch.Done();
                }
        }