探秘强化学习中的双深度Q网络算法

探秘强化学习中的双深度Q网络算法

此篇文章是博主在研习强化学习(RL)领域时,用于自身学习、探究或品鉴之用,是依据博主对相关领域的若干认知所记录的学习摘要与笔记,若存在不当或侵权之处,一经指出将即刻修正,还望海涵。文章归类于👉强化学习
专栏:

【强化学习】- 【单智能体强化学习】(12)---《Double DQN(Double Deep Q-Network)算法》

Double DQN(Double Deep Q-Network)算法

目录

一、Double DQN算法详解

二、算法背景和提出

2.1 过估计偏差问题

2.2 Double Q-Learning的灵感

2.3 Double DQN的提出

三、Double DQN的核心思想

四、算法流程

五、公式推导

[Python] Double DQN算法实现

[Notice] 代码说明

六、优势与特点

七、总结


一、Double DQN算法详解

强化学习领域中,深度Q网络(DQN)是融合深度学习与Q学习的算法,它依靠神经网络去逼近Q函数,从而解决复杂的高维状态问题。不过,DQN存在过估计问题(Overestimation Bias),也就是在更新Q值的时候,由于同时使用同一个网络来选择动作和计算目标Q值,很可能使得Q值的估计偏高。

Double DQN(DDQN)引入了“双网络”机制来缓解该问题,进而提升算法的稳定性与收敛性。


二、算法背景和提出

在强化学习的早期研究里,Q学习是经典算法,它通过构建Q值表来描述每个状态 - 动作对的长期累积奖励。但当状态和动作空间变得极为庞大甚至连续时,Q学习方法难以扩展。于是,深度Q网络(Deep Q-Network, DQN)引入神经网络来逼近Q函数,并取得了显著成果,比如成功应用于Atari游戏。然而,DQN算法在实际应用中暴露出诸多问题,其中过估计偏差(Overestimation Bias)尤为突出。

2.1 过估计偏差问题

在DQN算法中,Q值更新公式如下:

y_t^{DQN} = r_t + \gamma \max_a Q_{\theta^-}(s_{t+1}, a)

其中:

  • r_t是当前的即时奖励;
  • \gamma是折扣因子;
  • Q_{\theta^-} 是目标网络的Q值。

DQN采用“最大值”max操作来选择动作并估计未来价值,这种方式可能引发过高估计。其根本缘由在于:

  1. 同一个网络(目标网络)既负责选择动作(动作选择偏好),又负责评估这些动作的价值(动作的价值计算)。
  2. 神经网络的逼近误差会放大估计值,从而进一步加剧过估计问题。

这种偏差会导致:

  • 策略变得过于激进;
  • 学习过程变得不稳定;
  • 收敛速度减慢甚至无法收敛。

2.2 Double Q-Learning的灵感

Double Q-Learning是一种用于降低过估计问题的经典方法。其基本理念是分离动作选择和价值估计。它运用两个独立的Q值表:

  1. 一个表用于选择动作;
  2. 另一个表用于计算目标值。

Double Q-Learning的目标值公式为:

y_t^{DoubleQ} = r_t + \gamma Q_2(s_{t+1}, \arg\max_a Q_1(s_{t+1}, a))

通过这种分离计算,动作选择的误差不会直接影响目标值计算,从而降低了过估计的风险。


2.3 Double DQN的提出

Double DQN(DDQN)受Double Q-Learning启发,将其思想拓展到深度强化学习领域。主要区别在于:

  1. 使用在线网络(Online Network)来选择动作;
  2. 使用目标网络(Target Network)来估计动作的价值。

Double DQN的目标值公式为:

y_t^{DDQN} = r_t + \gamma Q_{\theta^-}(s_{t+1}, \arg\max_a Q_{\theta}(s_{t+1}, a))

其中:

  • Q_{\theta} 是在线网络,用于选择动作;
  • Q_{\theta^-}是目标网络,用于估计目标Q值。

<p>探秘强化学习中的双深度Q网络算法</p>

这种方法成功解决了DQN的过估计问题,并在多个强化学习任务中展现出更好的性能与稳定性。


三、Double DQN的核心思想

Double DQN通过分离动作选择目标Q值计算来减小过估计问题:

  1. 使用在线网络(Online Network)选择动作。
  2. 使用目标网络(Target Network)计算目标Q值。

这种分离使得目标Q值的计算更为可靠,有助于减少估计偏差。


四、算法流程

1.初始化

初始化两个神经网络:在线网络Q_{\theta}和目标网络Q_{\theta^-}

Q_{\theta^-}的参数定期从Q_{\theta}同步。

2.执行动作

当前状态s_t下,利用Q_{\theta}选择动作a_t

a_t = \arg\max_a Q_{\theta}(s_t, a)

3.存储经验

将转移样本(s_t, a_t, r_t, s_{t+1})存入经验回放池。

4.经验回放

从经验回放池中随机采样一个小批量 (s_i, a_i, r_i, s_{i+1})

5.目标值计算(关键点)

使用在线网络选择下一个状态s_{i+1}的最佳动作:

a' = \arg\max_a Q_{\theta}(s_{i+1}, a)

使用目标网络计算目标Q值:

y_i = r_i + \gamma Q_{\theta^-}(s_{i+1}, a')

6.更新在线网络

使用均方误差(MSE)作为损失函数,对Q_{\theta}进行梯度下降:

L(\theta) = \frac{1}{N} \sum_i \big(y_i - Q_{\theta}(s_i, a_i)\big)^2

7.更新目标网络

每隔一定步数,将Q_{\theta}的参数复制到Q_{\theta^-}


五、公式推导

  1. Q学习目标
    传统DQN的目标值是:y_t^{DQN} = r_t + \gamma \max_a Q_{\theta^-}(s_{t+1}, a)
    这里的 max 操作会导致过估计问题。

  2. Double DQN目标
    DDQN通过分离动作选择和目标计算,目标值改为:
    y_t^{DDQN} = r_t + \gamma Q_{\theta^-}(s_{t+1}, \arg\max_a Q_{\theta}(s_{t+1}, a))

    • 动作 a 是由在线网络 Q_{\theta}选择的。
    • Q值是由目标网络Q_{\theta^-}计算的。
    • 减小过估计的作用

    • 通过在线网络选择动作,可以更准确地反映当前策略的动作价值。

    • 目标网络仅用来计算Q值,减少了目标计算时的估计偏差。

[Python] Double DQN算法 实现

以下给出Double DQN算法的完整Python实现代码,它借助PyTorch框架实现,包含核心的在线网络和目标网络的更新机制:

项目代码已存放于GitCode中,可通过以下链接跳转:🔥

【强化学习】--- Double DQN算法

后续相关单智能体强化学习算法将持续在【强化学习】项目中更新,若该项目对您有所帮助,请为我点个星✨✨✨✨✨,鼓励分享,万分感谢!!!

若下方代码复现存在困难或有问题,也欢迎在评论区留言

1. 导入必要库

import numpy as np  # 导入NumPy库,用于处理数组和数值计算
import torch  # 导入PyTorch库,用于构建和训练深度学习模型
import torch.nn as nn  # 导入PyTorch的神经网络模块,用于构建网络结构
import torch.optim as optim  # 导入PyTorch的优化器模块,用于优化神经网络参数
import random  # 导入Python的随机模块,用于实现随机采样
from collections import deque  # 导入deque数据结构,用于存储经验回放池

2. 超参数设置

# Hyperparameters
GAMMA = 0.99  # 折扣因子,控制奖励的时间衰减
LR = 0.001  # 学习率,用于控制优化器的步长
BATCH_SIZE = 64  # 每次训练的批量大小
MEMORY_CAPACITY = 10000  # 经验回放池的最大容量
TARGET_UPDATE = 10  # 目标网络更新的周期(每10个回合更新一次)

3. 定义网络

# Define the neural network
class QNetwork(nn.Module):  # 定义Q网络,用于逼近Q值函数
    def __init__(self, state_dim, action_dim):
        super(QNetwork, self).__init__()  # 初始化父类
        self.fc1 = nn.Linear(state_dim, 128)  # 第一层全连接层,输入维度为状态维度,输出128维
        self.fc2 = nn.Linear(128, 128)  # 第二层全连接层,输入和输出均为128维
        self.fc3 = nn.Linear(128, action_dim)  # 输出层,输出维度为动作维度

    def forward(self, x):  # 定义前向传播过程
        x = torch.relu(self.fc1(x))  # 第一层激活函数为ReLU
        x = torch.relu(self.fc2(x))  # 第二层激活函数为ReLU
        x = self.fc3(x)  # 输出层不加激活函数,直接输出Q值
        return x

4. 缓存经验区

```python

Replay buffer

class ReplayBuffer: # 定义经验回放池,用于存储和采样经验数据
def init(self, capacity):
self.buffer = deque(maxlen=capacity) # 使用deque实现固定长度的经验池

def push(self, state, action, reward

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12774.html

(0)
LomuLomu
上一篇 2025 年 7 月 6 日
下一篇 2025 年 7 月 6 日

相关推荐

  • IDEA永久激活方法汇总:从激活码到破解码全都有!

    免责声明:下文所述 IDEA 2025.2.1 破解补丁与激活码均源自互联网公开资源,仅限个人学习与研究,严禁商业用途。若条件允许,请支持正版:https://panghu.hicxy.com/shop/?id=18(低至 32 元/年,官方全家桶账号即用即享)。 先放一张“战果图”镇楼:IDEA 2025.2.1 已顺利激活至 2099 年,爽到飞起! 下…

    IDEA破解教程 2025 年 9 月 13 日
    18200
  • 2025年最新DataGrip激活码永久破解教程(支持2099年)

    本教程适用于JetBrains全家桶(包括IDEA、PyCharm、DataGrip、Golang等),手把手教你永久激活至2099年! 先看破解成功效果图,有效期已成功延长至2099年: 下面将详细介绍DataGrip的完整激活流程,该方法同样适用于历史版本,无论你使用什么操作系统都能完美适配! 下载DataGrip安装包 若已安装可跳过此步骤 访问Jet…

    2025 年 5 月 13 日
    38400
  • 深入解析Java字符串编码转换方法getBytes()

    目录导航1. 方法重载解析2. 实际应用演示3. 两种编码参数方式的对比分析3.1 参数形式差异3.2 错误处理机制3.3 编码规范建议3.4 执行效率考量代码实例比较 Java语言中的getBytes()是字符串处理的重要方法,它能够将文本内容转换为特定编码格式的字节序列。该方法在String类中定义,为字符编码转换提供了灵活的实现方案。 1. 方法重载解…

    2025 年 5 月 19 日
    81600
  • 微服务篇-深入了解索引库与文档 CRUD 操作、使用 RestCliet API 操作索引库与文档 CRUD(Java 客户端连接 Elasticsearch 服务端)

    🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 索引库操作 1.1 Mapping 映射属性 1.2 索引库的 CRUD 1.2.1 创建索引和映射 1.2.2 查询索引库 1.2.3 修改索引库 1.2.4 删除索引库 2.0 文档操作 2.1 新增文档 2.2 查询文档 2.3 删除文档 2.4 修改文档 2.4.…

    2025 年 1 月 17 日
    46000
  • Java之反射

    目录 反射 定义 主要用途 反射相关的类 Class类中【获得类相关方法】 Class类中【获得类中属性相关的方法】 Class类中【获得类中注解相关的方法】 Class类中【获得类中构造器相关的方法】 Class类中【获得类中方法相关的方法】 获得Class对象 代码示例1 代码示例2 反射的优缺点 反射 定义 Java的反射(reflection)机制是在…

    2024 年 12 月 28 日
    41300

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信