Unity/AI인공지능

0517_ ML-Agent 간단한 씬 해보기

minquu 2021. 5. 17. 17:03
반응형

 

유니티에서 ML 에이젼트를 패키지 매니저에서 넣어준다.

 

ML에이전트 깃 허브 
https://github.com/Unity-Technologies/ml-agents
릴리즈 17를 다운받는다.

 

 

 

----

 

유니티 워크스페이스 안에다가 풀어 준다.

 

 

 

---

 

파이썬을 설치해준다.

 

파이썬을 설치하는 건 쌩파이썬과 아나콘다로 설치해주는 방법이있다.

 

아나콘다로한다.

 

anaconda 를 검색해준다.

 

텐서프로가 파이선 3.6를 지원하기 떄문에,  3.6를 다운받아야한다.

 

https://repo.anaconda.com/archive/

 

Index of /

 

repo.anaconda.com

 

아나콘다 3 2018.12 가 파이선 3.6를 쓰는 것

 

3.7도 괜찮아서

 

 

 

설치해준다.

 

-----

 

설치되는 동안

 

유니티
파일 - 오픈 프로젝트 - 추가 - 릴리즈 17 - 프로젝트 열기
기존 프로젝트 닫고 / 허브에서 다시 열기

 

테스트 씬 열어서 테스트해보기

 

----

아나콘다 설치후

아나콘다.Prompt

열어서 현재 버전 찍어보기

 

----

ML-Agent 시작 가이드

 

https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Getting-Started.md

 

Unity-Technologies/ml-agents

Unity Machine Learning Agents Toolkit. Contribute to Unity-Technologies/ml-agents development by creating an account on GitHub.

github.com

 

-----

 

https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Learning-Environment-Create-New.md#overview

 

Unity-Technologies/ml-agents

Unity Machine Learning Agents Toolkit. Contribute to Unity-Technologies/ml-agents development by creating an account on GitHub.

github.com

 

새로운 환경에서 만들기 

 

이 도큐먼터리에서 중요한것 

 

다큐 먼터리를 보면서 하나씩 조립해가는 걸 봐야한다.

 

OnEpisodeBegin /// API부터 찾아보기

https://docs.unity3d.com/Packages/com.unity.ml-agents@1.0/api/Unity.MLAgents.Agent.html

 

Class Agent | ML Agents | 1.0.7

Class Agent An agent is an actor that can observe its environment, decide on the best course of action using those observations, and execute those actions within the environment. Inherited Members UnityEngine.Component.guiText UnityEngine.Component.guiElem

docs.unity3d.com

 

Agent를 상속 받는다.

 

public override void OnEpisodeBegin() 이부분은 초기화를 시키는 부분

 

 

 

0일때 초기화를 시켜준다.

 

 

에이전트가 가지고있는 특징을 주는것,

 

 

파이썬에서 받은 걸 하는 걸

 

 

보상을 받는 부분, 끝나면 Enf에피스도ㅡ

 

 

 

 

 

 

Decision Reauester 는 우리가 꼭 붙여줘야하는 부분이다. 

 

 

---

 

제작.

 

플랜을 만들고, 큐브 (타켓), 스피어 (어젠트)와 RollerAgent 스크립터를 만들어준다

 

 

 

 

---

 

RollerAgent 스크립터

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;

public class RollerAgent : Agent
{
    Rigidbody rBody;
    // Start is called before the first frame update
    void Start()
    {
        this.rBody = GetComponent<Rigidbody>();
    }

    public Transform Target;
    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 = new Vector3(Random.value * 8 - 4,
                                            0.5f,
                                            Random.value * 8 - 4);
    }

}

using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;

 

public class RollerAgent : Agent  

Agent 를 상속받게 만들어준다.

 

리지드 바디를 받게한다.

 

타겟(목표)을 퍼블릭으로 뚫어준다.

에피소드가 시작 할때,

만약 어젠트가 떨어져있으면

초기값(위치)으로 위치를 하게 해준다.

그리고 타겟(목표)의 위치는 랜덤하게 위치를 하게 해준다.

 

 

----

 

 public override void CollectObservations(VectorSensor sensor)
    {
        // Target and Agent positions
        sensor.AddObservation(Target.localPosition);
        sensor.AddObservation(this.transform.localPosition);

        // Agent velocity
        sensor.AddObservation(rBody.velocity.x);
        sensor.AddObservation(rBody.velocity.z);
    }

 

CollectObservations( ) // 관련된 API

 

https://docs.unity3d.com/Packages/com.unity.ml-agents@1.0/api/Unity.MLAgents.Agent.html#Unity_MLAgents_Agent_CollectObservations_Unity_MLAgents_Sensors_VectorSensor_

 

Class Agent | ML Agents | 1.0.7

Class Agent An agent is an actor that can observe its environment, decide on the best course of action using those observations, and execute those actions within the environment. Inherited Members UnityEngine.Component.guiText UnityEngine.Component.guiElem

docs.unity3d.com

환경 관찰하는 것

 

현재 타겟의 포지션과 에이전트의 포지션을 관찰하게 만들어주는 것 (넘기는것)

또 움직일때 속도 관찰하게한다.

 

 

보낼때 각각 성분을 쪼개서 보낸다.

 

 

 

 

 

-----

 

액션을 취하고, 보상을 준다

 

 

액션은 배열로 들어온다.

 

리워드 부분

타겟과 거리를 계산하고, 점수를 주고 끝내준다.

 

 

떨어졌을때는  끝낸다.

 

 

ActionBuffers가 파이썬을 받아서 주는 것이다.

 

 

행동은 Continuous 같이 종류가 있다. 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;

public class RollerAgent : Agent
{
    public Rigidbody rBody;
    public Transform Target;
    // Start is called before the first frame update
    void Start()
    {
        this.rBody = GetComponent<Rigidbody>();
    }

    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 = new Vector3(Random.value * 8 - 4,
                                            0.5f,
                                            Random.value * 8 - 4);
    }

    public override void CollectObservations(VectorSensor sensor)
    {
        // Target and Agent positions
        sensor.AddObservation(Target.localPosition);
        sensor.AddObservation(this.transform.localPosition);

        // Agent velocity
        sensor.AddObservation(rBody.velocity.x);
        sensor.AddObservation(rBody.velocity.z);
    }

    //행동을 한다. 보상을 받는다.
    public override void OnActionReceived(ActionBuffers actionBuffers)
    {

        //파이썬 API로부터 전달받은 값으로 행동을 함
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = actionBuffers.ContinuousActions[0];
        controlSignal.z = actionBuffers.ContinuousActions[1];
        this.rBody.AddForce(controlSignal * 10f);

        // 보상
        float distanceToTarget = Vector3.Distance(this.transform.localPosition, Target.localPosition);

        // 타겟에 닿으면
        if (distanceToTarget < 1.0f)
        {
            SetReward(1.0f);
            EndEpisode();
        }

        // 떨어지면
        else if (this.transform.localPosition.y < 0)
        {
            EndEpisode();
        }

    }


}

 

 

 

 

반드시 이름은 지금은 RollerBall (나중에 설정 파일과 같게하면됌)

 

 

네임

스페이스 사이즈

컨티뉴어 액션

 세 가지 만줘야한다.

 

 

주기?

 

 

---

 

비헤이비어 파라미터에 

 

비헤이버 타입을 휴리스틱 온리로 하면 사용자가 넣은 키를 이용해서 움직일 수있다.

 

인퍼런스 디바이스 CPU로 해주기 

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;

public class RollerAgent : Agent
{
    public Rigidbody rBody;
    public Transform Target;
    // Start is called before the first frame update
    void Start()
    {
        this.rBody = GetComponent<Rigidbody>();
    }

    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 = new Vector3(Random.value * 8 - 4,
                                            0.5f,
                                            Random.value * 8 - 4);
    }

    public override void CollectObservations(VectorSensor sensor)
    {
        // Target and Agent positions
        sensor.AddObservation(Target.localPosition);
        sensor.AddObservation(this.transform.localPosition);

        // Agent velocity
        sensor.AddObservation(rBody.velocity.x);
        sensor.AddObservation(rBody.velocity.z);
    }

    //행동을 한다. 보상을 받는다.
    public override void OnActionReceived(ActionBuffers actionBuffers)
    {

        //파이썬 API로부터 전달받은 값으로 행동을 함
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = actionBuffers.ContinuousActions[0];
        controlSignal.z = actionBuffers.ContinuousActions[1];
        this.rBody.AddForce(controlSignal * 10f);

        // 보상
        float distanceToTarget = Vector3.Distance(this.transform.localPosition, Target.localPosition);

        // 타겟에 닿으면
        if (distanceToTarget < 1.42f)
        {
            SetReward(1.0f);
            EndEpisode();
        }

        // 떨어지면
        else if (this.transform.localPosition.y < 0)
        {
            EndEpisode();
        }

    }

    public override void Heuristic(in ActionBuffers actionsOut)
    {
        var continuousActionsOut = actionsOut.ContinuousActions;
        continuousActionsOut[0] = Input.GetAxis("Horizontal");
        continuousActionsOut[1] = Input.GetAxis("Vertical");
    }


}

 

반응형