수강생 작품

하늘에서 떨어지는 고양이

유니티 ML-Agent를 통해 강화학습으로 고양이의 움직임을 따라해본 프로젝트입니다.

팀구성 및 역할

하늘에서 떨어지는 고양이 포트폴리오

 

- 프로젝트 명 : 하늘에서 떨어지는 고양이

- 프로젝트 주제 : 머신러닝으로 학습된 고양이를 피하는 게임

- URL : https://www.youtube.com/watch?v=R9j29qq4MWI

https://www.youtube.com/watch?v=2n9SLVhFIz8

- 개발 인원 : 1명 홍유진

- 개발기간 : 04/20(월) ~ 04/24(금)

- 개발환경: Unity 2019.3.5f1, ML-Agents Master, Python3.6, Tensorflow, bash shell

 

프로젝트 개요

 고양이는 어떻게 뒤집어서 떨어져도 네 발로 착지하는걸까?

휴머노이드 로봇에게 가장 어려운 동작 가운데 하나는 점프 후 착지(Landing) 기술이다. 이러한 착지 기술이 으뜸인 동물에는 고양이가 있다. 고양이는 어떤 각도로 떨어져도 네발로 착지하는 모습을 보여준다. 고양이가 발로 착지하려면 공중에서 몸을 돌려야 하는데, 그러면 각운동량 보존 법칙에 의해서 몸의 다른 부분은 반대로 돌아가야 한다. 그러면 고양이의 몸이 꼬이게 될것이다. 하지만 실제로 그런일은 일어나지 않는다.

 고양이는 매우 높은곳에서 떨어져도 크게 다치지 않는다. 1987년, 미국 연구진들은 높은 곳에서 뛰어내려 뉴욕시 응급센터에 방문한 고양이들의 통원기록을 분석하였다. 그 결과 90%의 고양이들은 살아남았고, 단지 37%의 고양이만이 응급조치를 받았다. 심지어 32층에서 떨어진 고양이의 경우 이빨이 부러지고 각종 타박상을 입었지만 48시간 후에 회복되어 멀쩡히 돌아다녔다.

 고양이는 어떻게 이런 착지능력을 가질 수 있을까? 이러한 착지능력을 유니티 오브젝트에 적용하기 위해 이 프로젝트를 시작하게 되었다.

 

1. 학습내용

1.1. 관절설정 (4월 20일)

고양이가 제대로 걷고 착지하기 위해서는 관절이 필요하다. 관절의 각도를 조절해서 움직일 수 있는 고양이를 만들기 위해 Configurable Joint를 통해 고양이의 관절들을 연결하였다. 실제 고양이와 비슷한 관절을 제작하기 위해, 고양이의 골격계를 보고 뼈대를 제작하였다. 그래도 실제 고양이의 골격과 많은 차이가 있다. 고양이는 22~23개의 꼬리뼈를 가지고 있지만, 이 프로젝트의 고양이는 단 4개의 꼬리뼈만을 가지고 있다. 그 외에도 꼬리뼈 중 몸에 가장 가까운 뼈대만 움직일 수 있게 설정하고, 나머지는 그저 몸의 움직임에 영향을 받아서 움직이게 설정하였는데, 프로젝트를 마무리하고 생각해보니 잘못된 선택이였던 것 같다. 고양이는 대부분의 꼬리뼈를 잘 움직인다.

 

1.2. 걷기

유니티 ML-Agents를 이용한 Joint Driver제어가 처음이라 이에 익숙해지기 위해 먼저 걷기동작을 학습시켜보았다. ML-Agents Master버전에서는 기본적으로 휴머노이드 형태의 오브젝트가 걷는 프로젝트와, 네발을 가진 거미가 걷는 동작이 학습되어있는 예제가 포함되어 있다. 그것을 보고 공부하는것이 큰 도움이 되었다.

 

1.2.1. 학습전 (4월 21일)

 학습을 시작하기 전, 모든 관절에 랜덤한 값을 주어 움직이게 한 모습이다. 이때 Joint Driver의 미숙한 사용으로 버그가 있어서, 꼬리 관절이 초기화되지 않아 학습의 다음 Step에서 고양이가 하늘로 날라가는 버그가 있었다. 사진은 버그로 고양이가 날라가는 모습이다.

 

1.2.2. 1차 학습완료(4월 22일)

 학습을 시작하고 자고 왔더니 고양이가 타겟(파란 네모)을 매우 잘 찾는 모습을 보여주었다. 학습방법이 미흡해도 근본적으로 잘못된 것이 아니라면 긴 시간 학습하면 원하는 결과가 나오는듯 하다. 보상(가운데 그래프)는 계속해서 증가하고 있고, Episode Length는 3M까지 증가하다가 이후 감소하는 그래프를 보여주고 있다. 3M번 까지는 넘어지지 않기 위해 균형을 잡는 법을 학습하고, 그 이후로 목표를 따라가는 학습이 진행된 듯 하다.

184개의 Vector Observation, 28개의 Vector Action을 사용하고, 인중에Ray Perception Sensor를 장착하여 물체를 식별하게 하였다. 원래는 Ray대신 카메라를 이용한 Vision방식을 사용했으나, 학습속도가 비효율적일것이란 판단이 들어 Ray로 변경하게 되었다.

보상

Set (-0.001f) // Time Panalty

Set (0.002f * Vector3.Dot(eyeDir, targetToCatDir)); // 고양이와 타겟이 마주보는 각도

If(preDistanceMag – currDistanceMag >= 0.02f) Set (0.001f); // 거리가 줄어들수록 보상

Set (1f) // TouchTarget

Set (-1f) // 넘어짐

 

1.2.3. 뼈대 유연성 재설정

고양이의 이동속도가 느려 뼈대의 유연성을 재설정하였다. 이후 학습을 다시 진행하니 초반에는 잘 넘어지다가 금방 잘 걷기 시작하였다.

 

1.2.4. 커리큘럼(4월 23일)

 고양이의 학습 커리큘럼은 4단계로 나누어 진행하였다.

  1. 가만히 있는 큰 상자 따라가기 ( 넘어지면 학습 종료 )
  2. 천천히 움직이는 큰 상자 따라가기 ( 이후 넘어져도 학습 종료 x )
  3. 천천히 움직이는 작은 상자 따라가기
  4. 빠르게 움직이는 큰 상자 따라가기

4단계까지 학습 후, 방해를 받아도 공중에서 중심을 잡고 목표를 따라가는 모습을 보여줬다.

 

1.3. 착지하기(4월 22일)

 이제 ML-Agents를 어떻게 사용할지 감이 와서 한대의 노트북을 더 사용해 착지 동작을 학습시켰다. 같은 프로젝트에 두개의 씬을 만들어 두대의 노트북을 이용해 학습을 진행했다.

 

1.3.1. 뼈대 유연성 재설정

 고양이의 착지영상을 유심히 살펴보다가, 허리가 더 유연해야할 것 같은 느낌이 들어 허리 유연성을 대폭 증가시켰다. 허리뼈도 더 추가하여 더욱 다양한 움직임이 가능하게끔 하였다. 이제 ‘무섭다’라는 말을 들을 정도로 유연한 고양이가 되었다. 학습 전에는 이전과 마찬가지로 제대로 서있지도 못하는 모습을 보여줬다.

 

1.3.2. 학습진행

 고양이를 공중에서 떨어트려 학습을 진행했다. 총 202개의 Vector Observation, 36개의 Vector Action을 사용하였다.

보상

Set (0.01f * (Vector3.Dot(Vector3.down, CatMouthTr.rotation * Vector3.forward))); // 턱이 땅으로

Set (0.01f * (Vector3.Dot(Vector3.forward, CatMouthTr.rotation * Vector3.left))); // 입이 정면으로

Set (0.003f * (Head.localPosition.y - Tummy.localPosition.y)); // 머리가 배보다 위로

Set (0.001f); // Time Penalty

Set (-1f); // 넘어짐

 

1.3.3. 커리큘럼 (4월 23일)

 고양이가 땅에 잘 착지하긴 하나 한번 넘어지면 다시 못일어서는 모습을 보여주고, 착지하는 자세 자체가 원래 의도했던 고양이 착지가 아니였다. 이런 문제와 안정성을 개선하기 위해 추가 커리큘럼을 진행하였다.

  1. 넘어지면 벌점 후 다시시작
  2. 턱이 땅바닥을 바라보면 상점 추가
  3. 넘어지면 벌점을 주지만 다시시작은 하지 않음
  4. 랜덤한 높이에서 떨어지도록 수정.

 

1.3.4. 실패 (4월 25일)

 

 

 원래는 고양이가 공중에서 회전 후 네 발로 착지하는 모습을 구현하고 싶었지만, 저의 고양이는 계속해서 엉덩이로 착지해 반동으로 튕겨나간 후 네발로 착지하는 모습을 보여줬다. 이 동작을 고치고싶어 다양한 변화를 줘보았지만 결국 실패했다.

 가장 결정적인 실패원인으로 생각되는 것은, 꼬리는 넘어짐 패널티가 없었다는것이다. 땅바닥에 꼬리가 닿는 것을 생각해서 꼬리에 패널티를 주지 않았더니 고양이Agent가 이를 이용해 꼬리로 착지한후 발을 땅바닥에 붙이는 식으로 학습이 진행된 듯 하다. 이를 개선하기 위해서는 꼬리의 Velocity값이 특정 값 이상일시 땅에 닿으면 패널티를 주는 식으로 개선하면 될 것 같다.

 추가로 배의 Vector가 땅바닥쪽으로 회전할수록 추가 보상을 주어도 더 안정적으로 착지할 것으로 예상된다.

 

2. 게임 구성 (4월 25일)

 

 그저 학습만 진행하고 프로젝트를 끝내기 아쉬워서 간단한 게임을 제작해보았다. 파란색 타겟을 플레이어가 조종할 수 있게끔 바꾸고, 카메라가 따라가게 설정하여 고양이를 피하는 게임을 만들었다. 맵에는 수십마리의 고양이가 있으며 고양이에 가까이 가면 고양이들이 따라오게 된다. 시간이 지날수록 하늘에서 고양이가 떨어져 고양이의 수가 증가한다.

 

3. 결과, 느낀점

 

 ML-Agents를 통해 강화학습으로 고양이에게 걷기와 착지 동작을 학습시켰다. 고양이 꼬리와 관련하여 여러 이슈가 있었지만, 이 덕분에 더 리얼한 오브젝트를 만들기 위해 에이전트를 어떻게 구성하고 보상을 설정하는지 고민해 볼 수 있었다. 이 프로젝트를 통해 또 하나의 새로운 툴을 익히게 되었고, 지능형 에이전트와 지능형 게임을 만드는 것에 대한 두려움이 사라지게 되었다. 앞으로 ML-Agents를 이용하여 이전보다 깊은 상호작용이 가능한 에이전트를 만들거나, 자율주행, 인공위성제어와 같은 실용적인 프로젝트에도 이용할 수 있을 것이다.