Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Обучение с подкреплением (Reinforcement Learning)
Обучение с подкреплением (Reinforcement Learning, RL) — парадигма машинного обучения, где агент учится взаимодействовать с окружением, получая награды за хорошие действия и штрафы за плохие. Цель агента — максимизировать суммарную награду.
Основные компоненты
# Компоненты RL системы
# 1. Agent — обучаемый объект
# 2. Environment — окружение, с которым взаимодействует агент
# 3. State (s) — текущее состояние окружения
# 4. Action (a) — действие, которое может выполнить агент
# 5. Reward (r) — вознаграждение/штраф за действие
# 6. Policy (π) — стратегия выбора действий: π(a|s)
# Процесс взаимодействия:
# Agent наблюдает State -> выбирает Action ->
# окружение выдает Reward и новый State
Формальное определение
RL часто моделируется как Markov Decision Process (MDP):
- S — множество состояний
- A — множество действий
- P(s'|s,a) — вероятность перехода из состояния s в s' при действии a
- R(s,a,s') — вознаграждение за переход
- γ — коэффициент дисконтирования (0 < γ < 1)
Q-Learning
Это самый популярный метод RL для дискретных пространств действий и состояний.
import numpy as np
import random
class QLearningAgent:
def __init__(self, n_states, n_actions, learning_rate=0.1, discount=0.99, epsilon=0.1):
self.n_states = n_states
self.n_actions = n_actions
self.learning_rate = learning_rate # α
self.discount = discount # γ
self.epsilon = epsilon # ε для epsilon-greedy
# Q-таблица: Q[состояние][действие]
self.Q = np.zeros((n_states, n_actions))
def select_action(self, state):
"""Epsilon-greedy: иногда исследуем (random), иногда эксплуатируем (best)"""
if random.random() < self.epsilon:
# Исследование: случайное действие
return random.randint(0, self.n_actions - 1)
else:
# Эксплуатация: лучшее известное действие
return np.argmax(self.Q[state])
def update_Q(self, state, action, reward, next_state, done):
"""Q-learning update: Q(s,a) <- Q(s,a) + α[r + γ*max(Q(s',a')) - Q(s,a)]"""
if done:
target = reward
else:
# Максимальное Q-значение для следующего состояния
max_next_q = np.max(self.Q[next_state])
target = reward + self.discount * max_next_q
# Обновляем Q-значение
current_q = self.Q[state, action]
self.Q[state, action] += self.learning_rate * (target - current_q)
def train(self, env, episodes=1000):
"""Обучаем агента на окружении"""
for episode in range(episodes):
state = env.reset()
done = False
while not done:
action = self.select_action(state)
next_state, reward, done = env.step(action)
self.update_Q(state, action, reward, next_state, done)
state = next_state
# Пример использования
class SimpleGridEnvironment:
"""Простое окружение: агент движется к цели на сетке 5x5"""
def __init__(self):
self.n_states = 25 # 5x5 сетка
self.n_actions = 4 # вверх, вниз, влево, вправо
self.goal = 24
self.position = 0
def reset(self):
self.position = 0
return self.position
def step(self, action):
# Перемещаемся в зависимости от действия
if action == 0: # Вверх
self.position = max(0, self.position - 5)
elif action == 1: # Вниз
self.position = min(24, self.position + 5)
elif action == 2: # Влево
if self.position % 5 > 0:
self.position -= 1
elif action == 3: # Вправо
if self.position % 5 < 4:
self.position += 1
# Вознаграждение
if self.position == self.goal:
reward = 1
done = True
else:
reward = -0.01 # Штраф за каждый шаг
done = False
return self.position, reward, done
# Обучаем агента
env = SimpleGridEnvironment()
agent = QLearningAgent(25, 4, learning_rate=0.1, epsilon=0.1)
agent.train(env, episodes=1000)
print(f"Q-таблица (первые 5 строк):\n{agent.Q[:5]}")
Policy Gradient Methods (REINFORCE)
Другой подход — напрямую обучать политику π(a|s).
import torch
import torch.nn as nn
import torch.optim as optim
class PolicyNetwork(nn.Module):
"""Нейросетевая политика"""
def __init__(self, state_dim, action_dim):
super().__init__()
self.fc1 = nn.Linear(state_dim, 128)
self.fc2 = nn.Linear(128, action_dim)
def forward(self, state):
x = torch.relu(self.fc1(state))
action_probs = torch.softmax(self.fc2(x), dim=-1)
return action_probs
class REINFORCEAgent:
def __init__(self, state_dim, action_dim, learning_rate=0.01, discount=0.99):
self.policy = PolicyNetwork(state_dim, action_dim)
self.optimizer = optim.Adam(self.policy.parameters(), lr=learning_rate)
self.discount = discount
self.log_probs = []
self.rewards = []
def select_action(self, state):
state = torch.FloatTensor(state)
probs = self.policy(state)
action_dist = torch.distributions.Categorical(probs)
action = action_dist.sample()
# Сохраняем log probability для обновления
self.log_probs.append(action_dist.log_prob(action))
return action.item()
def update(self):
"""REINFORCE update: ∇J = E[∇log π(a|s) * G_t]"""
discounted_rewards = []
cumulative = 0
# Вычисляем discounted rewards (return)
for reward in reversed(self.rewards):
cumulative = reward + self.discount * cumulative
discounted_rewards.insert(0, cumulative)
# Нормализуем для стабильности
discounted_rewards = torch.tensor(discounted_rewards)
discounted_rewards = (discounted_rewards - discounted_rewards.mean()) / (discounted_rewards.std() + 1e-8)
# Вычисляем loss
loss = 0
for log_prob, g_t in zip(self.log_probs, discounted_rewards):
loss -= log_prob * g_t
# Обновляем политику
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
# Очищаем буфер
self.log_probs.clear()
self.rewards.clear()
Actor-Critic Methods
Комбинирует Policy Gradient (Actor) и Value Function (Critic).
class ActorCriticAgent:
"""Агент с Actor-Critic архитектурой"""
def __init__(self, state_dim, action_dim, learning_rate=0.01):
# Actor — сетка для выбора действий
self.actor = PolicyNetwork(state_dim, action_dim)
# Critic — сетка для оценки ценности состояния
self.critic = nn.Sequential(
nn.Linear(state_dim, 128),
nn.ReLU(),
nn.Linear(128, 1) # Оцениваем V(s)
)
self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=learning_rate)
self.critic_optimizer = optim.Adam(self.critic.parameters(), lr=learning_rate)
def update(self, state, action, reward, next_state, done):
state = torch.FloatTensor(state)
next_state = torch.FloatTensor(next_state)
# Critic: предсказываем ценность состояния
value = self.critic(state)
next_value = self.critic(next_state) if not done else torch.tensor(0.0)
# TD-ошибка (advantage)
td_target = reward + 0.99 * next_value.detach()
advantage = td_target - value
# Обновляем Critic
critic_loss = advantage.pow(2).mean()
self.critic_optimizer.zero_grad()
critic_loss.backward()
self.critic_optimizer.step()
# Обновляем Actor
probs = self.actor(state)
action_dist = torch.distributions.Categorical(probs)
log_prob = action_dist.log_prob(torch.tensor(action))
actor_loss = -log_prob * advantage.detach()
self.actor_optimizer.zero_grad()
actor_loss.backward()
self.actor_optimizer.step()
Практические примеры RL
1. Игры (Atari, Go)
- AlphaGo использовал RL с Monte Carlo Tree Search
- Deep Q-Networks (DQN) обучались на Atari играх
2. Робототехника
- Обучение манипулятору схватывать объекты
- Балансировка робота
3. Рекомендационные системы
- Выбор лучшего контента для пользователя
- Балансировка исследования vs эксплуатации
4. Трейдинг
- Обучение торговых стратегий
- Управление портфелем
Exploration vs Exploitation
# Exploration: попробовать новые действия
# Exploitation: использовать известные хорошие действия
# Epsilon-greedy: простой баланс
epsilon = 0.1 # 10% вероятность исследования
if random.random() < epsilon:
action = random.choice(actions) # Исследование
else:
action = argmax(Q[state]) # Эксплуатация
# Soft-max (Boltzmann) — более гладкое распределение
probs = softmax(Q[state] / temperature)
action = sample(probs)
Лучшие практики
- Начни с простых окружений (CartPole, MountainCar)
- Нормализуй награды для стабильности обучения
- Используй experience replay для улучшения sample efficiency
- Регулярно проверяй progress на test-окружении
- Гиперпараметры (α, γ, ε) сильно влияют на результат
Обучение с подкреплением — мощный инструмент для решения задач, где нет явного обозначения "правильных" действий.