Beispiel #1
0
        /// <summary>
        /// Computes a single-mutation neighborhood (one param at a time) for a given configuration. For
        /// numeric parameters, samples K mutations (i.e., creates K neighbors based on that paramater).
        /// </summary>
        /// <param name="parent">Starting configuration.</param>
        /// <returns>A set of configurations that each differ from parent in exactly one parameter.</returns>
        private ParameterSet[] GetOneMutationNeighborhood(ParameterSet parent)
        {
            List <ParameterSet>     neighbors = new List <ParameterSet>();
            SweeperProbabilityUtils spu       = new SweeperProbabilityUtils(_host);

            for (int i = 0; i < _sweepParameters.Length; i++)
            {
                // This allows us to query possible values of this parameter.
                IValueGenerator sweepParam = _sweepParameters[i];

                // This holds the actual value for this parameter, chosen in this parameter set.
                IParameterValue pset = parent[sweepParam.Name];

                _host.AssertValue(pset);

                DiscreteValueGenerator parameterDiscrete = sweepParam as DiscreteValueGenerator;
                if (parameterDiscrete != null)
                {
                    // Create one neighbor for every discrete parameter.
                    float[] neighbor = SweeperProbabilityUtils.ParameterSetAsFloatArray(_host, _sweepParameters, parent, false);

                    int hotIndex = -1;
                    for (int j = 0; j < parameterDiscrete.Count; j++)
                    {
                        if (parameterDiscrete[j].Equals(pset))
                        {
                            hotIndex = j;
                            break;
                        }
                    }

                    _host.Assert(hotIndex >= 0);

                    Random r           = new Random();
                    int    randomIndex = r.Next(0, parameterDiscrete.Count - 1);
                    randomIndex += randomIndex >= hotIndex ? 1 : 0;
                    neighbor[i]  = randomIndex;
                    neighbors.Add(SweeperProbabilityUtils.FloatArrayAsParameterSet(_host, _sweepParameters, neighbor, false));
                }
                else
                {
                    INumericValueGenerator parameterNumeric = sweepParam as INumericValueGenerator;
                    _host.Check(parameterNumeric != null, "SMAC sweeper can only sweep over discrete and numeric parameters");

                    // Create k neighbors (typically 4) for every numerical parameter.
                    for (int j = 0; j < _args.NumNeighborsForNumericalParams; j++)
                    {
                        float[] neigh  = SweeperProbabilityUtils.ParameterSetAsFloatArray(_host, _sweepParameters, parent, false);
                        double  newVal = spu.NormalRVs(1, neigh[i], 0.2)[0];
                        while (newVal <= 0.0 || newVal >= 1.0)
                        {
                            newVal = spu.NormalRVs(1, neigh[i], 0.2)[0];
                        }
                        neigh[i] = (float)newVal;
                        ParameterSet neighbor = SweeperProbabilityUtils.FloatArrayAsParameterSet(_host, _sweepParameters, neigh, false);
                        neighbors.Add(neighbor);
                    }
                }
            }
            return(neighbors.ToArray());
        }
Beispiel #2
0
        /// <summary>
        /// Generic parameter parser. Currently hand-hacked to auto-detect type.
        ///
        /// Generic form:   Name:Values
        /// for example,    lr:0.05-0.4
        ///          lambda:0.1-1000@log10
        ///          nl:2-64@log2
        ///          norm:-,+
        /// </summary>
        /// REVIEW: allow overriding auto-detection to specify type
        /// and delegate to parameter type for actual parsing
        /// REVIEW: specifying ordinal discrete parameters
        public bool TryParseParameter(string paramValue, Type paramType, string paramName, out IValueGenerator sweepValues, out string error)
        {
            sweepValues = null;
            error       = null;

            if (paramValue.Contains(','))
            {
                var generatorArgs = new DiscreteParamArguments();
                generatorArgs.Name   = paramName;
                generatorArgs.Values = paramValue.Split(',');
                sweepValues          = new DiscreteValueGenerator(generatorArgs);
                return(true);
            }

            // numeric parameter
            if (!CmdParser.IsNumericType(paramType))
            {
                return(false);
            }

            // REVIEW:  deal with negative bounds
            string scaleStr = null;
            int    atIdx    = paramValue.IndexOf('@');

            if (atIdx < 0)
            {
                atIdx = paramValue.IndexOf(';');
            }
            if (atIdx >= 0)
            {
                scaleStr   = paramValue.Substring(atIdx + 1);
                paramValue = paramValue.Substring(0, atIdx);
                if (scaleStr.Length < 1)
                {
                    error = $"Could not parse sweep range for parameter: {paramName}";
                    return(false);
                }
            }

            // Extract the minimum, and the maximum value of the list of suggested sweeps.
            // Positive lookahead splitting at the '-' character.
            // It is used for the Float and Long param types.
            // Example format: "0.02-0.1;steps:5".
            string[] minMaxRegex = Regex.Split(paramValue, "(?<=[^eE])-");
            if (minMaxRegex.Length != 2)
            {
                if (minMaxRegex.Length > 2)
                {
                    error = $"Could not parse sweep range for parameter: {paramName}";
                }

                return(false);
            }
            string minStr = minMaxRegex[0];
            string maxStr = minMaxRegex[1];

            int    numSteps = 100;
            Double stepSize = -1;
            bool   logBase  = false;

            if (scaleStr != null)
            {
                try
                {
                    string[] options          = scaleStr.Split(';');
                    bool[]   optionsSpecified = new bool[3];
                    foreach (string option in options)
                    {
                        if (option.StartsWith("log") && !option.StartsWith("log-") && !option.StartsWith("log:-"))
                        {
                            logBase             = true;
                            optionsSpecified[0] = true;
                        }
                        if (option.StartsWith("steps"))
                        {
                            numSteps            = int.Parse(option.Substring(option.IndexOf(':') + 1));
                            optionsSpecified[1] = true;
                        }
                        if (option.StartsWith("inc"))
                        {
                            stepSize            = Double.Parse(option.Substring(option.IndexOf(':') + 1), CultureInfo.InvariantCulture);
                            optionsSpecified[2] = true;
                        }
                    }
                    if (options.Length != optionsSpecified.Count(b => b))
                    {
                        error = $"Could not parse sweep range for parameter: {paramName}";
                        return(false);
                    }
                }
                catch (Exception e)
                {
                    error = $"Error creating sweep generator for parameter '{paramName}': {e.Message}";
                    return(false);
                }
            }

            if (paramType == typeof(UInt16) ||
                paramType == typeof(UInt32) ||
                paramType == typeof(UInt64) ||
                paramType == typeof(short) ||
                paramType == typeof(int) ||
                paramType == typeof(long))
            {
                long min;
                long max;
                if (!long.TryParse(minStr, out min) || !long.TryParse(maxStr, out max))
                {
                    return(false);
                }
                var generatorArgs = new Microsoft.ML.Sweeper.LongParamArguments();
                generatorArgs.Name     = paramName;
                generatorArgs.Min      = min;
                generatorArgs.Max      = max;
                generatorArgs.NumSteps = numSteps;
                generatorArgs.StepSize = (stepSize > 0 ? stepSize : new Nullable <Double>());
                generatorArgs.LogBase  = logBase;

                try
                {
                    sweepValues = new LongValueGenerator(generatorArgs);
                }
                catch (Exception e)
                {
                    error = $"Error creating sweep generator for parameter '{paramName}': {e.Message}";
                    return(false);
                }
            }
            else
            {
                Float minF;
                Float maxF;
                if (!Float.TryParse(minStr, out minF) || !Float.TryParse(maxStr, out maxF))
                {
                    return(false);
                }
                var floatArgs = new FloatParamArguments();
                floatArgs.Name     = paramName;
                floatArgs.Min      = minF;
                floatArgs.Max      = maxF;
                floatArgs.NumSteps = numSteps;
                floatArgs.StepSize = (stepSize > 0 ? stepSize : new Nullable <Double>());
                floatArgs.LogBase  = logBase;

                try
                {
                    sweepValues = new FloatValueGenerator(floatArgs);
                }
                catch (Exception e)
                {
                    error = $"Error creating sweep generator for parameter '{paramName}': {e.Message}";
                    return(false);
                }
            }
            return(true);
        }