[python] 강화학습 Q-learning 구현하기

 

📢 아래 코드는 gym라이브러리에서 FrozenLake-v0 환경을 불러와 실행한다.

 

전체 코드


import gym
import numpy as np

env= gym.make('FrozenLake-v0',is_slippery=False) #환경 생성
Q=np.zeros([env.observation_space.n,env.action_space.n]) #Q배열 초기화

rho=0.8 #학습률
lamda=0.99 #할인율

n_episode= 2000
length_episode=100

#최적 행동 가치 함수 찾기
for i in range(n_episode):
    s=env.reset()
    for j in range(length_episode):
        argmaxs=  np.argwhere(Q[s,:]==np.amax(Q[s,:])).flatten().tolist()
        a=np.random.choice(argmaxs)
        s1, r, done,_=env.step(a)
        Q[s,a] = Q[s,a]+rho*(r+lamda*np.max(Q[s1,:])-Q[s,a])
        s=s1
        if done:
            break

np.set_printoptions(precision=2)
print(Q)

코드 해설


📖 Q러닝 학습에 사용된 수식

 

Q=np.zeros([env.observation_space.n,env.action_space.n])

q(s,a)를 저장하기 위한 배열 Q를 생성함 (0으로 채움)

rho=0.8 #학습률
lamda=0.99 #할인율

위의 식에서 사용하는 학습률 $\rho$ (rho)과 할인율 $\gamma$ (lamda)를 선언한다.

n_episode= 2000
length_episode=100

에피소드의 개수와 최대 길이를 정의함

for i in range(n_episode):
    s=env.reset()
    for j in range(length_episode):
        argmaxs=  np.argwhere(Q[s,:]==np.amax(Q[s,:])).flatten().tolist()
        a=np.random.choice(argmaxs)
        s1, r, done,_=env.step(a)
        Q[s,a] = Q[s,a]+rho*(r+lamda*np.max(Q[s1,:])-Q[s,a]) #식 18
        s=s1
        if done:
            break

학습을 n_episode만큼 반복한다.

즉, 멈춤 조건에피소드 개수만큼 반복하는 것으로 정의

 

이 코드를 자세히 살펴보자.

s=env.reset()

env를 reset하여 초기상태 s를 설정함

이 아래 행해지는 코드(for문)는 에피소드를 처리하는 부분이다.

argmaxs=  np.argwhere(Q[s,:]==np.amax(Q[s,:])).flatten().tolist()

상태 s에 대해 최댓값을 갖는 행동을 모두 찾아 리스트에 저장함

 

argwhere

argwhere은 특정값의 위치를 찾아내는 함수이다.
위 예시 a 배열에서 5인 원소의 인덱스는 [7] , [10]이기 때문에 위와 같이 반환됨
(+) argmax는 최대값의 위치, argmin은 최소값의 위치 반환

 

amax


amax는 배열의 최대값을 반환하는 함수이다.
위 예시 a배열에서 최대값은 10이므로 amax값은 10이 출력되었고
이 최대값이 위치한 인덱스는 3이므로 argmax값은 3이 출력되었다.

따라서, np.argwhere(Q[s,:]==np.amax(Q[s,:]))의 의미는 배열에서 최대값을 찾고, 이 최대값과 같은 값을 가지는 인덱스를 모조리 찾는 것이다.

∵ argmax는 최대값이 중복이라면 첫번째 인덱스만 반환

 

flatten

flatten 함수는 다차원 배열을 1차원 배열로 변환하는 함수이다.

따라서, 최댓값을 가지는 행동들을 모두 리스트에 담았으면 이곳에서 랜덤추출하여 행동을 선택해야 한다.

a=np.random.choice(argmaxs)

행동들 중 하나를 랜덤하게 선택해 저장한다.

s1, r, done,_=env.step(a)

step함수를 실행해 위에서 선택한 행동 a를 실행하고, 실행 결과로 다음 상태 s1, 보상 r, 에피소드의 끝 여부를 받는다.

Q[s,a] = Q[s,a]+rho*(r+lamda*np.max(Q[s1,:])-Q[s,a])

위에서 언급한 계산식을 적용하여 가치함수를 개선한다.

if done:
	break

에피소드 끝을 만나면 탈출한다.


참고교재 파이썬으로 만드는 인공지능 - 한빛미디어