on the blue plateau

카테고리 없음

ML-Agents 3D Ball 예제 튜토리얼

swu 2026. 5. 25. 23:57

https://docs.unity3d.com/Packages/com.unity.ml-agents@4.0/manual/Sample.html

* Unity 공식문서를 참고했습니다. 

1. 프로젝트 개요 및 튜토리얼 소개

현재 졸업 프로젝트로 플레이어의 심리 데이터를 실시간으로 분석해 공포도를 동적으로 조절하는 AI 적응형 공포 게임 'Friendly'를 개발 중입니다. 이 시스템을 구현하려면 유니티 환경 내에서 에이전트(Agent)가 상황을 인지하고 최적의 행동을 하도록 강화학습을 시켜야 합니다.

본 포스트에서는 Unity ML-Agents 4.0.0 (Unity 6 환경)을 로컬에 세팅하고, 공식 튜토리얼인 '3DBall' 예제를 훈련하여 모델을 추출해 보겠습니다.

 

 

2. 튜토리얼 (1): ML-Agents 설치 

안정적인 강화학습 환경 구성을 위해 공식 문서를 바탕으로 단계별 세팅을 진행했습니다. (진행 환경: Windows)

공식 문서: https://docs.unity3d.com/Packages/com.unity.ml-agents@4.0/manual/Installation.html  

Step 2.1: Unity 6 및 Python 가상환경 세팅

최신 ML-Agents 4.0.0을 사용하기 위해 Unity 6000.0.62f1 LTS 버전을 Unity Hub를 통해 설치했습니다. 이후 패키지 충돌을 막기 위해 Conda를 활용하여 권장 파이썬 버전(3.10.12)으로 독립된 가상환경을 구축했습니다.

보니까 그새 업데이트 되어 6000.4.8f1이 release 되었더군...  하지만 내 갈 길을 감.

 

# mlagents라는 이름의 가상환경 생성 및 활성화
conda create -n mlagents python=3.10.12 
conda activate mlagents

(기존 시스템의 파이썬 버전과 무관하게, 이 가상환경ㅡmlagents, 제가 그렇게 가상환경 이름을 지었습니다.ㅡ안에서는 3.10.12 버전이 격리되어 실행됨.)

 

Step 2.2: ML-Agents 리포지토리 Clone 및 패키지 설치

튜토리얼 샘플 환경(3DBall 등)을 직접 뜯어보고 커스텀하기 위해 공식 Git Repository를 로컬에 Clone 하는 방식을 선택했습니다.

git clone --branch release_23 https://github.com/Unity-Technologies/ml-agents.git

 

Step 2.3: PyTorch 및 ML-Agents 파이썬 패키지 빌드

클론한 디렉터리로 이동한 후, 로컬 GPU 환경에 맞는 PyTorch를 설치하고 ML-Agents가 파이썬 환경에서 동작할 수 있도록 패키지를 설치(빌드)합니다.

 

# PyTorch 설치 (본인 시스템의 CUDA 버전에 맞춰 설치)
pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu128

# ML-Agents 관련 패키지 로컬 설치
python -m pip install ./ml-agents-envs 
python -m pip install ./ml-agents

클론한 ml-agents repo가 있는 경로로 가서 명령어 pip list를 쳤을 때 torch, mlagents, mlagents-envs가 보인다면 환경 구축이 끝났습니다.

 

 

3. 튜토리얼 (2): 3DBall 예제 실행 및 핵심 코드 분석

환경 세팅을 마쳤으니, 앞서 클론한 폴더 내의 3DBall 예제를 Unity에서 열어보겠습니다. (Scenes 폴더)

경로: ml-agents/Project/Assets/ML-Agents/Examples/3DBall/Scenes

 

이 예제는 3D 큐브(Agent) 위에서 공이 떨어지지 않도록 큐브가 스스로 균형을 잡는 학습 환경입니다. 

 

전 Unity 6를 쓰고 예제 scene의 버전은 2022.3.62f3이지만 무사히 잘 열립니다. 

 

냅다 플레이를 눌러보면 큐브들이 살짝씩 움직이며 공을 안 떨어뜨리려고 노력하는 모습을 볼 수 있습니다. 

 

큐브가 12개나 있는 이유는 1 큐브 1 agent로 모두 동일한 행동을 하며 병렬로 학습하여 학습 시간을 단축하기 위해서라고 합니다. 

 

▶ 보상 처리 코드

강화학습의 핵심은 '보상(Reward)'입니다. 상위 시스템(Unity 게임 엔진)의 물리 엔진과 ML-Agents가 어떻게 통합되어 있는지 C# 핵심 코드를 통해 살펴보겠습니다.

// Agent 스크립트 내부 보상 로직
public override void OnActionReceived(ActionBuffers actionBuffers)
{
    // ... (큐브의 기울기를 조절하는 액션 로직) ...

    // 매 스텝마다 공을 떨어뜨리지 않고 유지하면 미세한 보상을 지속적으로 제공 (+)
    SetReward(0.1f); 
}

public void OnCollisionEnter(Collision collision)
{
    // 상위 시스템(Unity)의 물리 충돌 감지
    // 공이 바닥(ground 태그)에 닿으면 에피소드 실패 처리 및 패널티 부여 (-)
    if (collision.gameObject.CompareTag("ground"))
    {
        SetReward(-1.0f);
        EndEpisode();
    }
}

큐브 agent가 공을 떨어뜨리면 패널티(-1.0f)를 주고 균형을 잘 유지하면 보상(+0.1f)을 주고 있습니다. 

페널티가 보상보다 훨씬 강하네요.

 

 

4. 모델 학습 및 적용 방법

먼저 사전학습된 모델이 Agent 오브젝트 어디에 붙어있는지 보고 어떻게 적용하는지 보겠습니다.

3D Ball 오브젝트 프리팹에 Agent라는 오브젝트가 붙어있습니다. 

 

사전 학습된 모델을 3DBall의 Prefab에서 적용해주면 씬에 있는 모든 큐브에 적용이 되겠죠 

TFModels 폴더에 있는 모델을 드래그해서 Agent Inspector의 Behavior Parameter 스크립트 컴포넌트의 Model에 얹으면 됩니다.

Inference Device는 Burst로 하면 CPU를 쓰겠다는 뜻

 

 

아까 냅다 플레이버튼 눌렀을 때랑 비슷한 장면이 나오긴 합니다.

 

 

 

Step 4.1: PPO 알고리즘을 통한 학습 시작

이제 드디어 직접 학습 !! 

 

커맨드 창을 열고 0탄에서 clone했던 repo 파일로 이동한 후 

conda activate mlagents로 저번에 만든 가상환경을 활성화합니다. (명령어 pip list 로 위에서 세팅한 가상환경이 맞는지 확인해볼 수 있습니다. torch, mlagents, mlagents-envs 가 있을 것입니다.)

 

그리고 학습을 위해 아래 코드를 입력합니다. 

mlagents-learn config/ppo/3DBall.yaml --run-id=first3DBallRun

 

 

▶ config/ppo/3DBall.yaml 파일

명령어에 포함된 이 .yaml 파일은 모델 학습에 필요한 하이퍼파라미터(Hyperparameters)가 담긴 설정 파일입니다. 쉽게 말해 에이전트를 어떻게 훈련시킬지를 세밀하게 지정해 둔 학습 지침서입니다. 

이 파일을 열어보면 다음과 같은 값들이 설정되어 있습니다. 저는 VS Code로 열었습니다.

  • max_steps: 총 몇 번의 스텝(행동)까지 학습을 진행할 것인가? (예: 50만 번)
  • learning_rate: 한 번에 얼만큼의 크기로 지식을 업데이트할 것인가? (학습률)
  • batch_size / buffer_size: 한 번의 훈련에 사용할 데이터의 묶음 크기 

이외에도 beta 등 많은 하이퍼파라미터가 있고 또 memory같은 기능을 추가할 수 있어 원하는 모델을 설계할 수 있습니다. 

제 졸업 프로젝트를 진행할 때는 게임 환경과 목적에 맞춰 이 YAML 파일의 수치들을 직접 조작하며 최적의 모델을 찾아내고 있습니다.

 

 

와 됐다!

 

명령어 입력 후 유니티 에디터로 들어가서 play 버튼을 누르면 모델학습이 됩니다. 잘 모르고 그냥 가만히 있다가 30초~1분 정도 지나면 내부적으로 timeout같은 게 됩니다.. 

 

run-id만 바꿔서 두번째 시도를 하거나 --resume으로 재개할 수 있습니다. 

mlagents-learn config/ppo/3DBall.yaml --run-id=second3DBallRun
mlagents-learn config/ppo/3DBall.yaml --run-id=first3DBallRun --resume

 

 

 

커맨더 창을 보면 Step이 2000씩 증가하며 학습을 진행하고 있습니다. Max Step까지 학습이 끝나면 .onnx 모델이 추출됩니다. 

와 신기해!!!!!

 

 처음에는 공이 엄청 빨리 떨어져서 요란스럽더니 몇 분 지나니 공이 큐브 위에서 잘 버팁니다.

 

 

 

5. 학습 결과 시각화 및 시스템 통합

Ctrl+C나 유니티에서 플레이를 중단하여 학습을 그만하고 커맨드창에 아래 명령어를 입력했습니다.

(근데 학습 중에서도 다른 커맨더 창 열어서 이 명령어 치면 현재 학습 현황을 실시간으로 볼 수 있습니다.)

tensorboard --logdir results

tensorboard로 학습 과정만 보면 돼서 tensorflow를 설치할 필요는 없습니다. 

http://localhost:6006/ 들어가서 그래프 확인을 했습니다. 

 

Smoothing weight는 전체적인 추세만 보라고 그래프를 완만하게 만드는 필터 강도다. 1에 가까울수록 그래프가 둥글어지는 걸 볼 수 있다. 

 

대표적인 2개의 그래프를 보겠습니다. 

 

Environment/Cumulative Reward

에피소드당 얻은 총 보상입니다. 그래프가 명확한 우상향 곡선을 그리는 것을 통해 모델이 정상적으로 보상을 최대화하고 있음을 확인했습니다. 

 

공이 12개이므로 평균을 내서 그래프에 표시한다.

 

 

Environment/Episode Length

Episode length는 생존 기간이라고 생각하면 됩니다. 공이 큐브 위에서 안 떨어지고 버티는 시간. 

처음에는 아무것도 몰라서 떨어뜨렸을 테니 episode length도 작고 cumulative reward도 작습니다. 후에는 공이 균형 잡는 시간이 늘어나면서 우상향합니다. 

 

 

6. Unity에 모델 적용하기

지금까지 모델을 Unity 환경에서 학습시키기만 했을 뿐 모델을 뽑아내지 않았습니다.

이렇게 처음부터 학습시킨 모델을 추출하자. 

 

 

 

훈련된 모델은 results/<run-identifier>/<behavior_name>.onnx 경로에 있다고 합니다.

3DBall.onnx 파일을 라이브러리에서 바로 유니티창의 TFModels 폴더에 드래그하여 넣고

아까처럼 3DBall Prefab에서 모델을 드래그하여 적용하면 됩니다. 

(Prefab에서 적용하는 이유: 3DBall 프리팹의 설정을 수정하면 Hierarchy창에 있는 모든 12개 3DBall에 적용돼서 편하다) 

원래 있던 모델 3DBall과 모델이름이 겹쳐서 3DBalltest로 모델 이름을 수정했습니다

 

잘된다~~~