서론
강화 학습(Reinforcement Learning, RL)은 에이전트가 환경과 상호작용하며 최적의 행동을 학습하는 기계 학습의 한 분야입니다. 이번 글에서는
배고픔 관리 에이전트를 만들기 위한 사례를 소개합니다. 이 에이전트는 현실 세계에서의 복잡한 행동 문제를 해결하기 위해 강화 학습을
활용하며, 상태와 행동 공간을 효과적으로 설계하여 목표를 달성할 수 있도록 합니다.
배경 지식
배고픔 관리 시스템은 생물학적 요소와 외부 환경의 변화에 기반하여 에이전트가 식사를 관리하는 것을 목표로 합니다. 이러한 시스템은
특히 인간과 같은 복잡한 행동을 모델링하는 데 적합합니다. 행동 학습에서 고려해야 할 주요 요소는
상태(state)와 행동(action)입니다. 에이전트는 주어진 상태에서 어떤 행동을 선택하고,
그 행동이 선택된 후에 새로운 상태로 전이되는 환경에서 학습하게 됩니다.
상태와 행동 공간 설계
배고픔 관리 에이전트의 상태 공간은 에이전트의 현재 상태를 나타내며, 이는 다음과 같은 요소로 구성될 수 있습니다:
- 배고픔 수준(hunger level): 0 (완전 포만) ~ 10 (매우 배고픔)
- 에너지원(energy source): 최근에 섭취한 음식의 종류
- 활동 수준(activity level): 현재 에이전트의 활동 정도
에이전트는 다음과 같은 행동을 취할 수 있습니다:
- 음식 섭취 (consume food)
- 운동 (exercise)
- 휴식 (rest)
상태와 행동 공간을 정의함으로써 에이전트는 기능적이고 의미 있는 선택을 할 수 있으며, 환경과의 상호작용을 통해
최적의 정책(.policy)을 학습할 수 있습니다.
환경 설정
배고픈 관리 에이전트의 환경은 강화 학습의 OpenAI Gym 라이브러리를 사용할 수 있습니다. 이 환경은 에이전트가 상태를 관찰하고 행동을 취할 수 있는
인터페이스를 제공합니다. 이번에 구축할 환경의 초기 코드를 아래와 같이 설정해 보겠습니다.
import gym
from gym import spaces
import numpy as np
class HungerManagementEnv(gym.Env):
def __init__(self):
super(HungerManagementEnv, self).__init__()
self.action_space = spaces.Discrete(3) # 3가지 행동: 음식을 먹다, 운동하다, 쉬다
self.observation_space = spaces.Box(low=0, high=10, shape=(3,), dtype=np.float32) # 배고픔 수준, 에너지원, 활동 수준
self.state = None
def reset(self):
self.state = np.array([10, 0, 0], dtype=np.float32) # 초깃값: 매우 배고픔
return self.state
def step(self, action):
hunger_level, energy_source, activity_level = self.state
if action == 0: # 음식을 먹다
hunger_level = max(0, hunger_level - 5) # 배고픔 감소
energy_source += 1 # 에너지원 증가
elif action == 1: # 운동하다
hunger_level = min(10, hunger_level + 2) # 배고픔 증가
activity_level += 1 # 활동 수준 증가
elif action == 2: # 쉬다
hunger_level = min(10, hunger_level + 1) # 배고픔 완화
self.state = np.array([hunger_level, energy_source, activity_level], dtype=np.float32)
reward = -hunger_level # 배고픔이 낮을수록 좋은 보상
done = hunger_level <= 0 # 배고픔 수준이 0이면 종료
return self.state, reward, done, {}
def render(self, mode='human'):
print(f"Hunger Level: {self.state[0]}, Energy Source: {self.state[1]}, Activity Level: {self.state[2]}")
에이전트 설계
에이전트를 설계하기 위해 강화 학습 알고리즘 중 하나인 Q-Learning을 사용할 수 있습니다. Q-Learning 알고리즘은
각 상태에서 가능한 행동에 대한 가치를 학습하여 에이전트가 최적의 정책을 선택하도록 합니다. 에이전트의 기본 구조는 다음과 같습니다.
import random
class QLearningAgent:
def __init__(self, action_space):
self.action_space = action_space
self.q_table = {}
self.learning_rate = 0.1
self.discount_factor = 0.95
self.exploration_rate = 1.0
self.exploration_decay = 0.99
def get_action(self, state):
if random.uniform(0, 1) < self.exploration_rate:
return self.action_space.sample() # 무작위 행동 선택
return np.argmax(self.q_table.get(tuple(state), np.zeros(self.action_space.n))) # 최적 행동 선택
def learn(self, state, action, reward, next_state):
current_q = self.q_table.get(tuple(state), np.zeros(self.action_space.n))[action]
max_future_q = np.max(self.q_table.get(tuple(next_state), np.zeros(self.action_space.n)))
new_q = (1 - self.learning_rate) * current_q + self.learning_rate * (reward + self.discount_factor * max_future_q)
if tuple(state) not in self.q_table:
self.q_table[tuple(state)] = np.zeros(self.action_space.n)
self.q_table[tuple(state)][action] = new_q
self.exploration_rate *= self.exploration_decay # 탐색률 감소
훈련 및 학습
에이전트가 환경과 상호작용하면서 학습하도록 훈련하는 코드를 작성해 보겠습니다.
에피소드를 반복하면서 에이전트가 행동을 하도록 하고, 보상을 제공하며 Q-테이블을 업데이트합니다.
def train_agent(env, agent, episodes):
for episode in range(episodes):
state = env.reset()
done = False
while not done:
action = agent.get_action(state)
next_state, reward, done, _ = env.step(action)
agent.learn(state, action, reward, next_state)
state = next_state
if (episode + 1) % 100 == 0:
print(f"Episode: {episode + 1}, Q-Table Size: {len(agent.q_table)}")
결과 및 성능 평가
에이전트 학습이 완료된 후, 성능을 평가하기 위해 에이전트를 여러 번 실행하여 배고픔 수준이 0에 도달하는
평균 에피소드 수를 측정할 수 있습니다. 아래 코드는 성능 평가를 위한 방법입니다.
def evaluate_agent(env, agent, episodes):
total_steps = 0
for episode in range(episodes):
state = env.reset()
done = False
steps = 0
while not done:
action = agent.get_action(state)
next_state, reward, done, _ = env.step(action)
state = next_state
steps += 1
total_steps += steps
return total_steps / episodes
average_steps = evaluate_agent(env, agent, 100)
print(f"Average Steps to Hunger Level 0: {average_steps}")
결론
배고픔 관리 에이전트를 개발하면서 강화 학습의 기본 개념과 환경 설계, 에이전트 설계,
그리고 Q-Learning 알고리즘을 통해 복잡한 행동 문제를 해결하는 방법을 살펴보았습니다.
이 글에서 논의한 내용을 바탕으로 더 복잡한 환경과 에이전트를 설계하고 개선할 수 있는
기회를 만들어 보기를 바랍니다. 강화 학습은 훌륭한 가능성을 가진 분야이며, 다양한 문제를 해결하는 데
활용될 수 있습니다.