Пример #1
0
 public void StartRERA(DaneshWindow gen, int num)
 {
     danesh = gen;
     numberOfAttemptsRandom = num;
     // DrawRandomERGraph();
     LastERA = SampleExpressiveRangeRandomly(num, gen);
 }
Пример #2
0
    public float Evaluate(object[] arr, float samples, DaneshWindow dan)
    {
        for (int i = 0; i < c_params.Count; i++)
        {
            c_params[i].field.SetValue(c_params[i].owner, arr[i]);
        }

        float totalScore = 0f;

        for (int att = 0; att < samples; att++)
        {
            object map   = dan.GenerateContent();
            float  score = 0f;
            //Obtain a metric reading for every targeted metric
            for (int i = 0; i < c_metrics.Count; i++)
            {
                float val = (float)dan.GetMetric(c_metrics[i], new object[] { map });
                score += 1 - Mathf.Abs(val - c_targets[i]);
            }
            //Get a score by averaging them
            totalScore += score / c_metrics.Count;
        }
        return(totalScore / (float)samples);
    }
Пример #3
0
    List <List <float> > SampleExpressiveRangeRandomly(int totalAttempts, DaneshWindow gen)
    {
        float progressBar = 0f;

        EditorUtility.DisplayProgressBar("Computing Randomised Expressive Range Histogram", "Working...", progressBar);
        List <List <float> > res = new List <List <float> >();

        /*
         *      Current:
         *      eraSample[metric1][metric2] = object[,] of samples representing the histogram
         *      Lot of data duplication here, not the most efficient way to do it
         */
        eraSamples = new List <List <object[, ]> >();
        for (int i = 0; i < danesh.metricList.Count; i++)
        {
            List <object[, ]> secondmetric = new List <object[, ]>();
            for (int j = 0; j < danesh.metricList.Count; j++)
            {
                object[,] sampleH = new object[100, 100];
                secondmetric.Add(sampleH);
            }
            eraSamples.Add(secondmetric);
        }

        for (int att = 0; att < totalAttempts; att++)
        {
            //Randomly parameterise the generator
            foreach (GeneratorParameter p in gen.parameterList)
            {
                p.RandomiseValue();
            }

            object       map  = danesh.GenerateContent();
            List <float> nums = new List <float>();
            for (int i = 0; i < danesh.metricList.Count; i++)
            {
                float score = (float)danesh.GetMetric(i, new object[] { map });
                nums.Add(score);
            }

            //Update the samples list
            for (int i = 0; i < nums.Count; i++)
            {
                int index1 = (int)Mathf.Round(nums[i] * 100f);
                if (index1 < 0)
                {
                    index1 = 0;
                }
                if (index1 > 99)
                {
                    index1 = 99;
                }
                for (int j = 0; j < nums.Count; j++)
                {
                    int index2 = (int)Mathf.Round(nums[j] * 100f);
                    if (index2 < 0)
                    {
                        index2 = 0;
                    }
                    if (index2 > 99)
                    {
                        index2 = 99;
                    }
                    eraSamples[i][j][index1, index2] = map;
                }
            }

            res.Add(nums);
            EditorUtility.DisplayProgressBar("Computing Randomised Expressive Range Histogram", "Evaluating random expressive range... " + (100 * (float)att / (float)totalAttempts).ToString("F0") + " percent complete", (float)att / (float)totalAttempts);
        }
        EditorUtility.ClearProgressBar();
        return(res);
    }
Пример #4
0
 public void StartERA(DaneshWindow gen, int num)
 {
     danesh           = gen;
     numberOfAttempts = num;
     LastERA          = SampleExpressiveRange(num);
 }
Пример #5
0
    public List <GeneratorParameter> FindParameters(DaneshWindow d, MonoBehaviour b)
    {
        // Debug.Log("Searching for parameters... "+d.metricList.Count+" metrics found.");
        List <GeneratorParameter> res = new List <GeneratorParameter>();

        //Collect a control sample set
        List <float>   metricAverages = new List <float>();
        List <float[]> stdev_samples  = new List <float[]>();
        List <float>   stdev          = new List <float>();

        for (int i = 0; i < d.metricList.Count; i++)
        {
            metricAverages.Add(0);
            stdev_samples.Add(new float[numSamples]);
        }

        for (int s = 0; s < numSamples; s++)
        {
            object output = d.GenerateContent();
            for (int i = 0; i < d.metricList.Count; i++)
            {
                GeneratorMetric m  = d.metricList[i];
                float           sc = (float)m.method.Invoke(null, new object[] { output });
                metricAverages[i]  += sc;
                stdev_samples[i][s] = sc;
            }
        }

        //Calculate averages and standard deviation
        for (int i = 0; i < d.metricList.Count; i++)
        {
            metricAverages[i] = metricAverages[i] / numSamples;
            // Debug.Log("Average for metric "+i+": "+metricAverages[i]);
            float sqdif = 0;
            foreach (float s in stdev_samples[i])
            {
                sqdif += Mathf.Pow(s - metricAverages[i], 2f);
            }
            sqdif = sqdif / numSamples;
            stdev.Add(Mathf.Sqrt(sqdif));
            // Debug.Log("Standard deviation for metric "+i+": "+stdev[i]);
        }

        foreach (FieldInfo field in d.generator.GetType().GetFields())
        {
            bool useParam = true;
            foreach (Attribute _attr in field.GetCustomAttributes(false))
            {
                if (_attr is TunableAttribute)
                {
                    //We already know this parameter is good so don't worry.
                    useParam = false;
                }
            }
            if (!useParam)
            {
                continue;
            }

            //Remember the original value
            object original_value = field.GetValue(b);
            //Change the value to something
            List <object> sampleValues = GetSampleValues(field, b);
            // Debug.Log(sampleValues.Count+" sample values found");
            //For each sample value, change the field to that value, run samples, get average
            foreach (object o in sampleValues)
            {
                field.SetValue(b, o);

                List <float> sampleData = new List <float>();
                for (int i = 0; i < d.metricList.Count; i++)
                {
                    sampleData.Add(0);
                }
                bool sampleFailed = false;
                for (int _ = 0; _ < numSamples; _++)
                {
                    try{
                        object output = d.GenerateContent();
                        for (int i = 0; i < d.metricList.Count; i++)
                        {
                            GeneratorMetric m = d.metricList[i];
                            sampleData[i] += (float)m.method.Invoke(null, new object[] { output });
                        }
                    }
                    catch (Exception e) {
                        //This failed, check the next value
                        sampleFailed = true;
                        break;
                    }
                }
                if (sampleFailed)
                {
                    continue;
                }
                //Did this change any of the metrics more than one standard deviation from the original sampling?
                bool nextParam = false;
                for (int i = 0; i < d.metricList.Count; i++)
                {
                    sampleData[i] = sampleData[i] / numSamples;
                    if (Mathf.Abs(sampleData[i] - metricAverages[i]) > stdev[i])
                    {
                        Debug.Log("Parameter " + field.Name + " may have an impact on metrics");
                        nextParam = true;
                        GeneratorParameter p = new GeneratorParameter(field.Name, original_value, original_value, original_value, field, b);
                        p.locked = true;
                        res.Add(p);
                        break;
                    }
                }
                if (nextParam)
                {
                    field.SetValue(b, original_value);
                    break;
                }
            }

            field.SetValue(b, original_value);
        }

        return(res);
    }
Пример #6
0
    public void Tune(DaneshWindow dan, List <GeneratorParameter> ps, List <GeneratorMetric> ms, List <float> ts)
    {
        this.c_params  = ps;
        this.c_metrics = ms;
        this.c_targets = ts;

        float bestScore = 0f;

        object[] bestArray = new object[ps.Count];

        //Pick a random spot
        float time = Time.realtimeSinceStartup;

        object[] ex = new object[ps.Count];
        for (int s = 0; s < ps.Count; s++)
        {
            ex[s] = ps[s].GetRandomValue();
        }

        bestScore = Evaluate(ex, 50, dan);
        bestArray = ex;

        EditorUtility.DisplayProgressBar("Automatic Tuning In Progress", "Working...", 0f);

        for (int iter = 0; iter < iterations; iter++)
        {
            if (bestScore > 0.98f)
            {
                break;
            }

            //Find all of the neighbouring parameter sets
            List <object[]> nbs                = CalculateNeighbours(ex);
            float           bestThisRound      = bestScore;
            object[]        bestArrayThisRound = new object[c_params.Count];

            foreach (object[] nb in nbs)
            {
                float score = Evaluate(nb, 50, dan);
                if (score > bestThisRound)
                {
                    bestThisRound      = score;
                    bestArrayThisRound = nb;
                }
            }

            if (bestThisRound > bestScore)
            {
                bestScore = bestThisRound;
                bestArray = bestArrayThisRound;
                ex        = bestArrayThisRound;
            }
            else
            {
                //Random restart
                ex = new object[c_params.Count];
                for (int s = 0; s < c_params.Count; s++)
                {
                    ex[s] = ps[s].GetRandomValue();
                }
            }

            EditorUtility.DisplayProgressBar("Auto-tuning", "Searching parameter space... " + (100 * (float)iter / (float)iterations).ToString("F0") + " percent complete", (float)iter / (float)iterations);
        }

        EditorUtility.ClearProgressBar();

        //Apply the parameters
        object[] pvs = bestArray;
        for (int i = 0; i < pvs.Length; i++)
        {
            c_params[i].SetValue(pvs[i]);
        }
    }