이 글은 강화학습/심층강화학습 특강을 학습하고 정리한 글입니다.
🎯 문제 상황 및 목표
한 창고 안에 A부터 L까지 총 12개의 위치가 있습니다. 고객이 상품을 주문하면 창고 로봇이 이 12개의 위치 중에서 특정 위치에 보관된 상품을 찾아 배송합니다.
📦 목표
- 로봇이 최우선 순위로 가야 하는 위치에 항상 빠르고 효율적으로 도착하도록 AI를 학습시키는 것
- 단순히 최우선 위치로 가는 것뿐만 아니라 중간에 우선순위가 높은 다른 위치를 거쳐 가는 옵션도 제공하는 것
우선순위 | 위치 |
1 | G |
2 | K |
3 | L |
4 | J |
5 | A |
6 | I |
7 | H |
8 | C |
9 | B |
10 | D |
11 | F |
12 | E |
🏭 환경 구성
📕 상태(State) 정의
각 위치를 AI가 이해할 수 있도록 숫자로 인코딩합니다.
위치 | 상태 |
A | 0 |
B | 1 |
C | 2 |
D | 3 |
E | 4 |
F | 5 |
G | 6 |
H | 7 |
I | 8 |
J | 9 |
K | 10 |
L | 11 |
이와 같이 상태를 정의하면 로봇이 현재 어떤 위치에 있는지 명확하게 표현할 수 있습니다.
location_to_state = {
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5,
'G': 6, 'H': 7, 'I': 8, 'J': 9, 'K': 10, 'L': 11
}
💡보충 설명
상태를 숫자로 매핑하면 수치 연산과 행렬 계산을 사용하는 Q-러닝 알고리즘을 효과적으로 구현할 수 있습니다.
📗 행동(Action) 정의
로봇이 취할 수 있는 모든 가능한 행동은 창고 내의 12개의 위치로 이동하는 것입니다. 즉, 행동 리스트는 단순히 0부터 11까지의 숫자로 표현됩니다.
actions = [0,1,2,3,4,5,6,7,8,9,10,11]
💡보충 설명
각 행동은 로봇이 다음에 이동할 위치를 나타내며 이 숫자들을 통해 Q-러닝 알고리즘은 '어떤 행동을 취해야 하는가?'를 판단하게 됩니다.
📘 보상(Reward) 정의
보상은 로봇이 특정 행동을 수행할 때 받는 값입니다.
- 이동 가능한 경로: 보상 +1
- 이동 불가능한 경로: 보상 +0
- 추가 보상: 최우선 위치로 가는 경로에 큰 보상(+1000)을 부여하여 반드시 방문하도록 유도합니다.
보상 행렬은 아래와 같이 정의됩니다. 행렬의 각 행은 현재 상태 $s_t$를, 각 열은 다음 상태 $s_{t+1}$를 의미하며 셀에 들어있는 값이 그 행동에 대한 보상을 나타냅니다.
import numpy as np
R = np.array([
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 1000, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0]
])
💡보충 설명
보상 행렬 $R$은 창고의 구조와 연결 관계를 반영합니다. 예를 들어, 만약 로봇이 어떤 위치에서 특정 위치로 이동할 수 없으면 해당 셀의 값은 0이 되고 이동이 가능하면 1 또는 추가 보상을 받게 됩니다. 이를 통해 Q-러닝은 "어떤 경로가 가장 이득이 되는가"를 학습합니다.
💡 Q-러닝의 기본 원리
Q-러닝은 경험을 통한 학습 방법으로, 로봇이 다양한 상태에서 어떤 행동을 취할 때 얻는 보상을 기반으로 최적의 경로를 찾아갑니다.
1️⃣ Step 1: 초기화
모든 상태와 행동의 조합에 대해 Q-값을 0으로 초기화합니다. 즉, $Q(s, a) = 0$으로 시작합니다.
Q = np.zeros(shape=(12, 12))
💡 보충 설명
초기화 단계에서는 로봇이 아무런 경험 없이 시작할 때 모든 행동의 가치가 동일하다고 가정합니다. 이후 학습 과정을 통해 어떤 행동이 더 좋은 결과를 내는지 차차 학습됩니다.
2️⃣ Step 2: 학습 과정
1. 현재 상태 선택
- 임의의 상태 $s_t$를 선택합니다.
2. 가능한 행동 선택
- 현재 상태에서 수행 가능한 행동(즉, 보상이 0보다 큰 행동) 중 하나를 무작위로 선택합니다.
3. 행동 수행 및 보상 관찰
- 선택한 행동을 수행하여 다음 상태 $s_{t+1}$에 도달하고 보상 $R(s_t, a_t)$를 받습니다.
4. TD 오차 계산
- 시간차(Temporal Difference, TD) 오차는 다음과 같이 계산됩니다.
- 여기서 $\gamma$는 할인 계수이며 $\alpha$는 학습률입니다.
$$TD(s_t,a_t) = R(s_t, a_t) + \gamma \max_a Q(s_{t+1}, a) - Q(s_t, a_t)$$
5. Q-값 업데이트
- 벨만 방정식에 따라 Q-값을 업데이트합니다.
$$Q \leftarrow Q(s_t, a_t) + \alpha \times TD(s_t, a_t)$$
6. 반복
- 이 과정을 1,000회 반복하여 Q-값이 점점 최적의 값으로 수렴하도록 합니다.
gamma = 0.75 # 할인 계수
alpha = 0.9 # 학습률
for i in range(1000):
current_state = np.random.randint(0, 12) # 임의 상태 선택
playable_actions = [j for j in range(12) if R[current_state, j] > 0] # 가능한 행동 필터링
next_state = np.random.choice(playable_actions) # 가능한 행동 중 하나 선택
TD = R[current_state, next_state] + gamma * Q[next_state, np.argmax(Q[next_state,])] - Q[current_state, next_state]
Q[current_state, next_state] = Q[current_state, next_state] + alpha * TD
💡 보충 설명
- 할인 계수 $\gamma$: 미래의 보상을 현재의 가치로 환산하는 역할을 합니다. $\gamma$가 클수록 먼 미래의 보상도 중요하게 고려됩니다.
- 학습률 $\alpha$: 현재의 Q-값을 얼마나 빠르게 업데이트할지를 결정합니다. $\alpha$가 클수록 최근의 경험에 더 크게 반응합니다.
- TD 오차: 현재 예측과 실제 보상 그리고 다음 상태의 최대 보상과의 차이를 나타내며 이를 통해 Q-값이 점진적으로 개선됩니다.
🚚 경로 탐색 및 최적 경로 출력
🗺 상태와 위치 간의 매핑
코드를 쉽게 이해하기 위해 상태(숫자)와 실제 위치(문자)를 서로 변환할 수 있도록 역 매핑 딕셔너리를 생성합니다.
state_to_location = {state: location for location, state in location_to_state.items()}
💡 보충 설명
이 매핑을 통해 Q-러닝 알고리즘이 계산한 상태(숫자)를 실제 로봇이 이동할 위치로 쉽게 변환할 수 있습니다.
🚀 최적 경로 계산 함수 route()
route() 함수는 시작 위치와 목표(최우선) 위치를 받아서 학습된 Q-값을 기반으로 최적의 경로를 도출해 줍니다.
1. 초기 경로 설정
- 시작 위치를 리스트에 추가합니다.
2. 반복 이동
- 현재 상태에서 Q-값이 가장 큰 행동을 선택하여 다음 상태로 이동합니다.
3. 종료 조건
- 목표 위치에 도달하면 반복을 종료합니다.
def route(starting_location, ending_location):
route_path = [starting_location]
next_location = starting_location
while next_location != ending_location:
starting_state = location_to_state[starting_location]
next_state = np.argmax(Q[starting_state,])
next_location = state_to_location[next_state]
route_path.append(next_location)
starting_location = next_location
return route_path
# 예시 실행
print(f"Route: {route('E', 'G')}")
# 출력 예시: ['E', 'I', 'J', 'F', 'B', 'C', 'G']
🔧 추가 개선 방안 및 확장 아이디어
Q-러닝을 활용한 창고 물류 최적화는 기본적인 경로 탐색 외에도 다음과 같은 개선 방안을 고려할 수 있습니다.
⚙ 보상 부여 자동화
- 문제점: 기존에는 목표 위치(G)에 수동으로 높은 보상(1000)을 부여했습니다.
- 해결책: route() 함수 내에서 목표 위치의 보상을 자동으로 업데이트하도록 하여 환경 설정 단계에서 수동 조작을 줄일 수 있습니다.
def route(starting_location, ending_location):
R_new = np.copy(R)
# 종료 위치의 셀에 보상을 자동으로 업데이트
ending_state = state_to_location[ending_location]
R_new[ending_state, ending_state] = 1000
🔦 중간 목표 추가
- 목표: 단순히 목표 위치로 바로 가는 것이 아니라 두 번재 우선순위인 위치 등 중간 경유지를 반드시 거치도록 합니다.
- 해결책: 세 개의 입력(시작, 중간, 종료 위치)을 받는 best_route()를 만듭니다.
- 먼지 시작 → 중간 경로를 구하고 두 경로를 합치는 방식으로 최종 경로를 도축합니다.
def best_route(starting_location, intermediary_location, ending_location):
return route(starting_location, intermediary_location) + route(intermediary_location, ending_location)[1:]
# 예시 실행
print(f"Route: {best_route('E', 'K', 'G')}")
# 출력 예시: ['E', 'I', 'J', 'K', 'L', 'H', 'G']
💡 전체 코드는 q_learning_with_intermediate_goal.py와 q_learning_without_intermediate_goal.py에 있습니다.
'강화학습' 카테고리의 다른 글
[강화학습/심층강화학습 특강] Q-러닝 기초 (0) | 2025.03.04 |
---|---|
[강화학습/심층강화학습 특강] 영업과 광고를 위한 AI (0) | 2025.03.02 |
[강화학습/심층강화학습 특강] 다중 슬롯머신 - 톰슨 샘플링 모델 (2) (0) | 2025.02.26 |
[강화학습/심층강화학습 특강] 다중 슬롯머신 - 톰슨 샘플링 모델 (1) (0) | 2025.02.21 |
[강화학습/심층강화학습 특강] 강화학습의 5가지 원칙 (0) | 2025.02.18 |