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)); } }
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; }
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()); }
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); }
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]; } }
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); } }
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); } }