오늘은 목표물을 향해서 바닥에 떨어지지 않고 추적하는 교육을 시키도록 하겠습니다.
우선 기본적인 환경을 만들기 위한 세팅을 합니다. (저번 포스트에서 봤듯이 ML-Agent폴더를 가져옵니다.
패키지도 가져옵니다.)
1. 빈 오브젝트를 만들어주시고 이름은 Academy라고 짓습니다.
2. 빈 오브젝트를 하나 더 만들고 Brain이라고 이름을 지은 후에 Academy에 child시킵니다.
3. floor을 만듭니다. plane 오브젝트로 만들며 위치와 로테이션 값을 모두 0으로 하시고 스케일은 1로 합니다.(스케일은 변경하면 안됩니다. 환경을 고정적으로 에이전트의 기능만 사용할 것이기 때문.)
4. target도 만들어줍니다. target의 크기나 위치는 상관 없습니다.
5. 마지막으로 agent를 만들어줍니다.
agent는 sphere 게임오브젝트로 만들고 rigidbody component를 추가해줍니다.
스크립트를 만듭니다.
1. academy script
2. agent script
1. academy script
1-1. using mlagent; 추가
1-2 academy 상속
1 2 3 4 5 6 7 8 9 | using System.Collections; using System.Collections.Generic; using UnityEngine; using MLAgents; public class RollerAcademy : Academy { } | cs |
2. agent script
2-1. reset 값 설정
2-2. 환경 관찰
모든 값을 /5로 나누어주는 이유는 현재 환경 plane의 칸 수가 10칸이기 때문에
5로 나누어주는 것이다. (normalizing)
2-3. 리워드
2-4. brain으로부터 지시 받는 함수
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | using System.Collections; using System.Collections.Generic; using UnityEngine; using MLAgents; public class RollerAgent : Agent { Rigidbody rBody; private void Start() { rBody = GetComponent<Rigidbody>(); } public Transform Target; //에이전트가 리셋될 때 초기값 public override void AgentReset() { if(this.transform.position.y < -1.0) { //agent가 떨어지면 this.transform.position = Vector3.zero; this.rBody.angularVelocity = Vector3.zero; this.rBody.velocity = Vector3.zero; } else { //target을 새로운 지점으로 이동 Target.position = new Vector3(Random.value * 8 - 4, 0.5f, Random.value * 8 - 4); } } //에이전트가 환경을 관찰하는 함수 public override void CollectObservations() { //타겟과 에이전트의 상대적 위치 Vector3 relativePosition = Target.position - this.transform.position; //상대적 위치 AddVectorObs(relativePosition.x / 5); AddVectorObs(relativePosition.z / 5); //바닥과 에이전트 사이의 거리 AddVectorObs((this.transform.position.x + 5) / 5); AddVectorObs((this.transform.position.x - 5) / 5); AddVectorObs((this.transform.position.z + 5) / 5); AddVectorObs((this.transform.position.z - 5) / 5); //에이전트의 속도 AddVectorObs(rBody.velocity.x / 5); AddVectorObs(rBody.velocity.z / 5); } //brain으로부터 지시를 받는 함수 public float speed = 10; private float previousDistance = float.MaxValue; public override void AgentAction(float[] vectorAction, string textAction) { // Rewards float distanceToTarget = Vector3.Distance(this.transform.position, Target.position); // Reached target if (distanceToTarget < 1.42f) { AddReward(1.0f); Done(); } // Time penalty AddReward(-0.05f); ₩ if(_collision.obs == true) { AddReward(-0.05f); } // Fell off platform if (this.transform.position.y < -1.0) { AddReward(-1.0f); Done(); } // Actions, size = 2 // brain으로부터 받는 지시를 수행하는 Vector3 controlSignal = Vector3.zero; controlSignal.x = vectorAction[0]; controlSignal.z = vectorAction[1]; rBody.AddForce(controlSignal * speed); } } |
이 후에 테스트를 위하여 player를 사용해보자
player를 사용하기 위해서는 input값에 대한 키 세팅이 필요하다.
brain에서 brain mode를 player로 설정하고 아래와 같이 세팅을 맞춘다.
그러면 이제 플레이를 할 수 있다.
본인은 개인적으로 obstacle을 만들어서 obstacle에도 부정적 보상을 주어 obstacle을 피하면서 target을 추적하도록 교육시켰다. 그런데 실질적으로 교육성과는 시간이 지남에 따라서 별로 크게 변화하지 않았다... 보상값을 더 조절해야 될 듯.... 하지만, 미세하게 좀 더 빨리 찾는 것 같기도 하였다. 아래 영상은 brain mode를 external로 둔 것이다.
사용하는 방법은 이전 포스팅에 기록되어있다.
보다시피 교육에 눈에 띄는 성과가 없이 계속 뒤죽박죽하다.
결론. 머신러닝은 자동적인 움직임 관찰이 흥미로움.
생각보다 원하는 목표를 위해서는 보상체계에 대한 정교한 가이드가 필요한 듯.
'mlAgent' 카테고리의 다른 글
3d ball 환경 분석하기 + tensorBoard사용법 (0) | 2018.11.14 |
---|---|
ML-Agents Toolkit 개요 (0) | 2018.11.11 |
유니티 mlAgent 설치하기 (version. v0.5 ) - 맥북 (0) | 2018.11.08 |