Sunday, October 15, 2017

슈퍼마리오에 모두를 위한 RL 수업의 딥러닝 코드 붙이기


윈도우에서 openAI Gym을 이용해서 슈퍼마리오 AI 플레이 만들기


1. 윈도우 서브시스템 리눅스에 openAI Gym 설치하기
http://jinman190.blogspot.ca/2017/10/openai-gym.html

2. openAI gym을 이용해서 슈퍼마리오 설치해서 자동 플레이 하기
http://jinman190.blogspot.ca/2017/10/openai-gym_14.html

3. 슈퍼마리오에 모두를 위한 RL 수업의 딥러닝 코드 붙이기
지금 여기

4. 슈퍼마리오의 딥러닝 코드 효율적으로 고쳐보기






목표: 모두를 위한 RL 수업에서 쓰인 코드로 슈퍼마리오를 실행 해 보려고 한다.
(효율적인 딥러닝을 하는게 아니라 우선 변수 차원 맞춰서 에러없이 실행만 해보기)



Sung Kim 교수님의 모두를 위한 RL 수업은 여기.
https://www.youtube.com/playlist?list=PLlMkM4tgfjnKsCWav-Z2F-MMFRx-2gMGG

코드는 여기서 받았다.
https://github.com/nalsil/kimhun_rl_windows/blob/master/07_3_dqn_2015_cartpole.py




알아내느라 꽤 걸렸는데 실제로 고친건 몇줄 안된다.


최종 코드 파일은 여기:
https://docs.google.com/document/d/16LLmgRPGZF2-wEa57uSbvwhDlnaPgyZLA9OnyImR2mQ/edit?usp=sharing

내가 고친 부분엔 ##### 표시를 해뒀다.





원래 소스는 Cartpole 게임을 플레이 하는 소스이다.


우선 받은 소스 위에 앞 글에서 찾아낸 슈퍼마리오 관련 코드를 붙이고

import gym
from gym.envs.registration import register
from gym.scoreboard.registration import add_group
from gym.scoreboard.registration import add_task
register(
     id='SuperMarioBros-1-1-v0',
     entry_point='gym.envs.ppaquette_gym_super_mario:MetaSuperMarioBrosEnv',
)

add_group(
     id='ppaquette_gym_super_mario',
     name='ppaquette_gym_super_mario',
     description='super_mario'
)

add_task(
    id='SuperMarioBros-1-1-v0',
    group='ppaquette_gym_super_mario',
    summary="SuperMarioBros-1-1-v0"
)

게임 이름을 슈퍼마리오로 고쳐준다

env = gym.make('SuperMarioBros-1-1-v0')

다음으로 인풋/아웃풋 개수를 맞춰준다

input_size = env.observation_space.shape[0]*env.observation_space.shape[1]*3
output_size = 6

처음에 인풋 갯수가 172032개여서 헉 이게 뭐지! 했는데
스크린 픽셀 개수 가로*세로*3 이다.
ppaquette_gym_super_mario/nes_env.py 에서 정보를 찾을 수 있다.



스크린 픽셀 갯수에 *3이면 RGB 값... 그렇다면...


갑자기 이런게 막 떠오르려고 하는데 우선 넘어가자








소스의 아랫 부분을 보면 원래 이런 부분이 있는데 고쳐줘야 한다.
            while not done:
                if np.random.rand(1) < e:
                    action = env.action_space.sample()
                else:
                    # Choose an action by greedily from the Q-network
                    action = np.argmax(mainDQN.predict(state))


랜덤으로 입력을 받는 부분인 env.action_space.sample() 은 잘 돌아가는데 아래 action 부분이 원래 cartpole 게임에 맞춰져 있다. 이렇게 바꿔야 한다.

action = mainDQN.predict(state).flatten().tolist()
숫자 6개 출력을 받아서 argmax 하지말고 그냥 리스트로 만들어서 주면 된다.





드디어 슈퍼마리오를 플레이 해보면, 슈퍼마리오가 한번만 실행되고 에러가 난다.




ddqn_replay_train()에

            y_stack = np.vstack([y_stack, Q])
            x_stack = np.vstack([x_stack, state])
이 부분의 state가 한줄(array) 형태가 아니고 matrix 여서 vstack을 쓸 수 없다.
state를 한줄로 쫙쫙 펴줘야 한다.

            y_stack = np.vstack([y_stack, Q])
            x_stack = np.vstack([x_stack, state.reshape(-1, mainDQN.input_size)])
그래야 vstack 함수 그대로 쓸 수 있다.






여기까지만 고쳐도 실행해보면 슈퍼마리오가 돌아간다. 그런데 꼭 고쳐줘야 하는 부분이 있다.



위에서 아웃풋 크기가 6라고 했는데 무슨 뜻인지는
ppaquette_gym_super_mario/wrappers/action_space.py 에서 찾을 수 있다.

                0: [0, 0, 0, 0, 0, 0],  # NOOP
                1: [1, 0, 0, 0, 0, 0],  # Up
                2: [0, 0, 1, 0, 0, 0],  # Down
                3: [0, 1, 0, 0, 0, 0],  # Left
                4: [0, 1, 0, 0, 1, 0],  # Left + A
                5: [0, 1, 0, 0, 0, 1],  # Left + B
                6: [0, 1, 0, 0, 1, 1],  # Left + A + B
                7: [0, 0, 0, 1, 0, 0],  # Right
                8: [0, 0, 0, 1, 1, 0],  # Right + A
                9: [0, 0, 0, 1, 0, 1],  # Right + B
                10: [0, 0, 0, 1, 1, 1],  # Right + A + B
                11: [0, 0, 0, 0, 1, 0],  # A
                12: [0, 0, 0, 0, 0, 1],  # B
                13: [0, 0, 0, 0, 1, 1],  # A + B

그냥 float 6개를 넘기면 되는게 아니라 0 또는 1로 넘겨줘야 하는 것이다.

참고로 이거, float 0.0이나 1.0으로 넘겨도 안된다. 꼭 integer 0이나 1이어야 한다.

이 외의 숫자를 넘기면 슈퍼마리오가 아예 움직이지 않는다.

위에서 그냥 슈퍼마리오를 실행 했을 때 슈퍼마리오가 움직이는건 내가 계산해 낸 출력 때문이 아니라 윗줄의 랜덤 출력

                if np.random.rand(1) < e:
                    action = env.action_space.sample()
때문이다.




결과값이 0, 1이라니... 여기에 또 뭘 적용해볼까 막 시그모이... 같은게 떠오르지만, 

우선 슈퍼마리오를 실행하는게 목표니까 그냥 이렇게 하자.


                    for i in range(len(action)):
                        if action[i] > 0.5 :
                            action[i] = 1
                        else:
                            action[i] = 0
반올림 ㅋ



이제 슈퍼마리오를 실행하면 된다.

오~ 된다.





...

그런데 또 잠깐.

반복 실행을 하다보면 인풋이 이상하게 들어와서 에러가 날 때가 있다.

그게 왜 들어오는진 모르겠지만 인풋이 이상하게 들어오면 그 프레임은 무시하고 넘어가자.

우선 ddqn_replay_train()에서 출력만 시키고 다음으로 넘어가자

        if state is None:
            print("None State, ", action, " , ", reward, " , ", next_state, " , ", done)
        else:
            원래 함수

을 추가하고



랜덤 플레이를 만드는 아래 부분에

                if np.random.rand(1) < e:
                    action = env.action_space.sample()

이렇게 좀 추가하자. 그냥 버그스럽게 이렇게 인풋이 들어올 때가 있다는 것만 기억하고.

                if np.random.rand(1) < e or state is None or state.size == 1:
                    action = env.action_space.sample()


이렇게 하면 드디어 슈퍼마리오가 실행 된다.

(효율 적으로 플레이 된다는 게 아니다. 그냥 에러 없이 실행 된다는 것 뿐)



학습을 하는지 마는지 몰라도 에러 없이 실행되긴 한다.
그냥 랜덤 입력으로 플레이 하는 것도 같지만 계속 켜놓으면 행동이 점점 변하긴 한다.
그게 좋은 쪽으로 변하는건지가 문제지만.



최종 코드 파일은 여기:
https://docs.google.com/document/d/16LLmgRPGZF2-wEa57uSbvwhDlnaPgyZLA9OnyImR2mQ/edit?usp=sharing

내가 고친 부분엔 ##### 표시를 해뒀다.



# original DQN 2015 source from  https://github.com/nalsil/kimhun_rl_windows/blob/master/07_3_dqn_2015_cartpole.py
# The code is updated to play super mario by Jinman Chang
# super mario game can be downloaded at https://github.com/ppaquette/gym-super-mario

# ##### is marked where is updated
# explanation for this code is at http://jinman190.blogspot.ca/2017/10/rl.html


###############################################################################super mario initialized
import gym
from gym.envs.registration import register
from gym.scoreboard.registration import add_group
from gym.scoreboard.registration import add_task
register(
     id='SuperMarioBros-1-1-v0',
     entry_point='gym.envs.ppaquette_gym_super_mario:MetaSuperMarioBrosEnv',
)

add_group(
     id='ppaquette_gym_super_mario',
     name='ppaquette_gym_super_mario',
     description='super_mario'
)

add_task(
    id='SuperMarioBros-1-1-v0',
    group='ppaquette_gym_super_mario',
    summary="SuperMarioBros-1-1-v0"
)
#################################################################################




import numpy as np
import tensorflow as tf
import random
from collections import deque

from gym import wrappers

env = gym.make('SuperMarioBros-1-1-v0')                                             #####update game title

# Constants defining our neural network
input_size = env.observation_space.shape[0]*env.observation_space.shape[1]*3        #####change input_size - 224*256*3 acquired from ppaquette_gym_super_mario/nes_env.py
output_size = 6                                                                     #####meaning of output can be found at ppaquette_gym_super_mario/wrappers/action_space.py

dis = 0.9
REPLAY_MEMORY = 50000

class DQN:
    def __init__(self, session, input_size, output_size, name="main"):
        self.session = session
        self.input_size = input_size
        self.output_size = output_size
        self.net_name = name

        self._build_network()

    def _build_network(self, h_size=10, l_rate=1e-1):
        with tf.variable_scope(self.net_name):
            self._X = tf.placeholder(tf.float32, [None, self.input_size], name="input_x")

            # First layer of weights
            W1 = tf.get_variable("W1", shape=[self.input_size, h_size],
                                 initializer=tf.contrib.layers.xavier_initializer())
            layer1 = tf.nn.tanh(tf.matmul(self._X, W1))

            # Second layer of Weights
            W2 = tf.get_variable("W2", shape=[h_size, self.output_size],
                                 initializer=tf.contrib.layers.xavier_initializer())

            # Q prediction
            self._Qpred = tf.matmul(layer1, W2)

        # We need to define the parts of the network needed for learning a policy
        self._Y = tf.placeholder(shape=[None, self.output_size], dtype=tf.float32)

        # Loss function
        self._loss = tf.reduce_mean(tf.square(self._Y - self._Qpred))
        # Learning
        self._train = tf.train.AdamOptimizer(learning_rate=l_rate).minimize(self._loss)

    def predict(self, state):
        x = np.reshape(state, [1, self.input_size])
        return self.session.run(self._Qpred, feed_dict={self._X: x})

    def update(self, x_stack, y_stack):
        return self.session.run([self._loss, self._train], feed_dict={self._X: x_stack, self._Y: y_stack})

def replay_train(mainDQN, targetDQN, train_batch):
    x_stack = np.empty(0).reshape(0, input_size)
    y_stack = np.empty(0).reshape(0, output_size)

    # Get stored information from the buffer
    for state, action, reward, next_state, done in train_batch:
        Q = mainDQN.predic(state)

        # terminal?
        if done:
            Q[0, action] = reward
        else:
            # get target from target DQN (Q')
            Q[0, action] = reward + dis * np.max(targetDQN.predict(next_state))

        y_stack = np.vstack([y_stack, Q])
        x_stack = np.vstack( [x_stack, state])

    # Train our network using target and predicted Q values on each episode
    return mainDQN.update(x_stack, y_stack)

def ddqn_replay_train(mainDQN, targetDQN, train_batch):
    '''
    Double DQN implementation
    :param mainDQN: main DQN
    :param targetDQN: target DQN
    :param train_batch: minibatch for train
    :return: loss
    '''
    x_stack = np.empty(0).reshape(0, mainDQN.input_size)
    y_stack = np.empty(0).reshape(0, mainDQN.output_size)

    # Get stored information from the buffer
    for state, action, reward, next_state, done in train_batch:
        if state is None:                                                               #####why does this happen?
            print("None State, ", action, " , ", reward, " , ", next_state, " , ", done)
        else:
            Q = mainDQN.predict(state)

            # terminal?
            if done:
                Q[0, action] = reward
            else:
                # Double DQN: y = r + gamma * targetDQN(s')[a] where
                # a = argmax(mainDQN(s'))
                # Q[0, action] = reward + dis * targetDQN.predict(next_state)[0, np.argmax(mainDQN.predict(next_state))]
                Q[0, action] = reward + dis * np.max(targetDQN.predict(next_state)) #####use normal one for now

            y_stack = np.vstack([y_stack, Q])
            x_stack = np.vstack([x_stack, state.reshape(-1, mainDQN.input_size)])   #####change shape to fit to super mario

    # Train our network using target and predicted Q values on each episode
    return mainDQN.update(x_stack, y_stack)

def get_copy_var_ops(*, dest_scope_name="target", src_scope_name="main"):

    # Copy variables src_scope to dest_scope
    op_holder = []

    src_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=src_scope_name)
    dest_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=dest_scope_name)

    for src_var, dest_var in zip(src_vars, dest_vars):
        op_holder.append(dest_var.assign(src_var.value()))

    return op_holder

def bot_play(mainDQN, env=env):
    # See our trained network in action
    state = env.reset()
    reward_sum = 0
    while True:
        env.render()
        action = np.argmax(mainDQN.predict(state))
        state, reward, done, _ = env.step(action)
        reward_sum += reward
        if done:
            print("Total score: {}".format(reward_sum))
            break

def main():
    max_episodes = 5000
    # store the previous observations in replay memory
    replay_buffer = deque()

    with tf.Session() as sess:
        mainDQN = DQN(sess, input_size, output_size, name="main")
        targetDQN = DQN(sess, input_size, output_size, name="target")
        tf.global_variables_initializer().run()

        #initial copy q_net -> target_net
        copy_ops = get_copy_var_ops(dest_scope_name="target", src_scope_name="main")
        sess.run(copy_ops)

        for episode in range(max_episodes):
            e = 1. / ((episode / 10) + 1)
            done = False
            step_count = 0
            state = env.reset()

            while not done:
                if np.random.rand(1) < e or state is None or state.size == 1:           #####why does this happen?
                    action = env.action_space.sample()
                else:
                    # Choose an action by greedily from the Q-network
                    #action = np.argmax(mainDQN.predict(state))
                    action = mainDQN.predict(state).flatten().tolist()                  #####flatten it and change it as a list
                    for i in range(len(action)):                                        #####the action list has to have only integer 1 or 0
                        if action[i] > 0.5 :
                            action[i] = 1                                               #####integer 1 only, no 1.0
                        else:
                            action[i] = 0                                               #####integer 0 only, no 0.0

                # Get new state and reward from environment
                next_state, reward, done, _ = env.step(action)
                if done: # Penalty
                    reward = -100

                # Save the experience to our buffer
                replay_buffer.append((state, action, reward, next_state, done))
                if len(replay_buffer) > REPLAY_MEMORY:
                      replay_buffer.popleft()

                state = next_state
                step_count += 1
                if step_count > 10000:   # Good enough. Let's move on
                    break

            print("Episode: {} steps: {}".format(episode, step_count))
            if step_count > 10000:
                pass
                # break

            if episode % 10 == 1: # train every 10 episode
                # Get a random batch of experiences
                for _ in range(50):
                    minibatch = random.sample(replay_buffer, 10)
                    loss, _ = ddqn_replay_train(mainDQN, targetDQN, minibatch)

                print("Loss: ", loss)
                # copy q_net -> target_net
                sess.run(copy_ops)

        # See our trained bot in action
        env2 = wrappers.Monitor(env, 'gym-results', force=True)

        for i in range(200):
            bot_play(mainDQN, env=env2)

        env2.close()
        # gym.upload("gym-results", api_key="sk_VT2wPcSSOylnlPORltmQ")

if __name__ == "__main__":
    main()












Saturday, October 14, 2017

openAI gym을 이용해서 슈퍼마리오 설치해서 자동 플레이 하기


윈도우에서 openAI Gym을 이용해서 슈퍼마리오 AI 플레이 만들기


1. 윈도우 서브시스템 리눅스에 openAI Gym 설치하기
http://jinman190.blogspot.ca/2017/10/openai-gym.html

2. openAI gym을 이용해서 슈퍼마리오 설치해서 자동 플레이 하기
지금 여기

3. 슈퍼마리오에 모두를 위한 RL 수업의 딥러닝 코드 붙이기
http://jinman190.blogspot.ca/2017/10/rl.html

4. 슈퍼마리오의 딥러닝 코드 효율적으로 고쳐보기








목표: 슈퍼마리오를 파이썬 코드로 자동 플레이 하기 (랜덤 입력으로)


우선 슈퍼마리오 소스를 openAI gym에 추가 시켜줘야 한다.
gym에는 몇몇 아타리 게임 등이 있는데 슈퍼마리오는 들어있지 않다.

내가 받은 곳은
https://github.com/ppaquette/gym-super-mario

어떤 분이 수정 보완 되었다고 알려주신 링크 (난 이걸로 안했음)
https://github.com/chris-chris/gym-super-mario



위 링크의 설명을 보면... 리눅스에서 우선 gym-pull을 설치하고


$pip install gym-pull

아래 코드를 파이썬에서 실행하면 된다는데

import gym
import gym_pull
gym_pull.pull('github.com/ppaquette/gym-super-mario') # 한번만 실행하면 됨
env = gym.make('ppaquette/SuperMarioBros-1-1-v0') # 안됨

소스 끌어오기는 되는데 게임이 실행되지 않는다.




그냥 어떻게든 직접 해보자.

git에서 직접 소스를 받는다.

야매 프로그래머인 나는 윈도우의 노예이므로 그냥 윈도우용 git 프로그램으로 받는다.

http://github.com/ppaquette/gym-super-mario





우선 위 링크 질의응답 쪽에 써있는대로 fceux를 깔아야 한다.
(일반 패미컴 게임 에뮬레이터)

$ sudo apt-get install fceux





그리고 받은 소스를 gym 환경에 복사해줘야 한다.
만약에 gym을 가상환경 없이 깔았으면
/gym 폴더가 있을텐데

(tensorflow)$ 가상 환경을 켜놓은 채로 깔았으면 다음과 같은 폴더에 gym이 있을 것이다.
/tensorflow/local/lib/python3.5/site-packages/gym


그 곳에 이 슈퍼마리오 소스의 ppaquette_gym_super_mario 폴더를 복사해줘야 한다.
주의: git에서 제일 상위 디렉토리가 아니라 ppaquette_gym_super_mario 폴더

잘못 복사하면 나중에 소스를 실행할 때
No module named 'gym.envs.ppaquette_gym_super_mario' 같은 에러가 뜬다.



윈도우의 c:/gym-super-mario/에 소스를 받았다 치고 ->

가상 환경 없이 깔린 gym이면 이렇게
$ sudo cp -r /mnt/c/gym-super-mario/ppaquette_gym_super_mario ~/gym/gym/envs

가상 환경의 gym이면 이렇게
$ sudo cp -r /mnt/c/gym-super-mario/ppaquette_gym_super_mario /tensorflow/local/lib/python3.5/site-packages/gym/envs/

본인이 받은 소스가 c 드라이브의 어디 있는지 잘 보고 디렉토리를 입력하자
(리눅스에서 받았으면 리눅스의 어디에 받았는지 확인)
주의: /mnt/c/ 까지는 소문자로만 쳐야 함






그리고 이 전 글에서 게임 이름만 바꿔서 랜덤 플레이 소스를 실행해보면

import gym
env = gym.make('SuperMarioBros-1-1-v0')
env.reset()
for _ in range(10000):
    env.render()
    env.step(env.action_space.sample()) # take a random action

에러가 난다 ㅠㅜ
error.UnregisteredEnv('No registered env with id: {}'.format(id))


이 것은 게임 정보를 gym 환경에 추가시켜주지 않아서 나는 에러이다.


이 것을 참고해서 코드를 추가하고 게임을 실행하면 된다.


윗 글에는 gym 환경에 들어가서 파일을 고치라는데 난 보기 쉽게 내가 돌릴 코드에 다 넣었다. (아무데나 추가해도 된다)



자 이제 아래 코드를 실행하면 된다.

import gym
from gym.envs.registration import register
from gym.scoreboard.registration import add_group
from gym.scoreboard.registration import add_task

register(
     id='SuperMarioBros-1-1-v0',
     entry_point='gym.envs.ppaquette_gym_super_mario:MetaSuperMarioBrosEnv',
)

add_group(
     id='ppaquette_gym_super_mario',
     name='ppaquette_gym_super_mario',
     description='super_mario'
)

add_task(
    id='SuperMarioBros-1-1-v0',
    group='ppaquette_gym_super_mario',
    summary="SuperMarioBros-1-1-v0"
)

env = gym.make('SuperMarioBros-1-1-v0')
env.reset()
for _ in range(10000):
    env.render()
    env.step(env.action_space.sample()) # take a random action
중요한 내용은 아니고 고칠 일도 없으니 그냥 복사해서 쓰면 된다.




완성. 10000프레임 실행되고 종료된다.
딥러닝 플레이가 아니라 슈퍼마리오에게 우선 랜덤으로라도 코드에서 입력을 할 수 있는지 확인하기 위한 코드이다.
저 위 코드의 env.step()의 입력을 딥러닝 코드로 바꾸면 되는 것이다.




윈도우용 VS로 코드를 쓰고 우분투 앱에서 슈퍼마리오를 돌리는 화면









Sunday, October 8, 2017

윈도우 서브시스템 리눅스에 openAI Gym 설치하기

윈도우에서 openAI Gym을 이용해서 슈퍼마리오 AI 플레이 만들기


1. 윈도우 서브시스템 리눅스에 openAI Gym 설치하기
지금 여기

2. openAI gym을 이용해서 슈퍼마리오 설치해서 자동 플레이 하기

3. 슈퍼마리오에 모두를 위한 RL 수업의 딥러닝 코드 붙이기
http://jinman190.blogspot.ca/2017/10/rl.html

4. 슈퍼마리오의 딥러닝 코드 효율적으로 고쳐보기










목표: 윈도우에서 openAI gym의 아타리 게임 플레이 하기



Sung Kim 교수님의 모두를 위한 RL 강좌를 보려고 openAI gym을 설치하다가 윈도우에서 잘 설치가 안된다는 것을 알고 시도했다.

그래서 윈도우10 스토어에 있는 우분투 앱을 깔아서 거기에 설치를 해보았는데 전부 다 잘 설치되고 실행도 잘 된다.

리눅스나 맥 없이 윈도우10만 쓰시는 분들은 시도해봐도 좋을 것 같다.

윈도우와 우분투 간에 파일이 공유되기 때문에 코딩은 전부 윈도우에서 하고 우분투에서는 실행만 해보는 것도 가능하다.


아래는 내가 따라한 인터넷 설치법 링크들


1. 윈도우용 우분투앱 설치
출처: http://prolite.tistory.com/830
---- 윈도우를 개발자 모드로 설정하라고 하는데 난 안하고 됐다.


제어판 - 프로그램 및 기능 에서 Windows 기능 켜기/끄기] 메뉴를 선택


윈도우 참가자 프로그램에서 active development 버전을 받음

위 창과 같이 Active development of Windows 옵션을 선택하면 Windows 업데이트에 새 업데이트가 있다고 뜨는데 그 업데이트를 받고 재부팅 하면 된다.

어떤 사이트는 참가자 프로그램을 하라고 하고 어떤 사이트는 개발자 모드를 하라고 하는데, 개발자 모드는 선택만 하면 되니까 그게 더 편할 것이다.



윈도우 앱스토어에 가서 우분투를 받음(안받아지면 위에서 한 설정을 다시)



이하는 일반 우분투에 설치하는 법과 같다



2. 우분투용 텐서플로 설치
출처: https://www.tensorflow.org/install/install_linux#InstallingVirtualenv
우분투 앱을 실행하고 그냥 일반 우분투용 텐서플로를 설치하면 된다.
$ sudo apt-get install python3-pip python3-dev python-virtualenv # for Python 3.n
$ virtualenv --system-site-packages -p python3 targetDirectory # for Python 3.n
$ source ~/tensorflow/bin/activate
(tensorflow)~$ pip3 install --upgrade tensorflow     # for Python 3.n



(tensorflow)~$ sudo apt-get install -y python-numpy python-dev cmake zlib1g-dev libjpeg-dev xvfb libav-tools xorg-dev python-opengl libboost-all-dev libsdl2-dev swig
$ git clone https://github.com/openai/gym.git
$ cd gym
$ pip install -e '.[all]'    # 파이썬 3.5 설치

여기서 python 3.x 버전을 쓰는 사람은 python-XXX 라고 되어 있는 패키지들 몇개를 python3-XXX 라고 바꿔 써서 설치 하라는데 난 뭐뭐를 바꿔야 되는지 몰라서 그냥 다 깔았다.

python-numpy 라고 쳐서 한번 설치하고 python3-numpy 라고 쳐서 한번 설치하고...
어차피 없는 패키지는 알아서 넘어가니까.

그러니까 내 컴퓨터엔 지금 python2 버전과 python3 버전 용이 모두 깔려 있을 것이다.





4. 주의사항


여기까지 설치하고 일반 딥러닝 코드를 실행하면 잘되는데 게임 러닝을 시도하면 NoSuchDisplayException 에러가 난다

파이썬 코드 실행 전에 우분투에서
export DISPLAY=:0
를 실행해주고
윈도우10 에서 윈도우용 xming을 설치하고 실행시켜 주면 저 에러가 나지 않는다. (윈도우용임!)

또는 클라우드 서버에서 실행하는 등의 이유로 디스플레이가 아예 없는 경우에 NoSuchDisplayException 에러가 나는데 이 때는
export DISPLAY=:99
를 실행하고 코드를 실행하면 된다. (화면 출력을 아예 안함)





5. 윈도우에서 코드 쓰고 우분투에서 실행
윈도우 메모장 같은 데서 파이썬 코드를 작성한다

import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
    env.render()
    env.step(env.action_space.sample()) # take a random action



이 코드를 c:\abc\test.py에 저장했다고 치고

우분투 앱을 열어서 아래와 같이 입력하면 코드가 실행된다.

$ source ~/tensorflow/bin/activate
(tensorflow) $ export DISPLAY=:0
(tensorflow) $ cd /mnt/c/abc
(tensorflow) /mnt/c/abc $ python3 test.py












슈퍼마리오에 모두를 위한 RL 수업의 딥러닝 코드 붙이기

윈도우에서 openAI Gym을 이용해서 슈퍼마리오 AI 플레이 만들기 1. 윈도우 서브시스템 리눅스에 openAI Gym 설치하기 http://jinman190.blogspot.ca/2017/10/openai-gym.html 2. ope...