본문 바로가기

유니티 ML Agents/머신러닝과 강화학습 코딩

8. 카트폴 DQN 강화학습

카트폴 DQN 강화학습 예제 기본 구성


폴이 바닥으로 쓰러지지 않도록 카트를 좌우로 움직이는 게임인 카트폴 DQN 학습 과정은 두 단계로 구성된다. 학습 데이터의 시간적 상관관계를 없애기 위한 리플레이 메모리를 생성하는 단계와 리플레이 메모리에서 데이터를 무작위로 추출해 학습하는 미니 배치 단계가 그것이다.

기본 개념


리플레이 메모리 생성 단계는 우선 (1)-1 카트폴을 초기화 함으로써 무작위 행동을 유발하고 임의의 상태(state)를 출력한다. (1)-2 다음으로 초기화된 인공신경망 모델에 상태를 입력해 큐 값을 출력으로 반환 받아 (1)-3 입실론 탐욕 정책을 통해 적절한 행동을 출력한다. (1)-4 다음으로 앞에서 얻어진 모든 데이터를 종합해서 리플레이 메모리에 저장하고 (1)-5 새로운 상태를 인공신경망 모델에 입력해서 큐 값을 출력해 앞의 과정을 반복한다.


리플레이 메모리 생성을 몇 번 반복하는 지는 스텝(step)과 에피소드(episode)를 통해 결정된다. 스텝은 폴이 떨어지지 않을 때까지 카트를 좌우로 움직인 횟수를 의미하며, 에피소드는 하나의 스텝이 종료되고 다시 종료될 때까지 게임을 몇 번을 반복하는지에 대한 설정이다. 스텝은 게임이 스스로 결정하지만 에피소드는 학습자가 결정한다. 즉 카트폴 게임이 종료되지 않을 때까지 반복 실행한 스텝 수와 학습자가 종료된 게임을 몇 회까지 반복실행하도록 설정한 에피소드의 곱으로 리플레이 메모리가 몇 번 생성되는지 결정된다.


미니 배치 단계에서는 리플레이 메모리에 있는 데이터를 활용해 인공신경망 모델을 개선한다. (2)-1 먼저 리플레이 메모리에서 일정 크기의 데이터 세트를 무작위로 꺼낸다.


리플레이 메모리에서 가져온 데이터 세트는 상태(state), 행동(action), 보상(reword), 다음상태(next state) 그리고 종료 여부(done)로 각각 구성된다. 리플레이 메모리에서 어느 정도 크기의 데이터 세트를 가져올 지는 하이퍼파라미터를 통해 학습자가 결정한다.


데이터 세트에서 데이터를 하나씩 꺼내 학습을 진행하는데 먼저 (2)-2 상태를 모델에 입력해 큐 값을 출력으로 얻어 낸다. DQN에서 모든 데이터는 인공신경망에 저장되어 있고 모델을 사용해 값을 근사하기 때문에 상태를 입력하면 출력으로 큐 값을 얻을 수 있다.


(2)-3 다음으로 최적 큐함수를 통해 큐 값 중 가장 큐 값을 얻어내고 리플레이 메모리에서 가져온 행동(선택된 행동)과 일치하는 Q 값을 갱신한다. 여기서 잠깐 Q 값에서 행동이 의미하는 것이 무엇인지 알아보자. 카트폴에서 행동은 좌우 두 가지가 있다. 좌는 0으로 우는 1로 표현할 수 있으며 이것은 배열로 구성된 Q 값의 인덱스가 된다. 즉 선택된 행동이란 수학적으로 배열의 인덱스를 의미한다. 마지막으로 새로운 Q값을 사용해 모델을 개선한다. 모델 개선 작업의 횟수는 리플레이 메모리에서 가져온 데이터세트의 크기와 미니 배치 사이즈에 의해 결정되며 이 모든 데이터는 학습자가 입력하는 하이퍼파라미터에의해 결정된다.


카트폴 DQN 강화학습 예제 Agent 클래스 구조


Agent 클래스 구조


DQN 학습을 위해서 먼저 Agent클래스를 생성해보자. Agent 클래스는 카트폴을 실행하고 학습을 위한 모델을 구성하며 학습을 진행하는 기능을 가지고 있다. Agent 클래스는 모두 8개의 함수로 구성되는데 각각 어떤 기능을 하는지 알아보면서 DQN이 코드로 어떻게 구현되는지 알아보자.


(1) __init__함수는 클래스가 호출될 때 자동으로 불려지며 클래스 변수의 초기화와 딥러닝을 위한 준비작업을 담당한다. 먼저 클래스 변수에는 학습에 사용한 하이퍼파라미터가 저장되어 있고 클래스를 생성할 때 초기 값을 인자로 받아 해당 변수를 초기화 한다또한 딥러닝을 위해 몇 개의 레이어를 사용할 지 그리고 각각의 레이어는 몇 개의 노드로 구성할지 설정하는 네트워크 구성 작업을 진행한다. 마지막으로 손실 함수를 정의하는데 예측값과 실제값의 차이를 어떤 방식으로 최소화하면서 학습할지 결정한다.


(2) init_variables 함수는 단순하게 텐서플로우에서 정의한 변수를 초기화하는 기능을 담당한다. Agent 클래스가 생성된 후 바로 호출된다.


(3) train 함수는 본격적으로 강화 학습을 수행한다. train 함수는 내부적으로 리플레이 메모리를 생성하는 take_action_and_append_memory 함수와 리플레이 메모리에서 데이터를 가져와서 학습을 진행하는 train_mini_batch 함수 그리고 학습이 완료되면 모델을 파일로 저장하는 save_model 함수를 호출하면서 동작을 수행한다.


(4) take_action_and_append_memory 함수는 학습을 진행하지 않고 딥 네트워크에서 큐 값을 얻어 카트폴을 실행시키고 결과값을 받아 리플레이 메모리에 저장한다. 이 동작은 카트폴 게임이 종료될 때까지 계속된다.


(5) get_epsilon 함수는 에이전트가 탐험할 수 있는 확률인 입실론 값을 계산하고 반환하는 동작을 수행한다. 하이퍼파라미터로 설정한 입실론 값을 초기에 사용하며 시간에 지나면서 입실론 값이 일정 비율로 감소(decay)하도록 설계되어 있다.


(6) greed_search 함수는 입실론 탐욕 정책에 따라 입력 받은 큐 값에 따라 행동(action)을 결정하는 동작을 수행한다. 랜덤하게 선택한 값이 입력 받은 입실론 값보다 크면 최적의 행동을 선택하고 작으면 랜덤한 행동을 선택한다.


(7) train_mini_batch 함수는 리플레이 메모리에 저장된 데이터를 랜덤으로 선택해 모델을 학습하는 동작을 수행한다. 랜덤으로 선택하는 데이터의 크기는 하이퍼파라미터로 설정한다.


(8) save_model 함수는 학습한 딥러닝 모델을 파일로 저장하는 동작을 수행한다. 저장된 모델은 나중에 그대로 로딩에서 별도의 학습 과정없이 사용할 수 있다.


카트폴 DQN 강화학습 예제 하이퍼파라미터


Agent 하이퍼파라미터 설정


DQN 예제에서 사용되는 하이퍼파라미터에 대해 살펴보자.


(1) REPLAY_MEMORY_LIMIT은 리플레이 메모리 크기를 결정하는 파라미터이다. 데이터가 REPLAY_MEMORY_LIMIT 이상으로 들어오면 가장 먼저 저장한 데이터를 지우도록 설계했다.


(2) REPLAY_SIZE 파라미터는 리플레이 메모리를 사용해서 모델을 학습할 때 몇 개의 데이터 세트를 가져올 지 결정한다.


(3) 입실론 탐욕정책을 위해서 모두 세 개의 파라미터가 사용되는데 EPSILON은 초기 입실론 값을 설정한다. 이 값이 클 수록 초기에 무작위 행동이 선택될 가능성이 높아진다. EPSILON_DECAY은 학습이 진행됨에 따라 어느 정도의 비율로 입실론 값이 줄어 들지 결정한다. 예를 들어 0.2로 설정되면 20% 정도의 에피소드가 진행되면 입실론 값은 최소 값으로 줄어들게 된다.


(4) LEARNING_RATE 파라미터는 비용 함수에 사용되는데 최적화 속도를 결정한다. LEARNING_RATE1에 가까울 수록 학습이 최적화가 진행되며 0에 가까울 수록 최적화가 더디게 진행된다.


(5) NODE_NUM은 인공신경망 네트워크를 구성할 때 각 레이어에 들어갈 노드 수를 결정한다. 노드 수가 많을 수록 복잡한 구조의 네트워크가 구성된다.


(6) DISCOUNT_RATE는 최적 큐함수에서 사용되는 파라미터로써 미래에 얻는 보상을 얼마의 비율로 할인해서 현재의 가치로 계산할 지 결정한다.


(7) EPISODE_NUM은 몇번의 게임을 실행할 지 결정하는 파라미터이다. 카트폴 게임은 폴이 바닥에 닿기 전까지 게임이 계속되며 폴이 바닥에 닿으면 게임이 종료된다. 이것이 하나의 에피소드이다.


(8) 리플레이 메모리를 활용한 미니배치 학습에는 두 가지 파라미터가 사용된다. MINIBATCH_SIZE는 리플레이 메모리에서 얼마 크기의 데이터를 가져올 지 결정하는 파라미터이다. MINIBATCH_STEP_SIZE은 몇 번의 에피소드 마다 미니배치 학습을 할 지 결정하는 파라미터이다. MINIBATCH_STEP_SIZE100으로 설정되면 100번의 에피소드마다 미니배치 학습이 진행된다.

 

카트폴 DQN 강화학습 예제 __init__ init_variables 함수


Agent 클래스 __init__ 함수 클래스 변수 설정


__init__ 함수의 클래스 변수 설정하는 부분을 살펴보자. 다른 나머지 변수는 앞서 설명한 하이퍼파라미터 부분을 참조하면 된다. 프로그램을 이해하는데 핵심적인 몇가지 변수에 대해 알아보자.


(1) 카트폴 프로그램을 생성해서 env 변수에 저장한다. 앞으로 카트폴 프로그램을 실행하기 위해서는 env 변수에 저장된 객체를 참조할 것이다. (2) replay_memory 는 리플레이 메모리가 저장될 변수로 배열로 선언했다. (3) input_size는 카트폴 게임에서 카트가 플레이어가 인식하는 환경을 몇 개의 변수로 처리하는지를 나타낸다. Input_size 만큼 인공신경망의 입력 값이 정해진다. (4) output_size는 플레이어가 할 수 있는 행동의 종류를 나타낸다. 카트는 좌/우로만 움직일 수 있기 때문에 여기에서는 2로 설정된다.


Agent 클래스 __init__ 함수 네트워크 구성


이제 인공신경망 네트워크를 구성해보자.


(1) 입력과 출력 변수를 정의한다. 입력(X)는 앞에서 정의한 input_size(4)만큼 실수형으로 정의된다. 출력(Y) 또한 output_size(2) 만큼 실수형의로 정의 된다.


(2) 가중치를 정의하는 부분이다. 가중치는 행렬의 형태로 정의되는데 입력 레이어와 출력 레이어의 사이즈는 정해져 있고 중간에 사용하는 노드의 크기는 사용자가 임의로 설정할 수 있다.

입력 레이어(L1)에 사용되는 가중치(w1)input_size x node_num 크기의 행렬로 정의했다. Input_size는 카트폴 게임에서 4로 고정되어 있지만 node_num은 학습자가 임으로 변경할 수 있다. node_num300으로 설정한 경우 4 x 300 행렬로 정의된다.

중간 레이어(L2)에서 사용하는 가중치 (w2)node_num x node_num 크기의 행렬로 정의했다. 행과 열의 크기를 서로 다르게 할 수 있지만 중간 레이어를 추가할 경우 일괄적으로 노드 개수를 설정하기 위해 동일한 크기로 설정했다. Node_num300으로 설정한 경우 300 x 300 행렬로 정의된다.


출력 레이어(Q_model)에서 사용하는 가중치(w3)node_num x output_size로 정의했다. node_num은 이전 레이어와 동일하며 output_size는 모델의 출력 값 플레이어가 취할 수 있는 행동(action)의 개수와 동일하다.

가중치를 초기화하기 위해 xavier_initializer() 함수는 기존에 균등 분포나 가우시안 분포를 가진 데이터로 변수를 초기화 했을 때 보다 좀 더 성능이 향상된 변수 초기화 기능을 제공한다고 생각하면 쉽다. 자세한 기능에 대한 설명은 이 책이  범위에서 벗어나기 때문에 생략하기로 한다.


(3) 편향을 설정해야 하는데 입력 값에 곱해지는 가중치와 다르게 편향은 더해지기 때문에 단일 변수로 설정할 수 있다. 편향은 0으로 초기화해서 사용한다.


(4) 이제 구체적인 레이어의 형태를 정의할 차례이다. 입력 레이어(L1)는 입력 값(X)와 가중치(w1)을 곱하고 편향(b1)을 더해서 마지막으로 relu 활성 함수를 사용하도록 정의했다.


중간 레이어 (L2)는 입력 값으로 입력 레이어의 출력 값인 L1 변수를 사용했고 레이어 구성은 동일하게 가중치(w2)를 곱하고 편향(b2)를 더 한 다음 마지막으로 relu 활성 함수를 사용해서 구성했다출력 레이어 (Q_model) 또한 앞에서 정의한 입력 레이어와 중간 레이어와 동일한 방식으로 구성했다


Agent 클래스 __init__ 함수 학습모델 완성


네트워크 구성이 끝났으면 손실 함수를 정의하고 학습 모델을 완성해보자. (1) 실제 값(Y)와 모델의 결과값(Q_model)의 차를 제곱한 합계(reduce_sum)를 손실 함수로 정의했다. 앞서 살펴본 머신러닝과 딥러닝에서는 reduce_mean 함수를 사용해서 평균을 구했지만 누적 보상의 합의 최대화하는 강화학습의 특성 때문에 평균이 아닌 합계를 사용했다.


(2) 최적화 함수로는 AdamOptimizer를 사용했다. GradentDecent 함수보다 성능이 향상된 최적화 함수 정도로 알아두자. 보다 구체적

인 기능을 알고자 한다면 텐서플로우 문서(https://www.tensorflow.org/api_docs/python/tf/train/AdamOptimizer)를 참고하기 바란다.


(3) 마지막으로 학습 모델을 완성했는데 AdamOptimizer를 사용해서 손실이 쵯화 되는 방향으로 학습하도록 모델을 설계했다.


Agent 클래스 init_variables 함수


Agent 클래스의 init_variables 함수는 텐서 플로에서 사용하는 모든 변수를 초기화하는 역할을 담당한다. Agent 클래스가 생성된 후 바로 호출된다.

 

카트폴 DQN 강화학습 예제 - train 함수


Agent 클래스 train 함수


train 함수는 모델 학습의 중심적인 역할을 수행한다. Agent 클래스는 모델 학습에 필요한 기능을 세분화하고 train 함수 안에 이 모든 기능들이 호출되도록 구성했다.


(1) reword_list는 단위 에피소드마다 받은 보상을 배열 형식으로 저장하고 있다. 강화학습의 최종 목적은 reword_list 배열의 평균 값을 최대로 만드는 것이다.


(2) episode_num은 몇 번의 에피소드를 학습할 지 결정한다. 카트폴 게임이 시작해서 종료될 때까지를 하나의 에피소드로 본다. 에피소드에서 카드폴이 반복하는 행동을 스텝이라 정의한다.


(3) __init__ 함수에서 gym.make 함수를 통해 만들어진 env 객체는 카트폴 게임을 담고있다. Env객체에서 제공하는 reset 함수를 통해 게임을 초기화하고 랜덤으로 카트를 움직여 발생한 상태 값을 얻을 수 있다.


(4) take_action_and_append_memory 함수를 사용해서 카트폴 게임을 실행시키고 게임에서 얻은 결과를 리플레이 메모리에 저장한다.


(5) minibatch_step_size 크기만큼 에피소드가 진행되면 train_mini_batch 함수를 실행 해 강화학습을 진행한다.


(6) 강화 학습을 통해 얻어진 모든 보상을 저장하고 있는 reword_list 변수에 단위 에피소드에서 얻어진 보상을 추가한다.


(7) 학습이 잘 진행되고 있는지 확인하기 위해 100번의 에피소드마다 로그를 찍는다. 몇번의 에피소드가 실행됐으며, 현재 에피소드에서 받은 보상이 얼마이고 지금까지 받은 누적 보상의 평균 값을 출력한다.


(8) episode_num 만큼 위 과정을 반복하고 마지막으로 학습된 모델을 지정된 경로에 저장한다.

 

카트폴 DQN 강화학습 예제 - take_action_and_append_memory 함수


Agent 클래스 take_action_and_append_memory 함수


리플레이 메모리에 저장할 데이터를 생성하는 take_action_and_append_memory 함수의 기능에 대해 자세히 알아보자.


(1) 함수 내부적으로 사용할 지역 변수를 선언한다. reword_tot 변수는 에피소드에서 얻은 모든 보상을 저장하기 하는 역할을 한다. count 변수는 경우 에피소드에서 몇 번 에이전트가 움직였는지 기록한다. done은 게임 종료 여부를 저장한다.


(2) get_episilon 함수는 입실론 탐욕 정책에 사용할 입실론 값을 반환한다. 구체적인 기능은 다음에 알아보도록 하자.


(3) 카트폴 게임은 done 변수가 True가 되기 전까지 반복 실행한다. 폴이 바닥으로 떨어지면 게임은 done 변수에 True 값을 담아 전달한다.


(4) StateX를 곱하기 위해서는 행렬의 형태를 곱셈 가능한 형태로 맞춰 줘야한다. Numpy에서 제공하는 reshape 함수를 통해 state의 값을 (1,4) 형태로 변형한다.


(5) 모델에 상태 값을 입력해서 출력을 얻어낸다. 출력에는 (1,2) 형태의 Q값이 들어있다. Q값은 행동 별 가치를 나타낸다.


(6) 입실론 탐욕 정책으로 어떤 행동을 취할지 결정한다. 입실론 탐욕 정책이 어떻게 구현되는지는 뒷부분에서 자세히 다루도록 한다.


(7) 앞에서 결정된 행동을 입력해서 카트폴을 움직이고 그 결과에 따라 다음 상태, 보상, 완료여부를 반환 받는다.


(8) 지금까지 구한 값들 중 학습에 필요한 값들을 리플레이 메모리에 저장한다.


(9) 리플레이 메모리가 학습자가 지정한 크기보다 커지면 가장 처음에 저장된 데이터부터 삭제한다.


(10) 앞에서 카트폴을 실행해서 받은 보상을 reword_tot 변수에 합산한다. reword_tot 변수에는 현재 에피소드에서 수집된 모든 보상에 대한 합계가 저장된다. 에피소드가 끝나면 reword_tot 변수는 모든 보상 값을 가지고 있는 reword_list 배열에 저장된다.


(11) 현재 상태(state)가 다음 상태(state_next)로 대체된다. 즉 새로운 상태를 다음 스텝에서 입력 값으로 사용한다.

 

카트폴 DQN 강화학습 예제 - get_episilon greed_search 함수


Agent 클래스 get_episilon 함수


get_episilon 함수는 탐욕 정책에 사용할 입실론 값을 계산하는 함수이다. 입실론 값은 클수록 무작위로 행동을 결정하기 때문에 학습 초기에 큰 값을 설정하고 학습이 진행될 수록 작아져야 한다. 초기 설정 값과 얼마의 비율로 감소하는지는 학습자가 하이퍼파라미터를 통해 결정한다.


(1) epsilon 변수는 초기에 설정되는 입실론 값을 저장하고 있으며 epsilon_decay 변수는 입실론 값이 최소가 되는 학습 단계를 나타낸다. 예를 들어 epsilon_decay 0.2로 설정되어 있으며 학습해야하는 에피소드 중 20% 정도 지나면 입실론 값은 최소값으로 줄어든다. episode_num 변수는 현재 몇 번째 에피소드를 진행하고 있는지를 저장하고 있으므로 시간이 지남에 따라 증가하게 된다.


(2) epsilon_min 변수는 학습자가 하이퍼파라미터를 통해 지정하는 최소 입실론 값이다. episode_num0.01로 설정되어 있으면 get_episilon 함수는 0.01보다 작은 값을 반환할 수 없다.


Agent 클래스 greed_search 함수


greed_search 함수는 입실론 탐욕 정책을 구현하는 함수다. (1) 먼저 입실론 값을 구해서 greed_search 함수에 전달하면 0부터 1사이의 랜덤 값과 입실론 값을 비교해서 입실론 값이 크면 행동을 무작위로 선택한다.


(2) 만일 입실론 값이 랜덤 값보다 작거나 같으면 입력 값은 Q (1x2 배열) 중에서 가장 큰 값을 가지고 있는 인덱스를 반환한다.

 

카트폴 DQN 강화학습 예제 - train_mini_batch save_model 함수


Agent 클래스 train_mini_batch 함수


train_mini_batch 함수는 리플레이 메모리에서 데이터를 가져와 최적 큐함수를 계산하고 이 값과 모델을 활용한 근사값의 차이를 최소화하는 방향으로 학습하는 기능을 수행한다.


(1) 학습자에 의해 결정된 minibatch_size 만큼 반복하면서 학습을 진행한다.


(2) 리플레이 메모리에서 학습자가 결정한 replay_size 만큼 데이터를 가져와 학습한다. 결국 train 함수에서 정의된 바와 같이 minibatch_step_size 단위로 학습이 진행되는데 한번 학습할 때 minibatch_size x replay_size 만큼 학습을 반복한다.

하이퍼  파라미터 설정에 따른 학습 횟수를 알아보자. 만일 EPISODE_NUM=300, MINIBATCH_STEP_SIZE=30, MINIBATCH_SIZE =10, REPLAY_SIZE=20으로 설정되었다면 총 학습 횟수는 300/30 x 10 x 20 = 2000이 된다.


(3) 리플레이 메모리에서 가져온 데이터를 학습을 위해 각각 다른 변수에 나누어 저장한다.


(4) 만일 학습이 종료된 시점에 수집된 데이터라면 별도의 계산을 하지 않고 받은 보상 그대로 Q 값으로 저장한다.


(5) 최적 큐함수를 구하는 공식에서 R +  - Q(S, A)  부분이 0이 되도록 하면 최적 큐함수가 된다고 앞장에서 설명한 바 있다. reword + self.discount_rate * np.argmax(Q_new) 식이 R +  와 같은 역할을 한다. Q(S,A)은 계산한 값이 아닌 실제 값이다. DQN에서는 이 값을 인공신경망 모델을 통해 근사하고 있다.


(6) 앞에서 정의한 학습모델이 정의된 training을 실행하면 학습이 진행된다.


Agent 클래스 save_model 함수


Save_model 함수는 사용자가 지정한 위치에 학습한 모델을 저장하는 기능을 수행한다. 저장된 모델은 나중에 다시 불러서 별도의 학습 없이 사용할 수 있다.

 

카트폴 DQN 강화학습 예제 - Agent 클래스 생성 및 실행


Agent 클래스 생성 및 실행


이제 하이퍼파라미터를 설정하고 에이전트 클래스를 생성해 학습을 진행해보자.


(1)하이퍼파라미터에 대한 자세한 설명은 앞 부분을 참고하도록 하자. DQN은 안정적인 알고리즘이 아니기 때문에 하이퍼파라미터 변경에 대해 굉장히 민감하게 반응한다. 하이퍼파라미터가 의미하는지가 뭐고 어떻게 동작하는지를 잘 생각한 다음에 값을 조정해 가면서 튜닝해 보도록 하자.


(2) reset_default_graph 함수는 혹시 남아있을지 모르는 텐서플로우 그래프를 없애주는 것이다. 주피터 노트북의 경우 커널을 초기화할 때까지 변수의 컨텐스트가 그대로 유지되기 때문에 텐서플로우 변수를 선언하기 전에 reset_default_graph 함수를 사용하는 것이 좋다.


(3) Agent를 클래스를 생성하면 내부적으로 __init__ 함수가 호출되면서 클래스 변수 할당과 네트워크 생성, 비용 함수 설정 그리고 모델 생성이 완료된다.


(4) Agent 클래스에서 사용하는 텐서플로우 변수를 초기화 한다.


(5) 마지막으로 train 함수를 호출해서 학습을 진행하고 학습이 완료되면 모델을 파일로 저장하면 모든 과정이 종료된다.


프로그램 실행


학습 로그를 살펴보자. 로그는 에피소드가 100번 진행될 때 마다 출력되도록 설정했다. 입실론 탐욕정책을 사용했기 때문에 초기에는 정책에 의해 행동이 결정되기 보다는 무작위로 결정된다. 입실론 값이 줄어드는 비율을 나타내는 EPSILON_DECAY0.1로 설정했기 때문에 전체 에피소드 2000번 중에 200번 정도 진행되면 입실론 값이 최소 값이 0.01로 줄어든다. 로그를 살펴보면 에피소드 200회 정도 진행된 다음 평균 보상 값(reword avg)이 대체적으로 증가하는 것을 확인할 수 있다.


평균 보상 값은 학습이 진행될 수록 커지는게 좋으며 마지막에 가장 큰 평균 값이 나오는 모델이 학습이 잘 된 모델이 확률이 높다. 하지만 평균 보상 값이 크다고 반듯이 좋은 모델은 아니다. 학습할 때 성능과 실제 모델을 활용해서 게임을 실행했을 때의 성능이 다르기 때문이다. 모델의 성능을 검증하기 위해서는 게임을 직접 실행해서 확인해 보는 것이 좋다.


cartpole_DQN.py






태그