오늘은 목표물을 향해서 바닥에 떨어지지 않고 추적하는 교육을 시키도록 하겠습니다.


우선 기본적인 환경을 만들기 위한 세팅을 합니다. (저번 포스트에서 봤듯이 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);
    }
 
}
 
 
 

cs



작성한 스크립트들을 각각 이름에 맞게 배치한다. 

에이전트 스크립트의 경우 inspector창에서 추가 작업이 필요하다. 
1. brain게임오브젝트에 스크립트를 넣은 후에 Brain에 끌어다 놓는다. 
2. target으로 설정한 오브젝트를 target으로 가져온다. 




brain 스크립트를 ml-agent폴더에서 가져와서 
brain 게임 오브젝트에 넣어주고 
아래와 같이 세팅값을 맞춘다. 


이 후에 테스트를 위하여 player를 사용해보자

player를 사용하기 위해서는 input값에 대한 키 세팅이 필요하다. 


brain에서 brain mode를 player로 설정하고 아래와 같이 세팅을 맞춘다.


그러면 이제 플레이를 할 수 있다. 


본인은 개인적으로 obstacle을 만들어서 obstacle에도 부정적 보상을 주어 obstacle을 피하면서 target을 추적하도록 교육시켰다. 그런데 실질적으로 교육성과는 시간이 지남에 따라서 별로 크게 변화하지 않았다... 보상값을 더 조절해야 될 듯.... 하지만, 미세하게 좀 더 빨리 찾는 것 같기도 하였다. 아래 영상은 brain mode를 external로 둔 것이다. 

사용하는 방법은 이전 포스팅에 기록되어있다. 


보다시피 교육에 눈에 띄는 성과가 없이 계속 뒤죽박죽하다. 



결론. 머신러닝은 자동적인 움직임 관찰이 흥미로움. 

생각보다 원하는 목표를 위해서는 보상체계에 대한 정교한 가이드가 필요한 듯. 





Posted by 도이(doi)
,