Неделя 11: Обучение с подкреплением (Reinforcement Learning)
1. Теоретическая часть
1.1. Основы RL
Обучение с подкреплением — метод машинного обучения, где агент учится, взаимодействуя со средой и получая награды.
Ключевые компоненты
Компонент
Описание
Агент (Agent)
Принимает решения (политика)
Среда (Environment)
Мир, с которым взаимодействует агент
Состояние (State)
Текущая ситуация
Действие (Action)
Выбор агента
Награда (Reward)
Обратная связь от среды
Математическая формулировка
Цель: максимизировать 𝐸[∑𝑡=0∞𝛾𝑡𝑟𝑡]Цель: максимизировать E[t=0∑∞γtrt]
где 𝛾γ — коэффициент дисконтирования.
1.2. Методы RL
Метод
Принцип работы
Q-Learning
Оценка полезности действий через Q-функцию
Policy Gradients
Прямая оптимизация политики
Deep Q-Networks (DQN)
Q-Learning + нейросети
Actor-Critic
Комбинация Policy Gradients и Q-Learning
1.3. Применение RL
Игры (AlphaGo, Dota 2)
Робототехника
Оптимизация бизнес-процессов
2.1. Реализация Q-Learning
python
Copy
import numpy as np
# Создаем среду (пример: GridWorld)
class GridWorld:
def __init__(self):
self.grid = np.zeros((5, 5))
self.goal = (4, 4)
self.state = (0, 0)
def step(self, action):
x, y = self.state
if action == 0: x = max(0, x-1) # Вверх
elif action == 1: x = min(4, x+1) # Вниз
elif action == 2: y = max(0, y-1) # Влево
elif action == 3: y = min(4, y+1) # Вправо
self.state = (x, y)
reward = 1 if self.state == self.goal else -0.1
done = self.state == self.goal
return self.state, reward, done
# Инициализация Q-таблицы
q_table = np.zeros((5, 5, 4)) # [x, y, action]
# Параметры обучения
alpha = 0.1 # Скорость обучения
gamma = 0.99 # Коэффициент дисконтирования
epsilon = 0.1 # Вероятность случайного действия
# Обучение
env = GridWorld()
for episode in range(1000):
state = (0, 0)
done = False
while not done:
# ε-жадная стратегия
if np.random.random() < epsilon:
action = np.random.randint(4)
else:
action = np.argmax(q_table[state[0], state[1]])
next_state, reward, done = env.step(action)
# Обновление Q-функции
q_table[state[0], state[1], action] += alpha * (
reward + gamma * np.max(q_table[next_state[0], next_state[1]]) -
q_table[state[0], state[1], action]
)
state = next_state
2.2. Deep Q-Network (DQN) на PyTorch
python
Copy
import torch
import torch.nn as nn
import torch.optim as optim
class DQN(nn.Module):
def __init__(self, input_dim, output_dim):
super(DQN, self).__init__()
self.fc = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Linear(128, 128),
nn.ReLU(),
nn.Linear(128, output_dim)
)
def forward(self, x):
return self.fc(x)
# Инициализация
env = gym.make('CartPole-v1')
model = DQN(env.observation_space.shape[0], env.action_space.n)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.MSELoss()
# Обучение
for episode in range(1000):
state = env.reset()
done = False
total_reward = 0
while not done:
# ε-жадное действие
if np.random.random() < epsilon:
action = env.action_space.sample()
else:
with torch.no_grad():
q_values = model(torch.FloatTensor(state))
action = torch.argmax(q_values).item()
next_state, reward, done, _ = env.step(action)
# Обновление модели
target = reward + gamma * torch.max(model(torch.FloatTensor(next_state)))
current_q = model(torch.FloatTensor(state))[action]
loss = criterion(current_q, target.detach())
optimizer.zero_grad()
loss.backward()
optimizer.step()
state = next_state
total_reward += reward
2.3. Использование OpenAI Gym
python
Copy
import gym
env = gym.make('LunarLander-v2')
observation = env.reset()
for _ in range(1000):
env.render()
action = env.action_space.sample() # Случайное действие
observation, reward, done, info = env.step(action)
if done:
observation = env.reset()
env.close()
3. Домашнее задание
Задача 1: Оптимизация Q-Learning
1. Реализуйте адаптивный ε (уменьшение epsilon со временем).
2. Добавьте визуализацию траектории агента.
Решение:
python
Copy
epsilon_start = 1.0
epsilon_end = 0.01
epsilon_decay = 0.995
epsilon = epsilon_start
for episode in range(1000):
# ... (основной цикл обучения)
epsilon = max(epsilon_end, epsilon * epsilon_decay)
# Визуализация
if episode % 100 == 0:
visualize_path(env, q_table) # Функция для отрисовки пути
Задача 2: Улучшение DQN
1. Добавьте replay buffer для более стабильного обучения.
2. Реализуйте target network для расчета целевых Q-значений.
Решение:
python
Copy
from collections import deque
class ReplayBuffer:
def __init__(self, capacity):
self.buffer = deque(maxlen=capacity)
def push(self, state, action, reward, next_state, done):
self.buffer.append((state, action, reward, next_state, done))
def sample(self, batch_size):
return random.sample(self.buffer, batch_size)
# Инициализация
buffer = ReplayBuffer(10000)
target_network = DQN(env.observation_space.shape[0], env.action_space.n)
target_network.load_state_dict(model.state_dict())
# Обновление обучения
if len(buffer) > batch_size:
transitions = buffer.sample(batch_size)
batch = list(zip(*transitions))
# Расчет целевых значений через target network
with torch.no_grad():
next_q_values = target_network(torch.FloatTensor(np.array(batch[3])))
max_next_q = torch.max(next_q_values, dim=1)[0]
targets = torch.FloatTensor(batch[2]) + gamma * max_next_q * (1 - torch.FloatTensor(batch[4]))
Задача 3: Policy Gradients
1. Реализуйте REINFORCE алгоритм для CartPole.
2. Сравните результаты с DQN.
Решение:
python
Copy
class PolicyNetwork(nn.Module):
def __init__(self, input_dim, output_dim):
super(PolicyNetwork, self).__init__()
self.fc = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Linear(128, output_dim),
nn.Softmax(dim=-1)
)
def forward(self, x):
return self.fc(x)
# Обучение
policy = PolicyNetwork(env.observation_space.shape[0], env.action_space.n)
optimizer = optim.Adam(policy.parameters(), lr=0.01)
for episode in range(1000):
state = env.reset()
rewards = []
log_probs = []
while True:
state = torch.FloatTensor(state)
probs = policy(state)
action = torch.multinomial(probs, 1).item()
next_state, reward, done, _ = env.step(action)
rewards.append(reward)
log_probs.append(torch.log(probs[action]))
state = next_state
if done:
break
# Расчет дисконтированных наград
discounted_rewards = []
R = 0
for r in rewards[::-1]:
R = r + gamma * R
discounted_rewards.insert(0, R)
# Обновление политики
policy_loss = []
for log_prob, R in zip(log_probs, discounted_rewards):
policy_loss.append(-log_prob * R)
optimizer.zero_grad()
torch.stack(policy_loss).sum().backward()
optimizer.step()
Итоги недели
✅ Изучили основы RL и ключевые алгоритмы.
✅ Реализовали Q-Learning и DQN для разных сред.
✅ Познакомились с Policy Gradients и улучшениями DQN.
✅ Научились работать с OpenAI Gym.
Следующая тема: Применение RL в реальных задачах. 🚀