강화 학습(Reinforcement Learning)

강화학습 Stochastic FrozenLake-v3 DQN

coding art 2022. 1. 7. 19:12
728x90

텐서플로우 regression 방식으로 학습하는 알고리듬을 검토해 보자.  이 알고리듬은 유튜브 sung kim의 동영상 강좌 lab 7-1:DQN 1(NIPS 2013) (https://www.youtube.com/watch?v=Fbf9YUyDFww )에서 설명하는 코드 내용을 그대로 타이핑하여 작성하였다. 영상 저자에 의하면 이 샘플 코드의 알고리듬은 이세돌과의 바둑대국 알파고로 유명세를 떨쳤던 영국의 인공지능 회사 지금은 이미 구글에 흡수되어버린 Deep Mind 사에서 개발한 알고리듬으로서 국제적으로 유명한 탑클래스 학술지인 Nautre지에 2013년 소개된 논문이라고 한다.  아울러 reinforcemt learning 을 연구하시는 분은 꼭 sung kime 의 구독자가 되셔서 강의 6-1부터 순차적으로 리뷰하시길 권고드립니다. 

 

아래의 코드를 실행시키기 위해서는 반드시 GPU 도움이 필요하며 아울러 텐서플로우 1.15.0 버전으로 살행해야 한다. 왜냐하면 tensorflow 코드 중에 버전 1.15.0 이하에서 사용하는  placeholder 용법이 사용되기 때문이다. 하지만 최근 아나콘다에서 아주 낮은 과거의 버전 install 이 금지되어 버린 듯하다. 따라서 아래의 코드 실행을 위해서는 GPU 서비스가 무료인 구글 Colab에서 런타임 유형을 GPU 로 설정 후 다음과 같이 tensorflow 버전을 1.15.0 로 install 하자.

구글 Colab은 리눅스 기반이므로 다음과 같이 gym 라이브러리를 설치한다.

아울러 아래의 Display 라이브러리를 함께 설치한다. 이 라이브러리가 Frozen Lake 에 필요한지는 모르겠으나 이어지는 CartPole 코드를 실행시켜 그래픽 출력을 얻어내는데 필수적이다.

그밖에 웬만한 라이브러리는 다 지원되므로 아래의 코드 전체를 하나의 셀에 모조리 copy & paste 하여 실행하기 바란다. 그래도 다소 실행 시간이 소요된다. 다음은 실행 결과로 얻어지는 그래프이다.

#DQN_01.py

!pip install tensorflow==1.15.0
 
!apt-get install x11-utils > /dev/null 2>&1 
!pip install pyglet > /dev/null 2>&1 
!apt-get install -y xvfb python-opengl > /dev/null 2>&1
!pip install gym pyvirtualdisplay > /dev/null 2>&1
 
from IPython import display as ipythondisplay
from pyvirtualdisplay import Display
display = Display(visible=0, size=(400300))
display.start()

 

import gym
import numpy as np
import tensorflow as tf #version 1.15.0
import matplotlib.pyplot as plt

env = gym.make('FrozenLake-v1')

input_size = env.observation_space.n
output_size = env.action_space.n
learning_rate= 0.1

X = tf.placeholder(shape=[1, input_size], dtype=tf.float32)
W = tf.Variable(tf.random_uniform([input_size, output_size],0,0.01))

Qpred = tf.matmul(X, W)
Y = tf.placeholder(shape=[1, output_size], dtype=tf.float32)

loss = tf.reduce_sum(tf.square(Y - Qpred))
train = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss)

#Q = np.zeros([env.observation_space.n,env.action_space.n])
#print(env.observation_space.n,env.action_space.n)
num_episodes = 2000
gamma = 0.99

rList = []

def one_hot(x):
    return np.identity(16)[x:x+1]

init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)

    for i in range(num_episodes):
        s = env.reset()
        e = 1./((i/50) + 10)
        rAll = 0
        done = False
        #local_loss = []
    
        while not done:
            Qs=sess.run(Qpred,feed_dict={X: one_hot(s)})
            if np.random.rand(1) < e:
                a = env.action_space.sample()
            else:
                a = np.argmax(Qs)

            s1, reward, done, _ = env.step(a)
            if done:
                Qs[0,a] = reward
            else:
                Qs1 = sess.run(Qpred, feed_dict={X: one_hot(s1)})
                Qs[0, a] = reward + gamma* np.max(Qs1)
            sess.run(train, feed_dict={X: one_hot(s), Y:Qs})
            rAll += reward
            s = s1
        rList.append(rAll)


print("Percent of Sucess Rate: ", (sum(rList)/num_episodes))
plt.bar(range(len(rList)), rList, color="blue")
plt.show()