qcoding

[강화학습]A2C (Actor-Critic)CartPole_Mountain Car 문제 본문

머신러닝 딥러닝

[강화학습]A2C (Actor-Critic)CartPole_Mountain Car 문제

Qcoding 2023. 2. 11. 16:49
반응형

* 이번 실습에서는 Actor-Critic 알고리즘을 통해 Mountain Car 문제를 해결해 보는 시간으로 Reinforce 알고리즘을 통해 Mountain Car 문제가 해결되지 않았으므로 이방법을 통해서 해결이 가능한 지 확인해 보는 Policy Based의 연장선이다.

Actor-critc은 value / policy 학습을 둘 다 진행하는 것으로 인공신경망을 통해 가치함수와 정책함수를 둘다 근사하는 것이 특징이다.

 

* 결론부터 말하면 Cartpole은 잘되지만, 역시나 Mountain Car은 잘되지 않았다.

 

이번실습은 아래와 같은 순서로 진행된다.

 

1. A2C 에 대한 간략한 이론

2. A2C의 알고리즘 구조

3. A2C CartPole / Mountain car 코드 및 리뷰

4. 평가결과

 

1. A2C 에 대한 간략한 이론

(참고 : https://www.davidsilver.uk/wp-content/uploads/2020/03/pg.pdf)

-> 앞의 Reinforce 알고리즘 소개에서 Policy를 평가하는 목적함수 (J)를 정의하였으며, 이 때 목적함수내의 state에서 action에 대한 행동가치함수 (q)를 구하는 방법으로 MDP (S , A , R , P , γ ) , P(상태전이확률), R(보상)을 모를 때 Monte Calro 방법을 사용하여 아래와 같이 θ 를 변경해 가며 최적 Policy를 Gradient Ascent 방법을 통하여 구하였다.

-> 즉, Monte Carlo 방법을 통해 아래의 Q_pi 를 G_t (리턴값)으로 대체하게 되는데, G_t(리턴은)

가치함수의 정의를 나타낼 때  사용되는 값이다. 가치함수 정의 자체가 " state s에서 받을 리턴의 기댓값"으로 정의 되어있기 때문에 Monte Carlo 방법을 통해 수많은 sampling을 통해 학습을 진행하면 이는 불편향 추정값 (unbiased estimation) 값이 된다. 다시 말하면 편향이 존재하지 않으므로 실제 존재하는 가치함수의 값과 동일하다고 볼수 있다.

 그러나 에피소드에서 움직이는 것이 확률적으로 random하기 때문에 다양한 궤적을 갖는 에피소드가 나오게 될 것이고 이는 높은 분산을 갖아 학습을 어렵게 한다.  머신러닝을 공부할 때 보면 항상 나오는 그림이 아래의 bias - variance 그래프이고 이것을 적절히 갖는 지점을 선택하는 것이 중요한 것처럼 A2C알고리즘에서는

Monte Carlo 방식이 아닌 Dqn에서 사용한 TD (Temporal diffence) - 매스텝에 대한 차이를 학습하여 variance를 낮추는 방법을 사용한다.

 

-> A2C를 살펴보면 아래와 같이 Q함수를 인공신경망의 parameter (w)로 대체한 것이며

A2C의 약어에 있는 Advantage 는 위에 있는 Q함수에서 v(가치)함수를 뺀 값으로 실제 상태 s에서 action을 취해서 얻는 이득을 의미하며 그 차이를 가지고 학습을 하면, Q값이 높은 상태에서도 학습이 잘 이뤄지게 한다. 예를 들어 State s의 가치 자체가 높아서 할수 있는 action들의 가치가 모두 높을 경우 내가 수행하는 action의 가치를 비교하기 어려우므로, 상태가치(v)를 빼주어 얻는 action을 했을 때 얻는 이득을 가지고 학습을 시키겟다는 의미로 이해하였다.

 위와 같은 식을 학습 시키기 위해서는 행동/ 상태 , 정책 이렇게 3개의 신경망이 필요하기 때문에 행동가치 Q함수를 V(가치함수)로 근사하여 표현함으로써 상태가치(v) , 정책(θ) 이렇게 2개의 파라미터를 사용하도록

변경한다.

여기까지가 구현에 필요한 이론이며, 위의 참조 pdf 를 통해서 작성하였다. 해당 pdf를 보면 마지막에 Policy gradient의 여러가지 형태가 나오는데 가치함수를 어떻게 사용하냐에 따라 다양한 형태가 나오게 된다.

이번 실습에서 사용해 볼 알고리즘은 TD Actor - Critic이다.

 

 

2. A2C의 알고리즘 구조

-> TD A2C의 1 step 구조를 살펴보면 아래와 같다.

-> 1) State에서 Action을 선택한다. ( Policy NN의 확률분포에 따라 선택 )

    2) 선택된 Action을 환경에 적용시키면 , 다음상태 , 보상, 에피소드의 완료 여부를 받는다. 

    3) 다음상태와 현재상태의 delta 만큼을 최소화하게  Value NN을 통해 가치 함수를 구하고 학습

       시킨다. 

    4) TD Error ( 상태 가시함수의 delta) 를 가지고 Policy NN의 학습을 진행한다.

 

3. A2C Mountain car 코드 및 리뷰

* 해당코드는 아래의 책을 구매해서 공부하면서 변경된 코드입니다. base는 아래의 코드와 동일합니다.

https://wikibook.co.kr/reinforcement-learning/

 

파이썬과 케라스로 배우는 강화학습: 내 손으로 직접 구현하는 게임 인공지능

“강화학습을 쉽게 이해하고 코드로 구현하기” 강화학습의 기초부터 최근 알고리즘까지 친절하게 설명한다! ‘알파고’로부터 받은 신선한 충격으로 많은 사람들이 강화학습에 관심을 가지

wikibook.co.kr

## 패키지 다운로드

!sudo apt-get install -y python-numpy python-dev cmake zlib1g-dev libjpeg-dev xvfb \
    xorg-dev python-opengl libboost-all-dev libsdl2-dev swig
!pip install pyvirtualdisplay
!pip install piglet

## gym
!pip install gym[classic_control]

##ffmpeg
!sudo apt-get install ffmpeg -y

## Import

### import
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1400, 900))
display.start()
from base64 import b64encode
from glob import glob
from IPython.display import HTML
from IPython import display as ipy_display
from gym import logger as gym_logger
from gym.wrappers.record_video import RecordVideo

import sys
import tensorflow as tf
from tensorflow import keras
from keras.utils.vis_utils import plot_model

from collections import deque
import numpy as np
import random
import gym
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
import os
import warnings
warnings.filterwarnings(action='ignore')

### 비디오 함수

#### show video func
def show_video(mode='train', filename=None):
    mp4_list = glob(mode+'/*.mp4')
    # print(mp4_list)
    if mp4_list:
        if filename :
            file_lists = glob(mode+'/'+filename)
            if not file_lists:
                print('No {} found'.format(filename))
                return -1
            mp4 = file_lists[0]
                    
        else:
            mp4 = sorted(mp4_list)[-1]

        print(mp4)
        video = open(mp4, 'r+b').read()
        encoded = b64encode(video)
        ipy_display.display(HTML(data='''
            <video alt="gameplay" autoplay controls style="height: 400px;">
                <source src="data:video/mp4;base64,%s" type="video/mp4" />
            </video>
        ''' % (encoded.decode('ascii'))))
    else:
        print('No video found')
        return -1

## early-stop class

#### early stopping by avg
class EarlyStopping_by_avg():
    def __init__(self, patience=10, verbose=0):
        super().__init__()

        self.best_avg = 0
        self.step = 0
        self.patience = patience
        self.verbose = verbose

    def check(self, avg , avg_scores):
        ## best avg가 나올경우
        if avg >= self.best_avg:
            self.best_avg = avg
            self.step = 0
            # print("avg_reset")
        ## 이전값보다 현재 avg가 높을경우
        elif len(avg_scores) > 1 and avg > avg_scores[-2]:  ### 이전 값과 비교해야하므로 -2  , -1은 지금 avg와 동일함
            self.step = 0
            # print("이전값보다 avg 높아서 reset")
        else:
            self.step += 1
            if self.step > self.patience:
                if self.verbose:
                    print('조기 종료')
                return True
        return False

## Agent ( Actor Critic )

class ActorCritic():
    def __init__(self, state_size, action_size):
        ## 상태 및 행동 size 정의
        ## stae = 2가지 정보 , action = 3가지 정보
        self.state_size = state_size
        self.action_size = action_size

        # ActorCritic 하이퍼 파라메터
        ## carpole = 0.98  / mountain_car = 0.999
        self.discount_factor = 0.99
        self.learning_rate = 0.001

        # ActorCritic 신경망 모델 생성
        self.model = self.actor_critic_dnn()
        
        # 최적화 알고리즘 설정, 미분값이 너무 커지는 현상을 막기 위해 clipnorm 설정
        self.optimizer = keras.optimizers.Adam(learning_rate = self.learning_rate, clipnorm=5.0)
        
        
    # 정책신경망으로 행동 선택
    def get_action(self, state):
        ## policy 선택
        policy , value = self.model(state)
        policy = np.array(policy[0])
        action =  np.random.choice(self.action_size, 1, p=policy)[0]
        # print(f'action : {action} , policy:{policy}')
        return action
        
        
    # Dnn 모델 생성   
    def actor_critic_dnn(self):
        ### state가 들어감
        input_ = keras.layers.Input(shape=(self.state_size))

        ### Actor (정책평가)
        actor_fc = keras.layers.Dense(64, activation='tanh')(input_)
        actor_fc = keras.layers.Dense(32, activation='tanh')(actor_fc)
        policy = keras.layers.Dense(self.action_size, activation='softmax', kernel_initializer=keras.initializers.RandomUniform(-1e-3, 1e-3))(actor_fc)

        ## Critic (가치평가)
        critic_fc1 = keras.layers.Dense(128, activation='tanh')(input_)
        critic_fc2 = keras.layers.Dense(64, activation='tanh')(critic_fc1)
        critic_fc3 = keras.layers.Dense(24, activation='tanh')(critic_fc2)
        value = keras.layers.Dense(1, kernel_initializer=keras.initializers.RandomUniform(-1e-3, 1e-3))(critic_fc3)

        ## model
        model = keras.models.Model(inputs=[input_], outputs=[policy, value])

        return model   
        
        
    # 정책신경망 업데이트
    # 각 타임스텝마다 정책신경망과 가치신경망을 업데이트
    def train_model(self, state, action, reward, next_state, done):
        model_params = self.model.trainable_variables
        with tf.GradientTape() as tape:
            policy, value = self.model(state)
            _, next_value = self.model(next_state)
            target = reward + (1 - done) * self.discount_factor * next_value[0]

            # 정책 신경망 오류 함수 구하기
            one_hot_action = tf.one_hot([action], self.action_size)
            action_prob = tf.reduce_sum(one_hot_action * policy, axis=1)
            cross_entropy = - tf.math.log(action_prob + 1e-5)
            advantage = tf.stop_gradient(target - value[0])
            actor_loss = tf.reduce_mean(cross_entropy * advantage)      

            # 가치 신경망 오류 함수 구하기
            # critic_loss = self.loss_fn( tf.stop_gradient(target) , value[0])  ### MeanSquaredError = tf.reduce_mean( tf.square )
            critic_loss = 0.5 * tf.square(tf.stop_gradient(target) -  value[0])  
            critic_loss = tf.reduce_mean(critic_loss)

            # 하나의 오류 함수로 만들기
            loss = 0.2 * actor_loss + critic_loss

        # 오류함수를 줄이는 방향으로 모델 업데이트
        grads = tape.gradient(loss, model_params)
        self.optimizer.apply_gradients(zip(grads, model_params))
        return None

## Env(Cartpole) 

#### 학습 환경
# CartPole 환경 정의
ENV_NAME = 'CartPole-v1'
env = gym.make(ENV_NAME)

# 비디오 레코딩
env = RecordVideo(env, './train', episode_trigger =lambda episode_number: True )
env.metadata = {'render.modes': ['human', 'ansi']}

# CartPole 환경의 상태와 행동 크기 정의
state_size = env.observation_space.shape[0]
action_size = env.action_space.n

load_model=False

# 위에서 정의한 DQN 클래스를 활용하여 agent 정의
agent = ActorCritic(state_size, action_size)

if load_model:
  # 위에서 정의한 DQN 클래스를 활용하여 agent 정의
  load_model = '200th'
  agent.model.load_weights(f'save_model/mountain_model/{load_model}/')

# 반복 학습 에피소드 수 정의
num_episode = 1000
early_stopping_by_avg = EarlyStopping_by_avg(patience=30, verbose=1)

## early stopping을 위한 초기값 설정 
print_interval = 20
avg_reward_episode = 0
scores, avg_scores, episodes, losses = [], [], [], []


for epoch in range(num_episode):
    # done flag와 score 값 초기화
    done = False
    score = 0
    step = 0
    rewards_list = [] 

    # 환경 reset을 통해 초기 상태 정의 --> state는 [car_position , car_velocity] 2개의 값을 받는데 
    # car_position = -0.6 ~ 0.4 사이의 값을 받으며 , car_velocity = 0 을 받음
    state = env.reset()
    # print(f'init_state : {state}')
    
    # print(f"avg: {avg_step}")
    if early_stopping_by_avg.check(avg_reward_episode , avg_scores ):
        print("earstpping 실행")
        break
      
    # print(f'epoch : {epoch}번째 수행 중')
    while not done:

        # 현재 상태에 대하여 행동 정의
        # action = agent.policy(init_state[np.newaxis,:]) ### network에 넣어 주기 위해서 기존 (2,) 배열을 (1,2)로 축을 추가함
        action = agent.get_action(np.expand_dims(state, axis=0))
        ### 위와 같은 의미 np.expand_dims(a, axis=0)
        
        next_state, reward, done, info = env.step(action)
        
        # 해당 에피소드의 최종 score를 위해 reward 값 누적  -> 환경에서 주는 reward 적산
        score += reward

        # 기본 환경은 pole이 쓰러지지 않으면 +1의 보상을 준다.
        # 자신만의 보상가설을 만들어 학습 가능
        ### 종료조건
        # 폴 각도는 ±12° 이상입니다.
        # 카트 위치가 ±2.4 이상(카트 중앙이 디스플레이 가장자리에 도달함)
        # 에피소드 길이가 200보다 큽니다.
        
        def get_reward(pos, angle , done):
            ### 위치 / 속도 조건으로 보상크게
            cond_pos = (pos < 2.0) and (pos > -2.0)
            cond_angle = (angle < 5.0) and (angle > -5.0)
            ### 상점
            if cond_pos or cond_angle:
                return 0.1
            elif cond_pos:
                return 0.2
            elif cond_pos and cond_angle:
                return 0.3
            ### 벌점
            elif (pos > 2.5) or (pos < -2.5):
                return -0.1
            elif (angle > 10.0) or (angle < -10.0):
                return -0.2
            
            
        ### position
        pos = next_state[0]
        ### velocity
        angle = next_state[2]
        reward = get_reward(pos, angle, done)  ## agent가 받는 보상설계

        # reward = 0.1 if not done or score == 500 else -1  ## agent가 받는 보상설계

        ## 매스텝 마다 신경망 업데이트
        ## 학습할때 사용할 next_state의 shape도 맞춰줌  
        ### network에 넣어 주기 위해서 기존 (2,) 배열을 (1,2)로 축을 추가함 np.expand_dims(state, axis=0)
        agent.train_model(np.expand_dims(state, axis=0), action, reward, np.expand_dims(next_state, axis=0), done)

        # 다음 상태를 현재 상태로 정의
        state = next_state
                    
        if done:            
             ### early stop
            avg_step = np.mean(scores[-10:])


            # 에피소드 종료마다 결과 그래프 저장
            scores.append(score)
            avg_scores.append(avg_step)
            episodes.append(epoch)

            
            # 에피소드 종료마다 결과 출력
            if epoch % print_interval == 0:
              print(f'episode: {epoch:3d} | avg_score: { avg_step :3.2f}')

            # 100 에피소드마다 모델 저장
            if epoch % 500 == 0:
               agent.model.save_weights(f'save_model/cartpole_model/{epoch}th/', save_format='tf')

            # 이동 평균이 400 이상일 때 종료
            if avg_step > 400:
               agent.model.save_weights(f'save_model/cartpole_model/final/', save_format='tf')
               sys.exit()
            

env.close()

plt.title('Test graph')
plt.xlabel('episodes')

plt.plot(episodes, avg_scores,
         color='skyblue',
         marker='o', markerfacecolor='blue',
         markersize=6)
plt.ylabel('avg_scores', color='blue')
plt.tick_params(axis='y', labelcolor='blue')

plt.savefig('cartpole_graph.png')
plt.show()

 

## 결과보기

### max episode
### nan이 젤 큰값이므로 이값을제거하고 계산함
avg_scores_fil = [x for x in avg_scores if np.isnan(x) !=True]
episode=np.argmax(avg_scores_fil)
# episode=88
filename = 'rl-video-episode-{}.mp4'.format(episode)
print("최대 avg : {} ,에피소드 번호 : {}".format(max(avg_scores_fil) , episode))
show_video(filename=filename)

--> CartPole의 경우는 아래와 같이 1000 에피소드를 하는 동안 400점이상의 높은 점수를 얻으며 문제를 해결할 수 있었다. 

보상의 경우 아래와 같이 설정하였으며, 보상설계를 잘 할 경우 학습이 잘되는 경향을 보였다.

기존의 dqn에서는 done값을 가지고 에피소드가 끝날경우 페널티를 주어서 에피소드가 끝나는 것을 막앗는 데, 해당 부분은 삭제 한 후 보상전체를 좀 낮춰서 설계하였다.

        def get_reward(pos, angle , done):
            ### 위치 / 속도 조건으로 보상크게
            cond_pos = (pos < 2.0) and (pos > -2.0)
            cond_angle = (angle < 5.0) and (angle > -5.0)
            ### 상점
            if cond_pos or cond_angle:
                return 0.1
            elif cond_pos:
                return 0.2
            elif cond_pos and cond_angle:
                return 0.3
            ### 벌점
            elif (pos > 2.5) or (pos < -2.5):
                return -0.1
            elif (angle > 10.0) or (angle < -10.0):
                return -0.2

사실 아래와 같이 보상 설계를 하여도 문제가 해결 되는 것을 확인하였다.

reward = 0.1 if not done or score == 500 else -1  ## agent가 받는 보상설계

 

 

 

## Env(Mountain Car) 

#### 학습 환경
# CartPole 환경 정의
ENV_NAME = 'MountainCar-v0'
# ENV_NAME = 'MountainCarContinuous-v0'
env = gym.make(ENV_NAME)

# 비디오 레코딩
env = RecordVideo(env, './train', episode_trigger =lambda episode_number: True )
env.metadata = {'render.modes': ['human', 'ansi']}

# CartPole 환경의 상태와 행동 크기 정의
state_size = env.observation_space.shape[0]
action_size = env.action_space.n
# action_size = env.action_space.shape[0]

# max_action = env.action_space.high[0]

load_model=False

# 위에서 정의한 DQN 클래스를 활용하여 agent 정의
agent = ActorCritic(state_size, action_size)

if load_model:
  # 위에서 정의한 DQN 클래스를 활용하여 agent 정의
  load_model = '200th'
  agent.model.load_weights(f'save_model/mountain_model/{load_model}/')

scores, avg_scores, episodes ,avg_rewards  = [], [], [], [] 

# 반복 학습 에피소드 수 정의
num_episode = 500
early_stopping_by_avg = EarlyStopping_by_avg(patience=30, verbose=1)

## early stopping을 위한 초기값 설정 
avg_reward_episode = 0
success = 0
max_position = -0.4
print_interval = 1

scores, episodes = [], []

for epoch in range(num_episode):
    # done flag와 score 값 초기화
    done = False
    score = 0
    step = 0
    rewards_list = [] 

    # 환경 reset을 통해 초기 상태 정의 --> state는 [car_position , car_velocity] 2개의 값을 받는데 
    # car_position = -0.6 ~ 0.4 사이의 값을 받으며 , car_velocity = 0 을 받음
    state = env.reset()
    # print(f'init_state : {state}')
    
    # print(f"avg: {avg_step}")
    if early_stopping_by_avg.check(avg_reward_episode , avg_scores ):
        print("earstpping 실행")
        break
      
    # print(f'epoch : {epoch}번째 수행 중')
    while not done:

        # 현재 상태에 대하여 행동 정의
        # action = agent.policy(init_state[np.newaxis,:]) ### network에 넣어 주기 위해서 기존 (2,) 배열을 (1,2)로 축을 추가함
        action = agent.get_action(np.expand_dims(state, axis=0))
        ### 위와 같은 의미 np.expand_dims(a, axis=0)
        
        # env.step 함수를 이용하여 행동에 대한 다음 상태, 보상, done flag 등 획득
        ### return ex) nex_state=[-0.57330334 -0.00063329]
        ###            reward=-1.0
        ###            done=False
        ###            info={}
        next_state, reward, done, info = env.step(action)
        


        ### reward 설계
        #### 목표는 가능한 한 빨리 오른쪽 언덕 위에 놓인 깃발에 도달하는 것이므로 에이전트는 각 타임스텝에 대해 -1의 보상으로 페널티를 받습니다.
        #### 다음 중 하나가 발생하면 에피소드가 종료됩니다.

        ###종료: 자동차의 위치가 0.5보다 크거나 같습니다(오른쪽 언덕 위의 목표 위치).
        ###잘림: 에피소드 길이는 200입니다.

        ### reward 설계
        #### 목표는 가능한 한 빨리 오른쪽 언덕 위에 놓인 깃발에 도달하는 것이므로 에이전트는 각 타임스텝에 대해 -1의 보상으로 페널티를 받습니다.
        #### 다음 중 하나가 발생하면 에피소드가 종료됩니다.

        ###종료: 자동차의 위치가 0.5보다 크거나 같습니다(오른쪽 언덕 위의 목표 위치).
        ###잘림: 에피소드 길이는 200입니다.
        reward=0.1 if not done else -1
        
        ### position에 따라서 action이 맞으면 reward를 줌
        car_pos = next_state[0]
        car_vel = next_state[1]

        # def get_reward(car_pos, car_vel,max_position,step):
          ## 2차함수로 만들어 속도가 커지게 더큰 리워드를 위치에 따라 받게함
        if car_vel > 0:
          reward = float(((car_pos+0.5)*20)**2/10+15*car_vel) 
        else:
          reward = float(((car_pos+0.5)*20)**2/10) 

          ### max position   
        if car_pos > max_position:
          ## max position
          max_position = car_pos 

          ## 성공 시 success
        if car_pos >= 0.5:
           reward=100
           success +=1
  
        else:
          score -= 1  

        step += 1


        # print(f'reward : {reward}')

        # 획득된 상태, 행동, 보상, 다음상태, done flag를 리플레이 버퍼에 축적
        rewards_list.append(reward)

        ## 매스텝 마다 신경망 업데이트
        ## 학습할때 사용할 next_state의 shape도 맞춰줌  
        ### network에 넣어 주기 위해서 기존 (2,) 배열을 (1,2)로 축을 추가함 np.expand_dims(state, axis=0)
        agent.train_model(np.expand_dims(state, axis=0), action, reward, np.expand_dims(next_state, axis=0), done)

        # 다음 상태를 현재 상태로 정의
        state = next_state
                    
        if done:            
            ### early stop
            avg_score_episode = np.mean(scores[-10:])
            avg_reward_episode = np.mean(rewards_list)


            # 에피소드 종료마다 결과 그래프 저장
            #### reward --> 매 스텝에서 받은 reward의 양 ( state에서 알맞는 action을 많이 할 수록 reward가 커짐)
            avg_rewards.append(avg_reward_episode)


            #### score --> 환경에서 reward는 매 step마다 -1 감소 인데, 200 step이 되면 종료되므로, -200 보다 커질수록 높은 score

            scores.append(score)
            avg_scores.append(avg_score_episode)
            episodes.append(epoch)

            
            # 에피소드 종료마다 결과 출력
            if epoch % print_interval == 0:
               print(f'episode: {epoch:3d} | success: {success} | car_pos_max : {max_position : .3f} | avg_reward : {avg_reward_episode : .3f} | score_avg : {avg_score_episode : .3f} |  step : {step} ')
            
            # 100 에피소드마다 모델 저장
            if epoch % 200 == 0 or epoch % num_episode == 0:
               agent.model.save_weights(f'save_model/mountain_model/{epoch}th/', save_format='tf')
               print("model 저장 ")

env.close()

        
plt.title('Test graph')
plt.xlabel('episodes')

plt.plot(episodes, avg_scores,
         color='skyblue',
         marker='o', markerfacecolor='blue',
         markersize=6)
plt.ylabel('avg_scores', color='blue')
plt.tick_params(axis='y', labelcolor='blue')
plt.savefig('cartpole_graph.png')
plt.show()

--> 학습을 많이 시켜도 실패하였다. Mountain Car 문제는 생각보다 어려운 문제인 것 같다.

오른쪽 언덕과 왼쪽 언덕에서의 각각 강화해야 되는 행동이 다르며, 보상이 직관적이지 않고 먼 미래에 큰 보상을 받으므로 다양한 환경을 탐험을 좀더 해보는 것이 필요할 것 같고, dqn에서 replay 메모리를 사용하는 것과 같은 off-policy 방법이 필요할 것도 같다.

다음 실습은 A3C 실습으로 Mountain Car 문제를 접근해 보려고 한다.

 

A2C.ipynb
0.25MB

반응형
Comments