20 深度强化学习之DQN算法

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

DQN算法概述

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

Q值函数

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

DQN的基本框架

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

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

经验回放

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

经验回放的实现

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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(\theta) = \mathbb{E}_{(s,a,r,s’) \sim D} \left[ (y - Q(s, a; \theta))^2 \right]
$$

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

$$
y = r + \gamma \max_{a’} Q(s’, a’; \theta^{-})
$$

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

案例:CartPole环境的DQN实现

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

环境设置

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

1
pip install gym

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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)

主程序

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

20 深度强化学习之DQN算法

https://zglg.work/reinforcement-learning-zero/20/

作者

IT教程网(郭震)

发布于

2024-08-15

更新于

2024-08-16

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论