인프런 커뮤니티 질문&답변

작성자 없음

작성자 정보가 삭제된 글입니다.

유니티 머신러닝 에이전트 완전정복 (기초편)

강의 마무리

배웠던 내용을 기반으로 match3 인공지능으로 플레이 하는 걸 만들고 있는데.. 질문이 있습니다.

24.07.16 23:15 작성

·

137

·

수정됨

0

match3 게임을 agent가 플레이 하게 하려는 목적으로 시작 했습니다.

 

과거 match3 게임 개발해 논게 있어서 AbstractBoard 못쓰고 agent 학습 작업을 하였습니다.

mlagent Release 21 버젼을 사용했습니다.

먼저 퍼즐판은 8*7이고 블럭은 5색깔을 사용한다고 정의 했습니다.

public class Match3MLAgentsBoard : Agent 클레스를 정의 하고

유니티 mlagnet match3 샘플을 참고해서 8*7 퍼즐판을 색깔별로 있으면 1 없으면 0을 넣는 소스 입니다.

public override void CollectObservations(VectorSensor sensor)
{
    MapBoardData mapBoardData = gameMain.IngameData.CurBoardData;
    MapData mapData = gameMain.IngameData.MapData;
   
    int oneHotSize = 5;
    for (int y = 0; y < mapData.BoardColumns; y++)
    {
        for (int x = 0; x < mapData.BoardRows; x++)
        {
            SlotTile slotTile = mapBoardData.GetSlotTile(x, y);
            var type = slotTile.ColorBlock.BlockColorType;
            for (var i = 0; i < oneHotSize; i++)
            {
                sensor.AddObservation((i == (int)type) ? 1.0f : 0.0f);
            }
        }
    }
}

유니티 mlagnet match3 샘플을 참고해서 agent가 받는 소스를 만들었습니다.

public override void OnActionReceived(ActionBuffers actionBuffers)
{
    int aiIndex = actionBuffers.DiscreteActions[0];
    MapBoardData mapBoardData = gameMain.IngameData.CurBoardData;
    var touchSlotIndex = (SharedInt)gameMain.behavior.GetVariable("touchSlotIndex");
    var targetSlotIndex = (SharedInt)gameMain.behavior.GetVariable("targetSlotIndex");

    int BoardRows = gameMain.IngameData.MapData.BoardRows;
    int BoardColumns = gameMain.IngameData.MapData.BoardColumns;

    int row, col;
    if (aiIndex < (BoardColumns - 1) * BoardRows)
    {
        col = aiIndex % (BoardColumns - 1);
        row = aiIndex / (BoardColumns - 1);

        int _Index = GetIndex(col, row);
        touchSlotIndex.SetValue(_Index);

        int _tarIndex = GetIndex(col + 1, row);
        targetSlotIndex.SetValue(_tarIndex);

    }
    else
    {
        var offset = aiIndex - (BoardColumns - 1) * BoardRows;
        col = offset % BoardColumns;
        row = offset / BoardColumns;


        int _Index = GetIndex(col, row);
        touchSlotIndex.SetValue(_Index);

        int _tarIndex = GetIndex(col, row + 1);
        targetSlotIndex.SetValue(_tarIndex);
    }
    Debug.Log("###OnActionReceived - end");
}

보상은 매칭되는 블럭이 수 만큼 보상을 주도록 했습니다. 3개 매칭 되면 0.3점 4개가 매칭 되면 0.4점 이런식으로요.

 

match3MLAgentsBoard = gameObject.GetComponent<Match3MLAgentsBoard>();
foreach (DamageObject damageObject in gameMain.IngameData.DamageList)
{
    foreach (var baseObject in damageObject.BaseObjectBlocks)
    {
        gameMain.IngameData.mReward += 0.1f;
        rewardSum += 0.1f;
    }
}

match3MLAgentsBoard.AddReward(rewardSum);

 

Behavior Paremeters 세팅 입니다.

Behavior Paremeters 설정_기본.png

8*7*5=280

8*(7-1) +7*(8-1) =97 해서 나온 값을 넣어 줬습니다.(유니티 셈플 계산법)

 

mlagents-learn "C:\Users\TT\Desktop\ml-agents-release_21\config\ppo\Match3.yaml" --env=C:\MyProject\MatchPuzzle\Client\trunk\MatchPuzzle\run\MatchPuzzle.exe --run-id=InGameMain --force --no-graphics

하고 나니

 

MatchPuzzle.png

이렇게 나오고 학습이 안되었습니다..

그래서 mlagent match3 샘플을 보니.

Match3SensorComponent

Match3ActuatorComponent

있다는걸 찾았고

Match3SensorComponent에 Write(ObservationWriter writer) 부분과 Match3ActuatorComponent의 OnActionReceived(ActionBuffers actions)부분을 흉내 내어 Component을 만들고

Match3MLAgentsBoard CollectObservations 함수와 OnActionReceived함수는 주석을 쳤습니다.

그리고 실행

mlagents-learn "C:\Users\TT\Desktop\ml-agents-release_21\config\ppo\Match3.yaml" --env=C:\MyProject\MatchPuzzle\Client\trunk\MatchPuzzle\run\MatchPuzzle.exe --run-id=PuzzleMatch3Sencor --force --no-graphics

 

 

PuzzleMatch3Sencor_MatchPuzzle.png여전히 학습이 안되여서.. 유니티 mlagent가 제공하는 match3 샘플을 돌려 보기로 했습니다.

 

mlagents-learn "C:\Users\TT\Desktop\ml-agents-release_21\config\ppo\Match3.yaml" --env=C:\Users\yree1\Desktop\ml-agents-release_21\Project\Match3Run\UnityEnvironment.exe --run-id=UnityMatch3Data --force --no-graphics

 

 

스크린샷 2024-07-16 235146.png

샘플도 딱히 학습이 된다고 보기 어려워서.. 혹시 너무 짧아서 학습이 제대로 안되었다고 생각되어 더 길게 학습을 하였습니다.

스크린샷 2024-07-17 015623.png

 

여전히 학습이 제대로 안되는거 같아서 mlagnet 셋팅 환경이 문제일지 몰라서 3dball 프로젝트를 돌려 봤습니다.

mlagents-learn "C:\Users\TT\Desktop\ml-agents-release_21\config\ppo\3DBall.yaml" --env=C:\Users\yree1\Desktop\ml-agents-release_21\Project\3DBallRun\UnityEnvironment.exe --run-id=3DBallData --force --no-graphics

 

스크린샷 2024-07-16 235415.png엄청 학습이 잘됩니다.

 

스크린샷 2024-07-16 235711.png3dball만 잘 학습 됩니다..

혹시나 싶어서 Release 20에서도 학습을 진행 했지만.. 결과는 똑같이 제대로 학습 되지 않았습니다.

 

제일 궁금한건 왜 match3 agent가 잘 학습을 못하는지 굼금합니다..

제가 만든건 왜 학습이 안되는지..궁금 하지만 더 궁금한건.. 유니티에서 제공하는 match3은 문제가 없을텐데.. 제가 뭔가 명령어 옵션이나.. 등등을 놓친게 있을까요?? 정말 아무것도 손 안되고 Release 21압축 풀고 바로 돌린건데요.

 

그 외에 몇까지 궁금한게 있습니다.

  1. 학습을 시키면 어느Step까지 기다리고 학습을 평가 해야 되는지..아까보여 드렸든 match3 보상 값은 올라 갔다 내려갔다 계속 값이 왔다 갔다만 있습니다.. 이걸 계속 기다리다보면 언젠가 학습을 잘하게 되는지..값이 계속 왔다 갔다 거리면 그만 해야 되는지..학습이 실패 했다고 정확하게 아는 방법이 있나요?

     

  2. 유니티 mlagent가 제공하는 match3은 왜 Agent을 상속 받아 CollectObservations,OnActionReceived함수를 정의 안하고.. Match3SensorComponent,Match3ActuatorComponent 만들어서 학습을 진행 했는지 궁금합니다.

     

  3. match3 센서값 엑터값을 위에 적은 방법이 아닌 다른 방식으로 많이 셋팅 해봤습니다. 그러나 제대로 학습 되는 경우가 없었습니다.. 인공지능 ppo 알고리즘이 제대로 된 결과값을 얻을 수 있는 팁이나 약간의 규칙(이렇게 하면 조금 잘된다..) 이런게 있을까요?

  4. Match3.yaml 파일만 유일하게 learning_rate_schedule: constant을 쓰고 있습니다. 나머지 파일은 전부 learning_rate_schedule: linear 쓰고 있습니다. constant,linear 차이가 뭔가요?? constant을 linear 로 바꾸고 학습 했지만.. 결과는 여전히 학습 되지 않았습니다.

  5. 파이썬으로 ppo 구현해서 유니티랑 연동하면 왜 학습을 잘 못하는지.. 어떻게 하면 잘 할수 있는지.. 등등이 도움이 될만한 것들이 있을까요? 기존 유니티가 제공하는 ppo를 쓰지 않고 python으로 제작해서 작업 하면 어떤 이득이 있을까요?

  6. match3 게임 말고 다른 게임에 mlagent를 적용하고 싶은데요.. match3 같은 색깔 블럭이면 게속 연결 가능한 게임 입니다. 프렌츠타워 라는게 임이 가장 유명합니다. 사진첨부 합니다.

스크린샷 2024-07-17 004458.png

위에 게임처럼 연결 할 수 있는 블럭이 3개 ,4개 5개일수도 8*7이라면 56개 일수도 있는 상황은 Behavior Paremeters 세팅은 어떻게 하나요? 8*7퍼즐판이라면 discrete branches 56이되고 Branch 0~Branch 55까지 다 55값을 넣어서는 학습이 잘 안됩다.. 이걸 어떻게 해야 될지.. 전혀 몰르겠습니다.

 

 

긴글 읽어주셔서 감사합니다.. 수업 내용과 직접적인 관련이 없는 내용을 질문해서 죄송합니다. 하지만 여기 말고는 물어볼 곳이 없어서.. 이렇게 글 남기게 되었습니다. 감사합니다.

 

답변 2

0

민규식님의 프로필 이미지
민규식
지식공유자

2024. 07. 20. 11:32

안녕하세요! 저도 match3는 직접 진행해본적이 없어서 질문주신 부분 중 몇 부분은 더 깊게 살펴봐야 할 것 같구요! 일단 대답할 수 있는 것 먼저 답변드리겠습니다!

일단 쓱 봤을때는 상태, 보상 설정은 괜찮게 하신 것 같은데 행동에 대한 부분은 제가 조금 더 이해해 봐야할 것 같습니다.

그리고 기타질문들 답변드려보겠습니다.

  1. 어느 스텝만큼 기다려야하는가는 환경의 난이도 등에 따라 차이가 있습니다. 예전에 알파고 학습할 때는 몇일을 기다려야 좀 학습에 대한 기미가 보이는 경우도 있었구요! match3 환경의 경우는 보상을 즉각적으로 받을 수 있는 환경이다 보니 학습 초반부터 학습에 대한 각이 보일 것 같긴합니다.

  2. 상속받아서 사용하는건 뭔가 match3의 경우 다른 설정이 필요하기 때문일 것 같은데요! 퍼즐 환경이다보니 설정 등에 차이가 있어 변경한 것 같습니다. 자세한건 저도 살펴봐야할 것 같네요

  3. PPO의 경우 파라미터 설정에 따라 설정의 차이를 보이긴합니다. 저희가 학습하면서 차이를 좀 보였던 파라미터는 n_step인데요. 그래도 match3 환경의 경우 보상을 얻기까지의 길이가 길지 않아서 이 값이 큰 영향을 미치지는 않을 것 같다고 생각됩니다.

  4. learning_rate_schedule이 constant인 경우 학습이 진행되어도 학습률이 유지되고 해당 값이 linear인 경우 감소합니다. 일반적으로는 학습이 진행됨에 따라 학습률을 조금씩 감소시키는 linear를 주로 사용합니다.

  5. 유니티가 제공하지 않는 PPO를 쓰는 경우의 장점은 자유도가 높다는 것입니다. mlagents-learn을 쓰는 경우 일부 파라미터만 변경할 수 있지만 직접 PPO를 구현하는 경우 코드를 마음대로 수정하고 필요시 새로운 모듈을 추가하는 것도 가능합니다.

  6. 말씀해주신대로면 행동 공간이 너무 크기도 하고 고정적이지도 않아서 학습이 어려울 것 같습니다. 환경에 대한 설정을 (저도 방법은 딱 떠오르지는 않는데) 최대한 간단하고 고정적인 행동 공간의 환경으로 설정해주시면 좋을 것 같습니다!

 

0

민규식님의 프로필 이미지
민규식
지식공유자

2024. 07. 16. 23:18

안녕하세요! 아마 질문 내용이 작성되다가 누락된듯 합니다! 확인 부탁드립니다!

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기