ML-Agents란?
Machine Learning Agents로 말 그대로 머신러닝을 시키는 API라고 이해하고 있음
Python을 사용, Unity에 접목 가능
진행과정
<시작>
- 새로운 Unity3D 프로젝트(RollerBall00)를 만든다.
- 유니티 패키지를 열어서 ML-Agents를 추가한다.
- Window -> Package Manager -> ML Agents(당시 실험 버전 1.0.6) Install
<오브젝트 환경 설정>
- SampleScene의 이름을 RollerBallA로 변경한다.
- Scene의 이름이 중요한가 확인 중
- 새 GameObject : TrainingArea 추가한다.
- TrainingArea 오브젝트 밑에 바닥을 추가한다.
- 3D Object > Plane
- 이름은 Floor
- 한 번 Reset
- TrainingArea 오브젝트 밑에 타겟이 될 Cube를 추가한다.
- 3D Object > Cube
- 이름은 Target
- 한 번 Reset하고 Position을 변경 : (3, 0.5, 3)
- TrainingArea 오브젝트 밑에 장애물이 될 Cube를 추가한다.
- 3D Object > Cube
- 이름은 Hurdle
- 한 번 Reset하고 Position을 변경 : (1.5, 0.5, 1.5)
- 장애물 테스트 중
- TrainingArea 오브젝트 밑에 이제 지가 알아서 학습할 녀석인 Sphere를 추가한다.
- 3D Object > Sphere
- 이름은 RollerAgent
- 한번 Reset하고 Position을 변경 : (0, 0.5, 0)
- Component 추가 : Rigidbody
<스크립트 설정>
- Scripts 폴더를 만들고 RollerAgent 스크립트를 그 속에 만든다.
- 이것을 구인 RollerAgent에 부착
- RollerAgent 편집
-
using System.Collections; using System.Collections.Generic; using UnityEngine; // : MLAgent 사용 using Unity.MLAgents; using Unity.MLAgents.Sensors; public class RollerAgent : Agent { // : 1 Start Rigidbody rBody; void Start() { rBody = this.GetComponent<Rigidbody>(); } // : Episode가 시작할 때마다 상황 변경 public Transform target; public Transform hurdle; public override void OnEpisodeBegin() { // : 떨어졌을 때 속도 및 위치 초기화 if(this.transform.localPosition.y < 0) { this.rBody.angularVelocity = Vector3.zero; this.rBody.velocity = Vector3.zero; this.transform.localPosition = new Vector3(0, 0.5f, 0); } // : 타깃 위치 변경 target.localPosition = this.GetRandomPosition(this.transform.localPosition); // : 장애물 위치 변경 hurdle.localPosition = this.GetRandomPosition(this.transform.localPosition); } // : 관찰 스테이터스 결정 public override void CollectObservations(VectorSensor sensor) { // :: 포지션 sensor.AddObservation(this.transform.localPosition); sensor.AddObservation(this.target.localPosition); sensor.AddObservation(this.hurdle.localPosition); // :: 속도 sensor.AddObservation(rBody.velocity.x); sensor.AddObservation(rBody.velocity.z); } // : 행동 에피소드 결정 public float forceMultiplier = 10; public override void OnActionReceived(float[] vectorAction) { // :: 행동할 액션은 2가지 x 이동과 z 이동 Vector3 controlSignal = Vector3.zero; controlSignal.x = vectorAction[0]; controlSignal.z = vectorAction[1]; rBody.AddForce(controlSignal * this.forceMultiplier); // :: 거리 측정 float distanceToTarget = Vector3.Distance(this.transform.localPosition, this.target.localPosition); float distanceToHurdle = Vector3.Distance(this.transform.localPosition, this.hurdle.localPosition); // : 보상 if(distanceToTarget < 1.42f) { Debug.Log("+1"); this.SetReward(1.0f); this.EndEpisode(); } // : 벌 else if(distanceToHurdle < 1.42f) { Debug.Log("-1"); this.SetReward(-0.5f); this.EndEpisode(); } // : 떨어졌을 때 else if(this.transform.localPosition.y < 0) { this.EndEpisode(); } } // : 키보드 조작 public override void Heuristic(float[] actionsOut) { actionsOut[0] = Input.GetAxis("Horizontal"); actionsOut[1] = Input.GetAxis("Vertical"); } // : Get private Vector3 GetRandomPosition(Vector3 exceptPosition) { // :: Set Vector3 position = new Vector3(Random.value * 8 - 4, 0.5f, Random.value * 8 - 4); // :: 중복이 발생하지 않도록 float distance = Vector3.Distance(exceptPosition, position); while(distance <= 1f) { position = new Vector3(Random.value * 8 - 4, 0.5f, Random.value * 8 - 4); distance = Vector3.Distance(exceptPosition, position); } return position; } }
-
- RollerAgent 스크립트에 Target과 Hurdle 오브젝트를 연결
- RollerAgent 오브젝트에 Add Component로 Decision Requester 추가
- Decision Period는 10으로 설정
- RollerAgent 오브젝트에 Add Component로 Behavior Parameter 추가
- Behavior Name은 RollerBall
- Vector Observation > Space Size 는 11로 변경
- Vector Action > Space Type을 Continuous로 변경
- Vector Action > Space Size는 2로 변경
<트레이닝 설정>
- Python, pip3, MLAgents 등의 설치 : 생략(나중에 기회되면 추가)
- MLAgents 클로닝(github.com/Unity-Technologies/ml-agents)
- MLAgents 의 config 폴더 밑에 rollerball_config.yaml 생성
- UTF-8 with BOM으로 되어 있으면 UTF-8로 변경
-
behaviors: RollerBall: trainer_type: ppo hyperparameters: batch_size: 10 buffer_size: 100 learning_rate: 3.0e-4 beta: 5.0e-4 epsilon: 0.2 lambd: 0.99 num_epoch: 3 learning_rate_schedule: linear network_settings: normalize: false hidden_units: 128 num_layers: 2 reward_signals: extrinsic: gamma: 0.99 strength: 1.0 max_steps: 500000 time_horizon: 64 summary_freq: 10000
- 터미널로 해당 config 폴더로 가서 MLAgents 실행
- 명령어 : mlagents-learn rollerabll_config.yaml --run-id=firstRollerBall00
- 2번째 테스트부터는 ID 변경하면 됨
- 배우는 것을 본다
- 결과물(Result 폴더에 있는 것)을 유니티에 넣는다.
- RollerBall.onmx
- RollerAgent 오브젝트의 Behavior Parameters의 Model에 해당 RollerBall.onmx를 추가
- 결과 확인(30만번 돌렸을 때)
'AI' 카테고리의 다른 글
[freeCodeCamp] ChatGPT 강좌 - OpenAI API를 사용하여 다섯 가지 프로젝트를 만들기 (0) | 2023.04.23 |
---|---|
[인공지능 용어] 할루시네이션(Hallucination) (0) | 2023.04.06 |