强化学习与神经网络结合(以 DQN 展开)

发布于:2025-03-31 ⋅ 阅读:(27) ⋅ 点赞:(0)

强化学习中,智能体(Agent)通过与环境交互学习最优策略。当状态空间或动作空间庞大时,传统表格法(如 Q-Learning)难以存储所有状态 - 动作值(Q 值)。此时引入神经网络,用其函数拟合能力近似 Q 函数,即深度 Q 网络(DQN)。

图片所示的运流程

1.环境交互:智能体根据当前状态St,选择动作A执行,环境反馈奖励R,转移到新状态St+1

Q 值计算:将St+1输入 Q 网络,计算所有动作的 Q 值,取最大值

目标值构建:更新目标为

为折扣因子,平衡短期与长期奖励)

损失计算:当前 Q 值Q(St,a)作为预测值,目标值作为标签,通过均方误差(MSE计算损失

网络更新:利用梯度下降优化 Q 网络,减少损失

基于 PyTorch 实现简单 DQN

import torch  
import torch.nn as nn  
import torch.optim as optim  
import gym  

# 定义Q网络  
class QNetwork(nn.Module):  
    def __init__(self, state_dim, action_dim):  
        super(QNetwork, self).__init__()  
        self.fc = nn.Sequential(  
            nn.Linear(state_dim, 64),  
            nn.ReLU(),  
            nn.Linear(64, action_dim)  
        )  

    def forward(self, x):  
        return self.fc(x)  

# 初始化环境与网络  
env = gym.make('CartPole-v1')  
state_dim = env.observation_space.shape[0]  
action_dim = env.action_space.n  
q_net = QNetwork(state_dim, action_dim)  
optimizer = optim.Adam(q_net.parameters(), lr=0.001)  
criterion = nn.MSELoss()  

# 训练循环  
for episode in range(100):  
    state = env.reset()  
    state = torch.FloatTensor(state)  
    total_reward = 0  
    done = False  

    while not done:  
        # 选择动作(简化示例,未包含探索策略)  
        with torch.no_grad():  
            q_values = q_net(state.unsqueeze(0))  
        action = torch.argmax(q_values).item()  

        # 执行动作,获取反馈  
        next_state, reward, done, _ = env.step(action)  
        next_state = torch.FloatTensor(next_state)  
        reward = torch.tensor(reward, dtype=torch.float32)  

        # 计算目标值与当前Q值  
        with torch.no_grad():  
            next_q = q_net(next_state.unsqueeze(0)).max(1)[0]  
        target = reward + 0.99 * next_q  
        current_q = q_net(state.unsqueeze(0))[0][action]  

        # 计算损失并更新网络  
        loss = criterion(current_q, target)  
        optimizer.zero_grad()  
        loss.backward()  
        optimizer.step()  

        state = next_state  
        total_reward += reward  

    print(f"Episode {episode}, Total Reward: {total_reward}")  

env.close()  

agent与env的交互

判断done:

done 状态是由环境(env)在交互过程中返回的终止信号,用于标识当前回合(episode)是否结束

done 的来源:

在 observation_, reward, done = env.step(action) 这一步中,环境会根据智能体执行的动作(action),反馈当前状态的后续信息:

observation_:执行动作后转移到的新状态。

reward:执行动作获得的即时奖励。

done:一个布尔值(True/False),由环境规则定义。当环境认为当前回合结束时(如达到任务目标、触发终止条件等),done 会被置为 True

double DQN

Double DQN(Double Deep Q-Network)是对传统DQN的改进算法,旨在解决Q值估计过估计(Overestimation)的问题

传统DQN的局限

传统DQN通过 同一个网络 同时完成两个任务:

1. 选择动作:根据当前状态选择Q值最大的动作(贪心策略)。

2. 评估价值:计算目标Q值以更新网络参数。

这会导致**过估计**问题:网络在计算目标值时,倾向于选择自身高估的动作,从而引入偏差,导致训练不稳定甚至发散。

Double DQN的核心改进

Double DQN通过 分离动作选择和动作评估 来解决过估计问题,具体方法如下:

1. 引入两个网络:

- 在线网络(Online Network):负责选择动作(ε-贪心策略)

- 目标网络(Target Network):负责计算目标Q值,其参数定期从在线网络复制

2. 解耦动作选择与评估:

- 用在线网络选择动作a_t = argmax Q(s_t, a; θ)

- 用目标网络评估该动作的Q值 Q(s_{t+1}, a_t; θ^-)

算法流程

1. 初始化:

- 在线网络和目标网络结构相同,但参数独立

- 目标网络参数初始化为在线网络的副本θ^- = θ

2. 经验回放池:存储训练样本s_t, a_t, r_t, s_{t+1}

3. 训练循环:

- 步骤1:在线网络根据当前状态选择动作

- 步骤2:执行动作,获取奖励和下一状态

- 步骤3:将样本存入经验回放池

- 步骤4:从池中随机采样一批数据

- 步骤5:计算目标Q值:

target_Q = r + γ * Q_target(s_{t+1}, argmax Q_online(s_{t+1}, a; θ); θ^-)

- 步骤6:用在线网络计算当前Q值,并通过MSE损失更新参数

- 步骤7:定期更新目标网络参数(如每C步复制θ到θ^-)

关键技术细节

1. 目标网络更新策略:

- 目标网络参数并非实时更新,而是每隔C步从在线网络复制一次,避免梯度震荡

2. 经验回放(Experience Replay):

- 打破数据相关性,提高样本利用率

3. ε-贪心策略:

- 平衡探索与利用,确保充分探索环境

伪代码

初始化在线网络 Q(θ) 和目标网络 Q(θ^-)
θ^- = θ  # 初始同步
经验回放池 D 初始化

for episode in episodes:
    初始化状态 s
    while s 非终止状态:
        根据 ε-贪心策略选择动作 a(由 Q(θ) 决定)
        执行动作 a,得到奖励 r 和下一状态 s'
(s, a, r, s') 存入 D
        从 D 中随机采样 mini-batch
        for 每个样本 (s_i, a_i, r_i, s'_i):
            a_next = argmax Q(s'_i, a; θ)  # 在线网络选动作
            Q_target = r_i + γ * Q_target(s'_i, a_next; θ^-)  # 目标网络评估
            loss = MSE(Q(s_i, a_i; θ), Q_target)
            反向传播更新 θ
        每隔 C 步,θ^- = θ  # 同步目标网络
        s = s'

优势与效果

1. 减少过估计:通过分离动作选择和评估,显著降低Q值偏差

2. 训练更稳定:目标网络参数定期更新,避免梯度震荡

3. 性能提升:在Atari游戏等任务中,Double DQN比传统DQN表现更优,如《Pong》《Breakout》等

扩展与变种

1. Dueling DQN:将Q值分解为状态价值和动作优势,进一步提升性能

2. Rainbow DQN:融合Double DQN、Dueling DQN、Prioritized Replay等技术

3. Noisy DQN:通过噪声层实现探索,替代ε-贪心策略

Double DQN通过解耦动作选择与评估,有效解决了传统DQN的过估计问题,成为深度强化学习的经典算法之一。其核心思想是利用两个网络的分工协作,平衡探索与利用,提升训练稳定性和样本效率

dueling DQN

Dueling DQN(对决网络 DQN)是对传统 DQN 的改进,核心在于将 Q 值拆解为状态价值和动作优势,让网络更高效地学习

核心思想:拆分 Q 值的意义

传统 DQN 直接学习 Q (s, a),即 “状态 - 动作” 的价值。而 Dueling DQN 将 Q 值拆分为两部分:

状态价值 V (s):衡量当前状态本身的好坏,不依赖具体动作。例如 “站在十字路口” 这个状态的基础价值。

动作优势 Adv (s, a):衡量某个动作相对于平均动作的优势。例如 “在十字路口,右转比左转 / 直行更好” 的优势。

公式:Q(s, a) = V(s) + Adv(s, a)。

通过这种拆分,网络能更清晰地学习 “状态本身的价值” 和 “动作的相对优势”,尤其在状态价值明显、动作选择影响较小时,学习效率更高。

网络结构:共享特征 + 双分支

共享特征提取层:

前几层网络(如卷积层、全连接层)用于提取状态特征,类似传统 DQN 的特征处理。双分支结构:V (s) 分支:输入共享层特征,输出标量(状态价值)。

Adv (s, a) 分支:输入共享层特征,输出向量(每个动作的优势)。

约束条件:为避免 V 和 Adv 的表示冗余,通常对 Adv 添加约束,例如让同一状态下所有动作的 Adv 均值为 0(∑Adv(s, a)/num_actions = 0)。这样 V (s) 实际代表该状态下所有动作 Q 值的平均值。

共享特征提取层:特征的 “通用加工厂”

作用:无论是计算状态价值 V(s) 还是动作优势Adv(s,a),都需要先从原始状态(如游戏画面、机器人传感器数据)中提取有意义的特征。

类比理解:类似炒菜前的备菜环节。不管最后是要炒青菜还是炒肉,都需要先洗菜、切菜(提取特征)。共享特征层就是 “洗菜切菜” 的通用流程,用卷积层、全连接层等处理原始状态,得到后续分支可用的特征。

双分支结构:分工明确的 “价值分析员”

V(s) 分支

目标:评估“状态本身的价值”,不考虑具体动作。例如,在“游戏角色站在能量道具旁边”的状态,V(s)衡量这个状态潜在的整体收益(无论捡道具还是不捡,先评估状态基础价值)。

输出:一个标量(单一数值),代表状态 s 的价值。

Adv(s,a) 分支:

目标:评估每个动作的“相对优势”。例如,在上述状态下,“捡道具”这个动作比“不捡道具”好多少,优势通过Adv(s,a) 体现。

输出:向量,每个元素对应一个动作的优势值。比如游戏有 4 个动作,就输出 4 个数值,分别表示每个动作的优势。

更新机制:为何能 “一次性调整所有 Q 值”?

普通 DQN 的更新局限:

传统 DQN 更新时,只针对选中的动作调整 Q 值。例如在状态 s 下选动作 a,仅更新 Q (s, a),其他动作的 Q 值不受影响。Dueling DQN 的更新优势:由于Adv(s, a)的和为 0 的约束,网络更倾向于先调整V(s)(状态价值)。而V(s)是该状态下所有动作 Q 值的平均值,调整V(s)相当于对该状态下所有动作的 Q 值进行了一次全局更新。

举例:若状态 s 的 V (s) 从 10 提升到 12,且 Adv (s, a) 不变,那么所有动作的 Q 值都会增加 2。这种 “批量更新” 让网络学习更高效,尤其在状态价值主导决策时,能更快收敛。

Noisy DQN:通过噪声层实现探索,替代 ε- 贪心策略

传统探索策略的局限

ε- 贪心的问题:通过固定概率(如 ε=0.1)随机选动作实现探索,但 ε 需手动调整,且无法根据训练阶段动态适应。例如,前期需要强探索,后期应聚焦利用,ε- 贪心难以灵活平衡

Noisy DQN 的核心原理:参数空间噪声

Noisy DQN 将探索直接融入网络结构,通过在网络参数中添加噪声,让智能体在决策时自然产生探索行为:

噪声添加方式:在网络的全连接层参数(权重W和偏置b)中加入噪声。例如,对某一层的权重W,实际使用W + epsilon_W是噪声,偏置b同理使用b + epsilon_b。

探索与利用的平衡:训练阶段:噪声激活,智能体因参数扰动尝试不同动作,实现探索。例如,原本选 Q 值最高的动作,加噪声后可能因参数变化选择其他动作。

推理阶段:去掉噪声(或噪声趋近于 0),直接基于确定的网络参数选择最优动作,专注利用。

实现细节:噪声层设计

噪声类型:常用高斯噪声,如权重噪声,偏置噪声,通过超参数sigma控制噪声强度。

Frostbite 噪声层:一种典型实现,对权重和偏置的噪声初始化做特殊设计。例如,权重噪声epsilon_W的每个元素初始化为(x是高斯分布样本),确保噪声有合理的方差尺度,避免探索过度或不足。

噪声的动态调整:训练中可逐渐降低噪声强度(如退火策略),让智能体从探索为主过渡到利用为主,无需像 ε- 贪心一样手动设定探索概率。

Rainbow_DQN如何计算连续型的Actions

Rainbow DQN 最初设计用于离散动作空间(如 Atari 游戏中的有限操作),若要处理连续动作空间,需对其进行改造

离散化处理:将连续动作转为离散

区间划分对连续动作的每个维度(如机器人关节角度、车辆速度)划分离散区间。例如,动作是二维连续空间 (a_1, a_2),可将 a_1分为 N_1 个区间,a_2分为 N_2个区间,形成N_1 * N_2个离散动作组合。

直接套用 Rainbow DQN离散化后,动作空间变为有限集合,直接使用 Rainbow DQN 的网络结构(如融合 Double DQN、Dueling DQN 等模块)计算每个离散动作的 Q 值,选择 Q 值最高的动作执行。局限性:离散化粒度影响性能,粒度过粗丢失细节,过细则计算量剧增。

结合连续动作策略网络:改造输出层

若需保持动作连续性,可改造 Rainbow DQN 的网络结构,引入连续动作生成机制:

策略网络输出修改网络末端,输出连续动作的参数。例如:均值 - 方差输出:网络输出动作的均值 mu和方差sigma^2,基于高斯分布 采样连续动作。

直接回归:通过全连接层直接回归连续动作值(如 DDPG 的思路),但需结合评论家网络(Critic)评估动作价值,与 Rainbow DQN 的 Q 学习框架融合。

价值函数计算保留 Rainbow DQN 的多组件改进(如优先经验回放、双网络结构),但将 Q 值计算适配连续动作。例如,使用积分或采样近似连续动作空间的 Q 值:

其中是连续动作的策略分布。

典型实践框架

实际应用中,常将 Rainbow DQN 的优化组件(如多步引导、噪声探索)与连续动作算法结合,形成新框架:

网络结构:特征提取层:与 Rainbow DQN 一致,提取状态特征。

策略分支:输出连续动作参数(如均值、方差)。

价值分支:计算状态 - 动作对的 Q 值,融合 Dueling DQN 等思想。

训练流程:

结合策略梯度(PG)或深度确定性策略梯度(DDPG)的训练方式,利用 Rainbow DQN 的经验回放、多步更新等技术优化训练稳定性。


网站公告

今日签到

点亮在社区的每一天
去签到