본문 바로가기
AI/모두를 위한 강화학습

Lecture 3-2 : Dummy Q-learning ( 실습 ) 모두를 위한 딥러닝 - Deep Reinforcement Learning

by 몽돌리스트 2020. 1. 26.
반응형

python 의 장점 -> 글로 적은 논리를 옮겨놓기 쉽다는 점

Python Language 의 장점은 

우리가 그냥 적어놓는 글들을 고스란히 코딩으로 바꿔놓을 수 있다는 점이다.

따라서 왼쪽에 나와있는 글을 쉽게(?) 파이썬 코드로 바꿔보면 오른쪽과 같다.


np.zeros ( 모든 Q를 0으로 만드러버린다. ) - 이때 0을 넣어줄 Space에 대한 Array 는 어떻게 만들어야 할까?

물론 직접 숫자 ( 16,4 ) 를 넣어줘도 되지만,  

이미 알고 있는 환경이기도 하고 추후에 환경의 변화가 생겼을 때 조금 더 유연하게 대처하기 위해 

[env.observation_space.n, env.action_space.n] 으로 나열해준다.

 

그리고 num_episodes = 2000은

에피소드의 개수를 의미한다. 


그 다음에 왼쪽의 Observe current state s 는

오른쪽의 state와 대치 된다. 

잘 보면 환경 초기화 시키면서, 첫 번째 state를 불러온다는 것을 알 수 있다.

 

그리고 왼쪽의 Do forever은 .. 

우리의 경우, 홀에 빠진다거나, 골에 도착하게 되면 게임이 끝나기 때문에 무조건 무한으로 반복할 필요가 없다. 

따라서 게임을 적절한 시기에 done(끝내라) 라는 명령어를 포함하게 된다.

이는 "게임이 끝나기 전까지는 무한 반복하고, 게임이 끝날 조건에 해당되면 끝내라!" 라는 것을 의미한다.


또한 원래 Q값 중에서 max한 값을 쓰겠다는 의미로

argmax를 선정해서 쓰곤 했는데, 조금 더 많은 케이스를 고려해보기 위해서

같은 Q값이 있다고 가정했을 때,(초기에는 모두가 0으로 세팅을 해놨기 때문에 ) 랜덤하게 선택할 수 있는 함수를 사용한다.

따라서 rargmax(Q[state,:])를 쓰게된다.

 

그 과정에서 정해진 action을 실행하게 되는데, 

이는 env.step(action)으로 실행하게 된다.

그러면 해당 함수가 new_state, reward, and done? or not? 까지 다 알려주게 된다. ( 참 친절하다! )

왼쪽에 보이는 Receive immediate reward / Observe the new state 를 알려준다.

 

그리고 이 과정에서 가장 중요한 것은 Q를 업데이트 해주는 것이다.

Q[state,action] 이라는 것은 해당 action과 state에서 행한 Q라는 애는 

방금 얻은 reward 와 다음 단계( new_state )에 있는 Q (( np.max(Q[new_state,:] ))를 더한 것과 같다는 것으로 적어준다. 

 

 

또한 모든 경우에 해당되는 것들을 하기 위해서 

Q 값을 업데이트를 할 때, np.max(Q[new_state,:]) 를 써주게 된다. ( 물론 가장 큰 값을 넣어준다는 것을 잊지말자. )

여기서 :는 모든 경우(위,아래,좌,우)에서 가장 큰 아이를 의미한다.

 

그 다음에는 new_state를 다시 지금의 state 로 대입해준다.


 

먼저 우리가 필요한 것들을 import 시켜준다.

이는 추후 우리가 가상 환경에서 pip 이나 conda 명령어를 통해 

설치하게 될 아이들인 경우가 많다.

혹은 기존에 제공하는 것들도 있으니, 꼭 참고하자.

 

또한 다시 한번 언급하면, rargmax(vertor) 는 초기에

모두가 0 이기 때문에, 한쪽 방향으로만 가보지 말고 random 하게 가보라는 것을 의미한다.

 

그 다음에는 환경 설정을 해주면 된다.

( 여기서 불러온 게임은 Frozen Lake 이다. )

 

 

앞에서는 환경 설정을 해줬으니,

이제는 설계(?)를 해보면 된다. [ 바로 위에서 각 코드가 어떤 의미인지 정리했기 때문에, 자세한 설명은 생략한다. ]

 

추가 내용은 얼마나 잘하고 있는지를 살펴보기 위해

나오는 값들을 저장해야 한다.

 

이를 위해 rList=[] 를 넣어준다.

또한 rAll += reward 를 해서, 모든 보상들을 더해주고,

이를 앞서 언급한 list 에 넣어준다.

그렇게 해주면 2000번 동안에 얼마나 성공했는지를 볼 수 있게 된다. ( num_episodes = 2000 )

 

 

 

 

 이제 결과를 도출하게 될텐데,

sum(rList)/num_episodes --> 총 2000번의 episode 중에서 얼마나 성공했느지를 알 수 있다.

성공하면 1이 rList에 들어가기 때문에, 그것을 합한 총 합을 전체 실행해준 횟수를 나눠준다.

그러면 총 2000번 중에 몇번을 성공했는지 알 수 있다.

 

또한 Q값이 잘 들어갔는지, 어떤 방향으로 가는지 등등 보기 위해 print를 써준다.

언제 성공하고 언제 실패하는지 보기 위해 plt.bar(range(len(rList)), rList, color="blue") 해준다.

plt.show()가지 해주면 아래의 파란색 그래프들을 볼 수 있다.

 

파란색 그래프를 보면, Success rate : 0.95임을 알 수 있는데,

이것을 살펴보면 앞에 0~ 100? 정도까지는 실패하다가 그 이후로는 쭉 성공하는 것을 볼 수 있다.

 

이 코드를 직접 돌려보면, 계속 돌릴수록 Success rate가 올라가게 된다는 것을 알 수 있다.

왜그럴까? 초기에 random 하게 움직이기 때문이다. 따라서 실행시킬 때 마다 결과값이 조금씩 달라질 수 있다.

 


또한 결과 중에 한가지를 골라서 Print하면 

첫번째 칸 부터 S0 S1 -------- S15 까지 총 16개의 index가 존재하고,

각각의 index 마다 [ 위, 아래, 좌, 우 ] 4개의 배열이 존재하므로

[ 16 , 4 ]의 Array를 가지게 된다는 점!

이를 그려보면 오른쪽의 그림과 같다.

[이때, s4,5,6은 1이 존재하지 않는데, 그 이유는 그쪽으로 가지 않았기 때문이다.]

 

여기서 한개의 Q를 살펴보면, 하나씩 Index를 보고 따라갔을 때 잘 S15에 도달하게 된다는 것을 알 수 있다.


다음 시간에는 "Dummy" Q-Learning 에서 발생한 문제점을 보완하여

더 완벽한 Q-learning 으로 만들어보자.

반응형

댓글