티스토리 뷰

강화학습 Tips and Tricks

Author: Benthebear93[이해구] & Keep9oing[정민재]

Reference: https://stable-baselines3.readthedocs.io/en/master/guide/rl_tips.html

Stable Baseline 3(SB3)에서 본격적으로 강화학습을 적용하고자 하는 사람들을 위한 팁들과 트릭들을 정리한 포스트의 번역물입니다. 오역이 있을 경우 피드백 환영입니다.

커여운 마스코트


Reinforcement Learning Tips and Tricks

이번 글의 목적은 강화학습을 연구하는 데 있어서 도움을 주기 위함입니다. 글에서는 강화학습을 연구하면서 '어떻게 시작하고, 어떤 알고리즘을 선택하고 평가하는지 등'에 대한 일반적인 조언들로 부터 커스텀 환경과 강화학습 알고리즘을 적용하는데 유용할 팁과 트릭들을 다루고 있습니다.

General advice when using Reinforcement Learning

TL;DR

  1. 강화학습과 Baselines3에 대해서 읽는다.
  2. 필요하다면 정량적인 경험들과 하이퍼 파라미터 튜닝을 해본다.
  3. 다른 환경을 통해서 성능을 평가한다.
  4. 더 좋은 성능을 위해 training budget을 늘린다.

다른 분야들과 똑같이 강화학습을 통해 무언가를 하고 싶다면, 내가 무엇을 사용하고 있는지에 대해 읽어봐야할 필요가 있다. (링크를 통해 정보를 얻을 수 있다.) 그리고 가능한 Stable Baselines3 문서를 읽어보고 튜토리얼을 진행하기를 추천한다. 튜토리얼에서는 기본적인 사용부터 라이브러리의 조금 더 많은 부분(callback 이나 wrapper와 같은)을 설명해준다.

강화학습은 다양한 부분에서 다른 머신러닝들과 다른점을 보인다. agent 자체가 환경과 상호작용하면서 모아진 데이터가 agent를 학습시키는데 사용된다. (supervised learning에서는 데이터셋을 고정해야 하는 것과는 다르게). 데이터의 이런 형태는 악순환을 초래할 수 있는데, 만약 agent가 좋지 않은 데이터를 모은다면 좋은 방향으로 움직이는 것이 아닌 계속해서 좋지 않은 행동만 할 것이다.

이런 사실 때문에 강화학습을 돌릴 때 마다 다른 결과가 나오는 이유이다. 따라서 정량적인 결과를 얻기 위해서는 여러번 (학습을) 돌릴 필요가 있다.

강화학습에서 좋은 결과를 얻는 것은 주로 좋은 하이퍼 파라미터를 찾는 것과 관련이 있다. 최근에 나온 PPO, SAC, TD3와 같은 알고리즘은 하이퍼 파라미터 튜닝이 적지만 다양한 환경에서 잘 작동하지는 않는다.

따라서 하이퍼 파라미터 튜닝에 익숙해지기 위해서 RL zoo를 한번 확인하는 것을 추천한다.

강화학습을 커스텀 문제에 적용할 때는 agent에 주는 input을 정규화(normalize)할 필요가 있다. 그리고 다른 환경에서 일반적인 프로세싱이 어떻게 끝나는지 볼 필요가 있다. 커스텀 환경에 대한 이야기는 아래에서 차차 다루겠다.

Current Limitations of RL

강화학습을 연구하고 적용하기 전에, 현대 강화학습(현재 2021년도 기준)의 한계에대해 인지할 필요가 있다.

SB3에 구현된 Model-free 알고리즘 들은 일반적으로 샘플 효율성이 떨어진다(sample inefficient). 학습에 유용한 샘플을 얻기위해 굉장히 많은 환경과 에이전트의 상호작용이 필요하기 때문이다. 이것이 대부분의 성공적인 RL 적용 사례가 게임들이나 시뮬레이션에만 치중된 이유다. 예를들어, ETH Zurich의 연구에서 ANYmal 로봇은 시뮬레이션에서만 학습되고, 실제 환경에서 테스트됐다.

일반적으로 더 나은 성능을 얻으려면 에이전트의 예산(학습스텝 수 등)을 더 늘려야 한다.

좋은 행동(desired behavior)을 달성하기 위해서는 적절한 보상 함수를 설계해야하는데, 이 때 문제 도메인에서 전문적 지식의 활용이 요구된다. Freak Stulp가 RewArt라고도 부르는 이 과정을 reward engineering이라고 하고 여러번 시행착오의 반복을 통해 이뤄진다. 묘기수준의 움직임을 학습하기 위해 모방학습과 강화학습을 사용한 Deep Mimic 논문을 보면 보상 설계의 좋은 예시를 볼 수 있다.

강화학습의 마지막 한계점은 학습의 불안정성이다. 예를들면, 학습중에 급격한 퍼포먼스 저하같은 것들을 말한다. 특히 DDPG에서 이런 일이 많이 일어나서 TD3에서 이런 문제점들을 해결하고자한다. 다른 방법으로는 TRPOPPOtrust region을 이용해 급격한 그래디언트 업데이트를 피하기도 한다.

How to evaluate an RL algorithm?

!Note: 다른 결과들과 비교하고 agent를 평가할 때는 environment wrapper를 잘 확인해야한다. episode의 reward나 length를 바꾸는 것이 평가에 영향을 끼칠 수 있다. 자세한 내용은 Evaluation Helper 섹션에서 evaluate_policy helper 함수를 확인해보자.

대부분 알고리즘이 학습 중에 exploration noise를 사용하기 때문에 agent의 성능을 평가할 때는 테스트 환경을 나눠야한다. 일정 기간동안 n번의 테스트 episode를 통해 agent를 평가해야 한다. 그 후 episode마다의 reward를 평균내여 성능을 예측한다.

!Note: 이런 평가를 위한 EvalCallback 를 제공하며 Callbacks 섹션에서 자세히 확인할 수 있다.

A2C나 PPO처럼 policy의 default가 stochastic으로 설정되어 있는 경우가 있으니 .predict() 메소드를 부를 경우 deterministic=True 를 설정해줘야한다. 이렇게 해주면 성능 향상에 도움이 된다. timestep의 episode reward function인 training curve를 보는 것은 간접적으로 성능을 볼 수 있는 방법이지만, agent의 실제 성능을 과소평가하고 있을 수 있다.

좋은 강화학습 평가를 위해 Deep Reinforcement Learning that Matters 를 읽어보는 것을 추천한다.

추가로 Cédric Colas가 제시한 issueblog post를 확인해보는 것도 좋다.

Which algorithm should I use?

만능 해결 도구(silver bullet)인 강화학습 알고리즘은 없다. 문제의 요구조건에 따라 활용자는 어떤 알고리즘을 사용할 지 결정해야한다. 가장 처음 고려해야 할 점은 action space이다. Discrete action(왼쪽, 오른쪽, ...)을 사용할 것인지, Continuous action(어떤 속도로 이동할 것 인지? 등)을 사용할 것인지 결정해야한다.

어떤 알고리즘들은 한 도메인에만 맞춤화 됐다. DQN은 discrete action만을 지원하고 SAC는 continuous action에만 한정되어 사용할 수 있다.

두번째로 고려해야할 점은 학습을 병렬화 할 수 있는가 없는가 이다. 만약 실제로 학습하는데 드는 시간(wall clock training time)이 고려되어야 한다면, A2CPPO같은 그 변형 알고리즘들을 이용해 학습하는 것을 생각해봐야한다. 다수의 worker를 사용해 학습을 진행하고 싶다면 Vectorized environment파트를 읽어보는 것을 추천한다.

밑에서 정리를 하자면,

Discrete Actions

여기서는 Discrete, MultiDiscrete, Binary, MultiBinary action space[gym 환경의 space 들]에 대해 다룬다.
  • Single Process
  • DQN알고리즘과 그 확장 알고리즘들(double DQN, prioritized replay, ...)들의 사용이 추천된다. SB3의 contrib repo에 가면 QR-DQN에 대한 구현도 돼있다. 일반적으로 DQN 계열은 wall clock time 관점에선 학습이 느리지만, 리플레이 메모리를 사용하기 때문에, 가장 샘플 효율성이 좋다.
  • Multiprocessed
  • PPOA2C를 사용해볼 수 있다.

Continuous Actions

  • Single Process
  • 현재의 SOTA(state of the art)알고리즘은 SAC, TD3, TQC(contrib repo)를 사용해보는 것을 추천한다. RL zoo의 하이퍼파라미터를 통해 좋은 결과를 낼 수 있을 것이다.
  • Multiprocessed
  • PPOA2C를 사용하면 된다. 다시 말하지만, RL zoo의 하이퍼파라미터를 사용하는 것을 잊지말길 바란다. (Bullet env같은 continuous action환경에서는)

이런 알고리즘들에선 Normalization이 매우 중요하다.

Goal Environment

만약 환경이 GoalEnv 인터페이스를 따른다면(HER 참고), action space가 무엇인지에 따라 HER +(SAC,TD3,DDPG,DQN,QR-DQN,TQC)등을 사용하면 된다.

HER을 사용할 때는, batch size가 굉장히 중요한 하이퍼파라미터이다.

Tips and Tricks when creating a custom environment

커스텀 환경을 만들고 싶다면 이 페이지를 참고하는 것을 추천한다. 커스텀 환경을 제작하기 위한 탄탄한 예시들도 Colab notebook으로 제공하고 있다.

Some Basic advice

  • observation space는 가능하다면(경계를 알고 있다면) 항상 normalize하자.
  • continuous일 경우 action space를 normalize하고 symmetric 형태로 만들자. 좋은 방법은 action들을 [-1, 1]로 조절(resclae)하는 것이다. environment안에서 action을 다시 조절할 수 있으므로 [-1, 1]로 조절한다고 해서 제한되는 것은 아니다. (1에서 1로 나오는 아웃풋을 따로 만든 함수를 통해서 env에 적용시켜주면 된다는뜻. EX) 속도제어할때 max vel이 3이면 [-1, 1]아웃풋을 환경에 적용할 때는 [-1 ,1] *3을 해주면 [-3, 3] 사이의 속도 제어 적용이 가능해짐)
  • 해결하려는 문제의 간단한 형태와 직관적인(informative) reward로 시작하자.
  • random action들로 환경이 잘 구성 됐고 gym interface를 잘 따르는지 디버깅 하자.

구성한 환경이 에러 없이 작동하는 지 확인할 수 있는 helper를 제공하고 있다.

from stable_baselines3.common.env_checker import check_env

env = CustomEnv(arg1, ...)
# It will check your custom environment and output additional warnings if needed
check_env(env)

만약 구성한 환경에서 랜덤한 agent를 확인하고 싶다면 아래와 같이 하면 된다.

env = YourEnv()
obs = env.reset()
n_steps = 10
for _ in range(n_steps):
# Random action
    action = env.action_space.sample()
    obs, reward, done, info = env.step(action)
   	if done:
		obs = env.reset()

action space를 normalize 해야하는 이유는?

다수의 강화학습 알고리즘은 연속적인 action일 경우 가우시안 분포를 따른다. 따라서 커스텀 환경에서 action space를 normalize하지 않았을 경우 학습에 문제가 생기며 디버깅 하기 어려울 것이다. 아래 이미지와 issue를 확인해보자.

가우시안을 사용하기 때문에 action의 범위가 정해지지 않는다. 이런 이유로 유효한 범위(valid interval)안에 존재하기 위한 방법으로 clipping이 사용된다. 더 좋은 방법은 squashing 함수(참고 : SAC)나 Beta distribution을 사용하는 것이다. (참고)

Tips and Tricks when implementing an RL algorithm

만약 강화학습논문을 구현하려고 한다면, John Schulman의 nuts and bolts of RL research 슬라이드가 아주 유용할 것이다. (비디오)

강화학습에 관련된 연구들을 구현 할때는 아래와 같은 순서를 지키는 것을 추천한다.

  1. 원 논문을 몇번에 걸쳐 읽는다.
  2. 가능하다면 존재하는 구현체에 대해 조사한다.
  3. 간단한 문제를 통해 잘 되는지 확인한다. (Try to have some "sign of life" on toy problems)
  4. 구현체가 잘 작동하는지 점점 더 어려운 환경에다가 학습시키면서 검증한다. 이 때 주로 하이퍼파라미터 최적화를 진행하는것이 필요하다.

특히 다른 object들의 shape를 다루는 것에 각별한 주의를 기울여야한다. (브로드캐스팅 실수는 알아차리기가 힘들다.) 또한, 언제 gradient propagation을 멈춰야하는지도 중요하다.

강화학습 알고리즘을 적용하기에 점점 어려운 환경에 대한 araffin이 추천하는 순서

  • Continuous action
  1. Pendulum (풀기 쉬움)
  2. HafCheetahBullet (로컬 미니마와 보상 설계에 대해 중간난이도를 가짐)
  3. BipedalWalkerHardcore (여기에서도 잘되면, 개잘되는거임)
  • Discrete action
  1. CartPole-v1 (최대 퍼포먼스를 얻기는 어려워도 랜덤 에이전트보다 잘하기 쉬운 환경)
  2. LunarLander
  3. Pong (가장 쉬운 아타리 게임중 하나)
  4. other Atari games (예: Breakout)
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31