Jupyter AI

20 深度强化学习之DQN算法

📅 发表日期: 2024年8月15日

分类: 🤖强化学习入门

👁️阅读: --

在上篇中,我们探讨了深度学习在强化学习中的应用,了解了如何利用深度神经网络来近似价值函数和策略。在本篇文章中,我们将深入到深度强化学习的重要算法之一——DQN(Deep Q-Network)算法。DQN不仅利用了深度学习的强大能力,还解决了传统Q学习方法的一些局限性,使得智能体能够在复杂的环境中进行决策。

DQN算法概述

DQN算法是由DeepMind在2013年提出的,旨在使用深度学习的方法来处理具有高维状态空间的强化学习问题。与传统的Q学习方法相比,DQN利用深度神经网络来逼近Q值函数。

Q值函数

在强化学习中,Q值函数Q(s,a)Q(s, a)表示在状态ss下采取动作aa能获得的预期回报。DQN通过神经网络来估计这个函数,即使用一个参数化的函数Q(s,a;θ)Q(s, a; \theta),其中θ\theta是神经网络的参数。

DQN的基本框架

DQN的基本框架主要包括以下几个步骤:

  1. 环境交互:智能体与环境交互,通过状态sts_t观察环境的状态,并选择动作ata_t
  2. 奖励反馈:环境根据智能体的动作给出奖励rtr_t,并返回新的状态st+1s_{t+1}
  3. 经验回放:将(st,at,rt,st+1)(s_t, a_t, r_t, s_{t+1})元组存储到经验回放池中。
  4. 目标网络和训练:定期从经验回放池中随机采样一个批次,更新神经网络参数,以减少Q值函数的逼近误差。

经验回放

在DQN中引入经验回放是其关键创新之一。它可以缓解样本之间的相关性,提供更稳定的学习过程。经验回放的应用允许智能体记住之前的交互,打破了时间序列的相关性,从而提高了学习效率。

经验回放的实现

在实践中,经验回放可以通过一个FIFO(先进先出)队列来实现,存储固定数量的交互记录。例如,Python中的实现如下:

import random
from collections import deque

class ReplayBuffer:
    def __init__(self, max_size):
        self.buffer = deque(maxlen=max_size)

    def add(self, experience):
        self.buffer.append(experience)

    def sample(self, batch_size):
        return random.sample(self.buffer, batch_size)

    def size(self):
        return len(self.buffer)

DQN的损失函数

DQN的核心在于通过最小化损失函数来更新网络。损失函数通常定义为:

L(θ)=E(s,a,r,s)D[(yQ(s,a;θ))2]L(\theta) = \mathbb{E}_{(s,a,r,s') \sim D} \left[ (y - Q(s, a; \theta))^2 \right]

其中,目标yy是由以下公式计算的:

y=r+γmaxaQ(s,a;θ)y = r + \gamma \max_{a'} Q(s', a'; \theta^{-})

这里,γ\gamma是折扣因子,Q(s,a;θ)Q(s', a'; \theta^{-})是来自目标网络的Q值。目标网络是一个延迟更新的网络,用来稳定学习过程。

案例:CartPole环境的DQN实现

为了更好地理解DQN算法,下面以OpenAI的CartPole环境为例,展示一个简单的DQN实现。

环境设置

首先,确保安装了OpenAI Gym库,命令如下:

pip install gym

然后我们可以定义CartPole的DQN算法:

import numpy as np
import gym
import tensorflow as tf

class DQNAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = ReplayBuffer(max_size=2000)
        
        self.gamma = 0.95  # 折扣因子
        self.epsilon = 1.0  # 探索率
        self.epsilon_decay = 0.995
        self.epsilon_min = 0.01
        
        self.model = self._build_model()

    def _build_model(self):
        model = tf.keras.models.Sequential()
        model.add(tf.keras.layers.Dense(24, input_dim=self.state_size, activation='relu'))
        model.add(tf.keras.layers.Dense(24, activation='relu'))
        model.add(tf.keras.layers.Dense(self.action_size, activation='linear'))
        model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(lr=0.001))
        return model

    def act(self, state):
        if np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)
        q_values = self.model.predict(state)
        return np.argmax(q_values[0])

    def replay(self, batch_size):
        minibatch = self.memory.sample(batch_size)
        for state, action, reward, next_state in minibatch:
            target = reward
            if next_state is not None:
                target += self.gamma * np.amax(self.model.predict(next_state)[0])
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)

主程序

继续定义主循环,与环境交互并训练模型:

if __name__ == "__main__":
    env = gym.make('CartPole-v1')
    agent = DQNAgent(state_size=4, action_size=2)

    for e in range(1000):
        state = env.reset()
        state = np.reshape(state, [1, 4])
        for time in range(500):
            action = agent.act(state)
            next_state, reward, done, _ = env.step(action)
            reward = reward if not done else -10
            next_state = np.reshape(next_state, [1, 4])
            agent.memory.add((state, action, reward, next_state))
            state = next_state

            if done:
                print(f"Episode: {e+1}, score: {time}, e: {agent.epsilon:.2}")
                break

            if len(agent.memory.buffer) > 32:
                agent.replay(32)
        
        if agent.epsilon > agent.epsilon_min:
            agent.epsilon *= agent.epsilon_decay

总结

DQN算法通过引入深度学习和经验回放,成功地扩展了传统Q学习的应用范围。它能够处理复杂的、高维的状态空间,使得智能体在多种环境中更为高效地进行学习。在下一篇文章中,我们将深入探讨DQN