示例#1
0
    public void AfterTrainingJob(NeuralBurst trainee, float dt)
    {
        var traineeBody = trainee.cachedRigidbody;

        var brake = traineeBody.velocity * -trainee.state2[3];
        var force = new Vector3(
            trainee.state2[0],
            trainee.state2[1],
            trainee.state2[2]
            ) * 1000.0f;

        //if (float.IsNaN(force.x)) force.x = 0.0f;
        //if (float.IsNaN(force.y)) force.y = 0.0f;
        //if (float.IsNaN(force.z)) force.z = 0.0f;

        var apply = (brake + force) * dt;

        traineeBody.AddForce(apply, ForceMode.Acceleration);

        if (showDebugLines)
        {
            //Debug.DrawLine(new Vector3(trainee.state0[0], trainee.state0[1], trainee.state0[2]), new Vector3(trainee.state0[3], trainee.state0[4], trainee.state0[5]), new Color(trainee.state2[0] * 2.0f, trainee.state2[1] * 2.0f, trainee.state2[2] * 2.0f));
            //Debug.DrawLine(new Vector3(trainee.state0[0], trainee.state0[1], trainee.state0[2]), new Vector3(trainee.state0[6], trainee.state0[7], trainee.state0[8]), Color.white);

            var accuracy = Vector3.Dot(force.normalized, (target.position - traineeBody.position).normalized);
            Debug.DrawLine(trainee.transform.position, trainee.transform.position + force * 0.01f, Color.Lerp(Color.white, Color.red, accuracy));
        }
    }
示例#2
0
    public void CalculateResult(NeuralBurst trainee, TrainingResult result)
    {
        var ofs = trainee.transform.position - target.transform.position;
        var lsq = ofs.sqrMagnitude;
        var len = 0.0f;

        if (lsq > 0.001f)
        {
            len = ofs.magnitude;
        }

        result.score = len;
    }
示例#3
0
    public NeuralBurst.StepJob PrepareAndQueueJobStep(NeuralBurst trainee, float dt)
    {
        var traineeBody = trainee.cachedRigidbody;

        trainee.state0[0] = target.transform.position.x - trainee.transform.position.x;
        trainee.state0[1] = target.transform.position.y - trainee.transform.position.y;
        trainee.state0[2] = target.transform.position.z - trainee.transform.position.z;

        trainee.state0[3] = traineeBody.velocity.x;
        trainee.state0[4] = traineeBody.velocity.y;
        trainee.state0[5] = traineeBody.velocity.z;

        return(trainee.QueueJobStep());
    }
示例#4
0
    public EvolveJob QueueJobEvolve(uint seed, NeuralBurst from, float evolveRate)
    {
        var job = new EvolveJob()
        {
            Seed           = seed,
            EvolveRate     = evolveRate,
            Layer0         = this.Layer0,
            Layer1         = this.Layer1,
            Layer2         = this.Layer2,
            from_bias0     = from.bias0,
            from_bias1     = from.bias1,
            from_bias2     = from.bias2,
            from_weights10 = from.weights10,
            from_weights21 = from.weights21,
            bias0          = this.bias0,
            bias1          = this.bias1,
            bias2          = this.bias2,
            weights10      = this.weights10,
            weights21      = this.weights21,
        };

        return(job);
    }
示例#5
0
    public void Evolve(NeuralBurst from, float x)
    {
        for (int i = 0; i < Layer0; ++i)
        {
            bias0[i] = UnityEngine.Random.Range(0.0f, 1.0f) < x ? from.bias0[i] : bias0[i];
        }
        for (int i = 0; i < Layer1; ++i)
        {
            bias1[i] = UnityEngine.Random.Range(0.0f, 1.0f) < x ? from.bias1[i] : bias1[i];
        }
        for (int i = 0; i < Layer2; ++i)
        {
            bias2[i] = UnityEngine.Random.Range(0.0f, 1.0f) < x ? from.bias2[i] : bias2[i];
        }

        for (int i = 0; i < Layer0 * Layer1; ++i)
        {
            weights10[i] = UnityEngine.Random.Range(0.0f, 1.0f) < x ? from.weights10[i] : weights10[i];
        }
        for (int i = 0; i < Layer1 * Layer2; ++i)
        {
            weights21[i] = UnityEngine.Random.Range(0.0f, 1.0f) < x ? from.weights21[i] : weights21[i];
        }
    }
示例#6
0
    public void LerpTowards(NeuralBurst from, float x)
    {
        for (int i = 0; i < Layer0; ++i)
        {
            bias0[i] = Mathf.Lerp(bias0[i], from.bias0[i], x);
        }
        for (int i = 0; i < Layer1; ++i)
        {
            bias1[i] = Mathf.Lerp(bias1[i], from.bias1[i], x);
        }
        for (int i = 0; i < Layer2; ++i)
        {
            bias2[i] = Mathf.Lerp(bias2[i], from.bias2[i], x);
        }

        for (int i = 0; i < Layer0 * Layer1; ++i)
        {
            weights10[i] = Mathf.Lerp(weights10[i], from.weights10[i], x);
        }
        for (int i = 0; i < Layer1 * Layer2; ++i)
        {
            weights21[i] = Mathf.Lerp(weights21[i], from.weights21[i], x);
        }
    }
示例#7
0
    public IEnumerator RunTrainingLoop()
    {
        Debug.LogFormat("NeuralTrainerEvolution_Follow.RunTrainingLoop(): running...");

        var cycle = 0;

        bestScore   = float.MaxValue;
        bestTrainee = (NeuralBurst)null;

        var stepJobs   = new List <JobHandle>(trainees.Count);
        var mutateJobs = new List <JobHandle>(trainees.Count);
        var evolveJobs = new List <JobHandle>(trainees.Count);

        while (true)
        {
            ClearResults();

            var worldOffset = Vector3.zero;

            if (trainingPhase >= 5)
            {
                worldOffset = Random.onUnitSphere * Random.Range(10.0f, 20.0f);
            }

            for (int i = 0; i < trainees.Count; ++i)
            {
                var trainee = trainees[i];
                var result  = results[i];

                var direction = Random.onUnitSphere;
                direction.y = 0.0f;
                direction   = direction.normalized;

                var position = new Vector3(
                    Random.Range(-10.0f, 10.0f),
                    Random.Range(-10.0f, 10.0f),
                    Random.Range(-10.0f, 10.0f));

                trainee.transform.position = position + worldOffset;
                trainee.transform.rotation = Quaternion.LookRotation(Random.onUnitSphere);

                trainee.GetComponent <Renderer>().material.color = trainee.GenerateColor();
            }

            switch (trainingPhase)
            {
            case 0:
                target.transform.position = Vector3.zero;
                break;

            case 1:
            {
                var position = Random.onUnitSphere * 5.0f;
                position.y = 0.0f;
                target.transform.position = position;
            }
            break;

            case 2:
                target.transform.position = Random.onUnitSphere * 5.0f;
                break;

            case 3:
                target.transform.position = Random.onUnitSphere * Random.Range(0.0f, 10.0f);
                break;

            case 4:
                target.transform.position = Random.onUnitSphere * Random.Range(0.0f, 10.0f);
                break;

            case 5:
                target.transform.position = Random.onUnitSphere * Random.Range(0.0f, 10.0f) + worldOffset;
                break;
            }

            var counter = 0.0f;

            while (counter < cycleTime)
            {
                if (hyper)
                {
                    Physics.autoSimulation = false;
                    Time.timeScale         = 1.0f * (float)hyperSpeed;

                    TickPhase(Time.fixedDeltaTime);

                    for (int h = 0; h < hyperSpeed; ++h)
                    {
                        for (int i = 0; i < trainees.Count; ++i)
                        {
                            var trainee = trainees[i];
                            var result  = results[i];
                            var dt      = Time.fixedDeltaTime;
                            var job     = PrepareAndQueueJobStep(trainee, dt);

                            stepJobs.Add(job.Schedule());

                            if ((i % 8) == 0)
                            {
                                JobHandle.ScheduleBatchedJobs();
                            }
                        }

                        for (int i = 0; i < trainees.Count; ++i)
                        {
                            var trainee = trainees[i];
                            var handle  = stepJobs[i];

                            handle.Complete();

                            AfterTrainingJob(trainee, Time.fixedDeltaTime);
                        }

                        stepJobs.Clear();

                        Physics.Simulate(Time.fixedDeltaTime);
                    }

                    counter += Time.fixedDeltaTime * Time.timeScale;

                    yield return(null);
                }
                else
                {
                    Physics.autoSimulation = true;
                    Time.timeScale         = 1.0f;

                    TickPhase(Time.fixedDeltaTime);

                    UnityEngine.Profiling.Profiler.BeginSample("QueueTrainingJobs");

                    for (int i = 0; i < trainees.Count; ++i)
                    {
                        var trainee = trainees[i];
                        var result  = results[i];
                        var job     = PrepareAndQueueJobStep(trainee, Time.fixedDeltaTime);

                        stepJobs.Add(job.Schedule());

                        if ((i % 8) == 0)
                        {
                            JobHandle.ScheduleBatchedJobs();
                        }
                    }

                    UnityEngine.Profiling.Profiler.EndSample();

                    UnityEngine.Profiling.Profiler.BeginSample("AfterTrainingJobs");

                    for (int i = 0; i < trainees.Count; ++i)
                    {
                        var trainee = trainees[i];
                        var handle  = stepJobs[i];

                        handle.Complete();

                        AfterTrainingJob(trainee, Time.fixedDeltaTime);
                    }

                    stepJobs.Clear();

                    UnityEngine.Profiling.Profiler.EndSample();

                    counter += Time.fixedDeltaTime;

                    yield return(new WaitForFixedUpdate());
                }
            }

            for (int i = 0; i < trainees.Count; ++i)
            {
                var trainee = trainees[i];
                var result  = results[i];

                CalculateResult(trainee, result);
            }

            results.Sort(CompareResults);

            var winner = results[0];
            if (winner.score < bestScore)
            {
                Debug.LogFormat("NeuralTrainerEvolution_Follow.RunTrainingLoop(): cycle {0} +++ new winner: {1}: score: {2}", cycle, winner.trainee.name, winner.score);

                bestScore   = winner.score;
                bestTrainee = winner.trainee;

                bestScore += 0.1f;
            }
            else
            {
                Debug.LogFormat("NeuralTrainerEvolution_Follow.RunTrainingLoop(): cycle {0} === old winner: {1}: score: {2}", cycle, bestTrainee.name, bestScore);

                bestScore += 1.0f;
            }

            for (int i = 0; i < trainees.Count; ++i)
            {
                var seed = (uint)(Time.frameCount * (i + 1));

                if (trainees[i] == bestTrainee)
                {
                    continue;
                }

                var jobMutate = trainees[i].QueueJobMutate(seed, mutateRate);
                var jobEvolve = trainees[i].QueueJobEvolve(seed, bestTrainee, evolveRate);

                var jobHandleMutate = jobMutate.Schedule();
                var jobHandleEvolve = jobEvolve.Schedule(jobHandleMutate);

                mutateJobs.Add(jobHandleMutate);
                evolveJobs.Add(jobHandleEvolve);

                if ((i % 8) == 0)
                {
                    JobHandle.ScheduleBatchedJobs();
                }
            }

            // this shouldnt be needed but getting dependency error
            for (int i = 0; i < mutateJobs.Count; ++i)
            {
                mutateJobs[i].Complete();
            }
            mutateJobs.Clear();

            for (int i = 0; i < evolveJobs.Count; ++i)
            {
                evolveJobs[i].Complete();
            }
            evolveJobs.Clear();

            for (int i = 0; i < trainees.Count; ++i)
            {
                trainees[i].cachedRigidbody.isKinematic = true;
            }
            yield return(null);

            for (int i = 0; i < trainees.Count; ++i)
            {
                trainees[i].cachedRigidbody.isKinematic = false;
            }

            cycle++;

            yield return(null);
        }
    }