强化学习概述#

什么是强化学习?#

强化学习(Reinforcement Learning) 是智能体通过与环境交互,根据奖励信号学习最优策略的机器学习方法。

核心特点#

  1. 交互式学习:通过试错学习
  2. 延迟奖励:奖励可能延迟到来
  3. 探索与利用:平衡探索新动作和利用已知好动作

应用场景#

  • 游戏AI:AlphaGo、Dota 2
  • 机器人控制:行走、抓取
  • 自动驾驶:决策规划
  • 推荐系统:个性化推荐

基本概念#

智能体与环境#

智能体(Agent)
  ↓ 动作 a_t
环境(Environment)
  ↓ 状态 s_{t+1}, 奖励 r_{t+1}
智能体

关键要素#

1. 状态(State)#

环境的当前情况,用 s 表示。

2. 动作(Action)#

智能体可以执行的操作,用 a 表示。

3. 奖励(Reward)#

环境对动作的反馈,用 r 表示。

4. 策略(Policy)#

从状态到动作的映射,用 π(a|s) 表示。

5. 价值函数(Value Function)#

评估状态或动作的价值。


马尔可夫决策过程#

MDP定义#

MDP(Markov Decision Process) 是强化学习的数学框架:

$$ \text{MDP} = (S, A, P, R, \gamma) $$

其中:

  • $S$ :状态空间
  • $A$ :动作空间
  • $P$ :转移概率 $P(s'|s,a)$
  • $R$ :奖励函数 $R(s,a,s')$
  • $\gamma$ :折扣因子 $[0,1]$

马尔可夫性质#

未来只依赖于当前状态:

$$ P(s_{t+1}|s_t, a_t, s_{t-1}, \ldots) = P(s_{t+1}|s_t, a_t) $$

目标#

找到最优策略 $\pi^*$ ,最大化累积奖励:

$$ G_t = r_{t+1} + \gamma r_{t+2} + \gamma^2 r_{t+3} + \ldots $$

价值函数#

状态价值函数#

在策略 $\pi$ 下,状态 $s$ 的价值:

$$ V^\pi(s) = \mathbb{E}_\pi[G_t | s_t = s] $$

动作价值函数(Q函数)#

在状态 $s$ 执行动作 $a$ 的价值:

$$ Q^\pi(s,a) = \mathbb{E}_\pi[G_t | s_t = s, a_t = a] $$

最优价值函数#

$$ V^*(s) = \max_\pi V^\pi(s) $$ $$ Q^*(s,a) = \max_\pi Q^\pi(s,a) $$

Bellman方程#

状态价值#

$$ V^\pi(s) = \sum_a \pi(a|s) \sum_{s'} P(s'|s,a)[R(s,a,s') + \gamma V^\pi(s')] $$

Q函数#

$$ Q^\pi(s,a) = \sum_{s'} P(s'|s,a)\left[R(s,a,s') + \gamma \sum_{a'} \pi(a'|s')Q^\pi(s',a')\right] $$

Q-Learning#

概述#

Q-Learning 是值函数方法,学习最优Q函数。

更新规则#

$$ Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha[r_{t+1} + \gamma \max_a Q(s_{t+1}, a) - Q(s_t, a_t)] $$

其中 $\alpha$ 是学习率。

特点#

  • 离策略:可以学习最优策略,而不遵循它
  • 表格方法:适用于离散状态空间

Deep Q-Network (DQN)#

使用神经网络近似Q函数:

$$ Q(s,a; \theta) \approx Q^*(s,a) $$

关键技巧#

  1. 经验回放:存储经验,随机采样
  2. 目标网络:使用固定目标网络稳定训练

DQN损失#

$$ L(\theta) = \mathbb{E}\left[\left(r + \gamma \max_{a'} Q(s', a'; \theta^-) - Q(s, a; \theta)\right)^2\right] $$

其中 $\theta^-$ 是目标网络参数。


策略梯度#

概述#

策略梯度 直接优化策略,而不是价值函数。

策略梯度定理#

$$ \nabla_\theta J(\theta) = \mathbb{E}[\nabla_\theta \log \pi_\theta(a|s) Q^\pi(s,a)] $$

REINFORCE算法#

$$ \theta \leftarrow \theta + \alpha \nabla_\theta \log \pi_\theta(a_t|s_t) G_t $$

Actor-Critic#

结合策略梯度和价值函数:

  • Actor:学习策略 $\pi(a|s)$
  • Critic:学习价值函数 $V(s)$ 或 $Q(s,a)$

A3C (Asynchronous Advantage Actor-Critic)#

使用优势函数:

$$ A(s,a) = Q(s,a) - V(s) $$

代码实现#

Q-Learning#

import numpy as np
import random

class QLearning:
    def __init__(self, states, actions, learning_rate=0.1, gamma=0.9, epsilon=0.1):
        self.states = states
        self.actions = actions
        self.lr = learning_rate
        self.gamma = gamma
        self.epsilon = epsilon
        self.Q = np.zeros((states, actions))
    
    def choose_action(self, state):
        if random.random() < self.epsilon:
            return random.randint(0, self.actions - 1)
        else:
            return np.argmax(self.Q[state])
    
    def update(self, state, action, reward, next_state):
        current_q = self.Q[state, action]
        max_next_q = np.max(self.Q[next_state])
        new_q = current_q + self.lr * (reward + self.gamma * max_next_q - current_q)
        self.Q[state, action] = new_q

DQN实现#

import torch
import torch.nn as nn
import torch.optim as optim
import random
from collections import deque

class DQN(nn.Module):
    def __init__(self, state_dim, action_dim):
        super(DQN, self).__init__()
        self.fc1 = nn.Linear(state_dim, 128)
        self.fc2 = nn.Linear(128, 128)
        self.fc3 = nn.Linear(128, action_dim)
    
    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        return self.fc3(x)

class DQNAgent:
    def __init__(self, state_dim, action_dim, lr=0.001, gamma=0.99, epsilon=1.0):
        self.state_dim = state_dim
        self.action_dim = action_dim
        self.gamma = gamma
        self.epsilon = epsilon
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        
        self.q_network = DQN(state_dim, action_dim)
        self.target_network = DQN(state_dim, action_dim)
        self.target_network.load_state_dict(self.q_network.state_dict())
        
        self.optimizer = optim.Adam(self.q_network.parameters(), lr=lr)
        self.memory = deque(maxlen=10000)
    
    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))
    
    def act(self, state):
        if random.random() <= self.epsilon:
            return random.randrange(self.action_dim)
        with torch.no_grad():
            q_values = self.q_network(torch.FloatTensor(state))
            return q_values.argmax().item()
    
    def replay(self, batch_size=32):
        if len(self.memory) < batch_size:
            return
        
        batch = random.sample(self.memory, batch_size)
        states, actions, rewards, next_states, dones = zip(*batch)
        
        states = torch.FloatTensor(states)
        actions = torch.LongTensor(actions)
        rewards = torch.FloatTensor(rewards)
        next_states = torch.FloatTensor(next_states)
        dones = torch.BoolTensor(dones)
        
        current_q = self.q_network(states).gather(1, actions.unsqueeze(1))
        next_q = self.target_network(next_states).max(1)[0].detach()
        target_q = rewards + (self.gamma * next_q * ~dones)
        
        loss = nn.MSELoss()(current_q.squeeze(), target_q)
        
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()
        
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay
    
    def update_target_network(self):
        self.target_network.load_state_dict(self.q_network.state_dict())

REINFORCE实现#

class PolicyNetwork(nn.Module):
    def __init__(self, state_dim, action_dim):
        super(PolicyNetwork, self).__init__()
        self.fc1 = nn.Linear(state_dim, 128)
        self.fc2 = nn.Linear(128, 128)
        self.fc3 = nn.Linear(128, action_dim)
    
    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        return torch.softmax(self.fc3(x), dim=-1)

class REINFORCE:
    def __init__(self, state_dim, action_dim, lr=0.001, gamma=0.99):
        self.gamma = gamma
        self.policy = PolicyNetwork(state_dim, action_dim)
        self.optimizer = optim.Adam(self.policy.parameters(), lr=lr)
        self.episode_rewards = []
        self.episode_log_probs = []
    
    def select_action(self, state):
        probs = self.policy(torch.FloatTensor(state))
        dist = torch.distributions.Categorical(probs)
        action = dist.sample()
        log_prob = dist.log_prob(action)
        return action.item(), log_prob
    
    def store_transition(self, log_prob, reward):
        self.episode_log_probs.append(log_prob)
        self.episode_rewards.append(reward)
    
    def update(self):
        returns = []
        G = 0
        for r in reversed(self.episode_rewards):
            G = r + self.gamma * G
            returns.insert(0, G)
        
        returns = torch.FloatTensor(returns)
        returns = (returns - returns.mean()) / (returns.std() + 1e-9)
        
        policy_loss = []
        for log_prob, G in zip(self.episode_log_probs, returns):
            policy_loss.append(-log_prob * G)
        
        self.optimizer.zero_grad()
        policy_loss = torch.stack(policy_loss).sum()
        policy_loss.backward()
        self.optimizer.step()
        
        self.episode_rewards = []
        self.episode_log_probs = []

总结#

  1. 强化学习:通过交互学习最优策略
  2. MDP:强化学习的数学框架
  3. Q-Learning:值函数方法,学习Q函数
  4. DQN:使用神经网络近似Q函数
  5. 策略梯度:直接优化策略
  6. REINFORCE:基础的策略梯度算法

关键要点

  • 强化学习是交互式学习
  • 需要平衡探索和利用
  • Q-Learning学习价值函数
  • 策略梯度直接优化策略
  • DQN结合深度学习和Q-Learning

延伸阅读#

  • 深度强化学习:DQN、A3C、PPO
  • 多智能体强化学习:多智能体系统
  • 模仿学习:从专家演示学习
  • 元学习:快速适应新任务