Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

개발이 취미인 개발자

OpenAI Gym-FrozenLakeEnv object has no attribute lastaction 오류 처리 본문

딥러닝 & 머신러닝

OpenAI Gym-FrozenLakeEnv object has no attribute lastaction 오류 처리

도그풋79 2022. 3. 30. 23:04

 OpenAI Gym를 공부하기 위해 인터넷에 제공되는 예제를 토씨 하나 안 틀리고 그대로 타이핑하고 실행을 해 봤지만 정상적으로 동작을 하지 않았다. 방향키를 입력하면 방향에 따라 state, action, reward, info 값을 출력하는 간단한 예제였는데 아래와 같은 오류를 메시지를 뿌리면서 동작을 하지 않았다.

AttributeError: 'FrozenLakeEnv' object has no attribute 'lastaction'

 

 위의 문제를 처리하기 전에 앞서 우선 키 입력을 받는 부분부터 처리를 해줘야한다. tty, termios와 같은 라이브러리는 mac에서만 동작하는 코드인 듯 하다. 아래는 소스 코드는 강좌에서 사용되는 예제인데 윈도우에서는 전혀 동작하질 않는다.

import sys, tty, termios # 키 입력을 위한 라이브러리

# 키입력을 받기 위한 클래스
class _Getch:
  # 키값 리턴
  def __call__(self):
      fd = sys.stdin.fileno()
      old_setting = termios.tcgetattr(fd)
      try:
          tty.setraw(sys.stdin.fileno())
          ch = sys.stdin.read(1)
      finally:
          termios.tcsetattr(fd, termios.TCSADRAIN, old_setting)
      print(ch)
      return ch
  
inkey = _Getch()

위의 소스는 아래와 같이 변경을 해줘야만 윈도우 환경에서 동작을 한다.

방향키를 누르게 되면 처음에는 b'\x00' 값을 리턴한 후에 두번째에 실제 입력한 방향키의 값을 리턴해준다.

따라서 키 입력을 처리하는 부분은 두번에 걸쳐 나눠서 받은 후 처리해 줘야한다.

import 해줘야하는 라이브러리도 tty, termios가 아닌 msvcrt 로 변경해 줘야한다.

import msvcrt
..
while True:    
    key = msvcrt.getch()
    if key == b'\x00':
        key = msvcrt.getch()
        if key == b'K':
            action = 0
        elif key == b'P':
            action = 1
        elif key == b'M':
            action = 2
        elif key == b'H':
            action = 3
    else:
        print("Game aborted!")
        break

 

그리고 mac에서는 아래 코드처럼 별다른 처리 없이 env.render() 해도 문제가 없는 듯 하다. 

env = gym.make("FrozenLake-v3")
env.render()

하지만 윈도우에서는 reset()을 먼저 선언해야 object has no attribute 'lastaction' 과 같은 오류 메시지가 뜨질 않고 동작한다. 

env = gym.make("FrozenLake-v3")
env.reset()

그리고 마지막으로 화면에 MAP의 형태와 현재 위치를 출력해주는 부분이 있는데 이 또한 별도로 출력하는 코드를 넣어줘야된다. 사실 강화학습을 공부하는 이 부분은 그냥 건너 뛰어도 무방하다. 하지만 그냥 건너 뛰면 뭔가 아쉬움이 남는거 같아 정상 동작하도록 소스를 수정해 보았다. 아..나도 mac으로 개발용 PC를 바꾸고 싶다.

import gym
import msvcrt
from gym.envs.registration import register

LEFT  = 0  #75
DOWN  = 1  #80
RIGHT = 2  #77
UP    = 3  #72

arrow_keys = {
    b'K':LEFT,
    b'P':DOWN,
    b'M':RIGHT,
    b'H':UP
}

register(
    id='FrozenLake-v3',
    entry_point='gym.envs.toy_text:FrozenLakeEnv',
    kwargs={'map_name':'4x4', 'is_slippery': False}
)

env = gym.make("FrozenLake-v3")
env.reset()

while True:    
    key = msvcrt.getch()
    if key == b'\x00':
        key = msvcrt.getch()
        #print("2:key = {0}".format(key))
        if key == b'K':
            action = 0
        elif key == b'P':
            action = 1
        elif key == b'M':
            action = 2
        elif key == b'H':
            action = 3
    else:
        print("Game aborted!")
        break
    
    state, reward, done, info = env.step(action)
    print(env.render("ansi"))
    print("state: {0}, Action: {1}, Reward: {2}, Info: {3}".format(state, action, reward, info))

    if done:
        print("Finished with reward {0}".format(reward))
        break