一、总思想及算法核心特点
1. 局部观测 vs 全局状态
- DDPG:基于全局环境状态进行决策
- MADDPG :每个智能体仅能获取局部观测信息
2. Critic网络中心化训练
- Critic网络训练 使用所有智能体的联合信息进行目标Q值计算 ,但每个智能体维护独立的奖励函数,适应协作、竞争、混合任务场景
3. Actor网络分布式执行
- Actor网络训练与执行 完全基于局部信息
- 训练:通过中心化Critic获得梯度指导
- 输出:无需其他智能体信息,是真正的分布式
二、Actor更新:以2智能体+batchsize=1为例
以MPE simple协作场景为背景,2智能体+batchsize=1为例叙述更新过程。
1. 场景前提
- 智能体配置:Agent1(作为我们例子中待更新主体)、Agent2(与agent1协作);
- 观测维度:8维(自身x/y坐标 + 自身x/y速度 + 其他智能体相对x/y位置 + 目标相对x/y位置);
- 动作维度:2维(x/y方向速度,范围[-1,1]);
- batchsize:1(单次更新使用1组历史经验,每组经验包含2个智能体的(s,a,r,s',done));
2. 步骤1:采样历史联合经验(固定值,无梯度)
从Agent1和Agent2的回放池中,采样1组"历史交互经验",所有数据为预先存储的固定值(与当前训练参数无关,无梯度):
数据类型 | Agent1(待更新) | Agent2 | 数据维度 | 含义说明 |
---|---|---|---|---|
历史观测(obs) | obs1 = [0.2, 0.3, 0.1, -0.2, -0.1, 0.2, 0.5, -0.3] |
obs2 = [-0.1, 0.5, 0.2, -0.3, 0.3, -0.2, 0.4, -0.1] |
1×8 | Agent1观测:自身在(0.2,0.3),x方向速度0.1,y方向速度- 0.2 |
历史动作(act) | act1_old = [0.2, -0.1] |
act2_old = [0.3, 0.2] |
1×2 | Agent1旧动作:x方向速度分量0.2,y方向速度分量-0.1 |
3. 步骤2:生成Agent1的新动作(网络输出,有梯度)
- 生成新动作 :
用待训练的Agent1 Actor网络,输入步骤1中Agent 1的历史观测obs1
,生成1个新动作act1_new = [0.3, -0.5]
(与历史动作维度一致,方便后续替换,这是"当前网络"对历史场景的改进动作) - 替换动作 :构造联合动作列表,固定Agent 2的历史动作
act2_old
不变,仅将 Agent 1的动作从旧动作act1_old
替换为新动作act1_new
。[act1_old, act2_old]
变为[act1_new, act2_old]
。此步的核心目的:孤立Agent1新动作的影响,确保梯度只回传给Agent 1。
4. 步骤3:计算新Q值与策略损失
- 计算新Q值 :将
[联合观测列表, 联合动作列表]
输入Critic网络,得到一个Q值; - 计算策略损失 :Actor目标是最大化Q值,因此损失定义为"负Q值":
p_loss = -Q
。 - 计算梯度 :对Agent 1的权重
w
求偏导,链式法则。
**通过 "计算Q 值→策略损失→梯度回传",更新Agent 1的Actor网络参数,让Agent 1的Actor网络在相同的观测下倾向输出Q值更大的好行为。
一、Critic更新:同样以2智能体+batchsize=1为例
以MPE simple协作场景为背景,2智能体+batchsize=1为例叙述Critic(中心化价值网络)的更新过程。Critic的核心目标是拟合"TD目标Q值",将critic输出的实际Q值向TD目标Q值靠近,为Actor提供准确的价值反馈。
1. 场景前提
- 智能体配置:Agent1(Critic网络待更新智能体)、Agent2;
- 观测/动作维度:与Actor一致------观测8维(自身坐标+速度+相对位置)、动作2维(x/y速度,范围[-1,1]);
- batchsize :1(单次更新使用1组完整历史经验,含
<联合观测, 联合动作, 即时奖励, 下一联合观测, 终止标志>
); - 关键参数 :折扣因子
gamma=0.95
(权衡未来价值的重要性)、终止标志done=False
(当前经验非回合结束则需计算未来价值,否则不用); - Critic核心依赖:需调用"target Actor网络"生成下一动作、"target Critic网络"计算下一Q值,再据此计算目标TD值,与实际Q值构成loss,梯度下降更新online Critic参数。
2. 步骤1:采样历史联合经验(固定值,无梯度)
从回放池采样1组"完整联合经验",所有数据为预先存储的固定值(与当前Critic训练参数无关,无梯度),与Actor更新只需要经验中的**"当前观测"和"当前动作"不同,Critic更新还需要额外的"奖励"和"下一状态"**:
数据类型 | Agent1(示例数据) | Agent2(示例数据) | 数据维度 | 含义说明 |
---|---|---|---|---|
历史观测(obs) | obs1 = [0.2, 0.3, 0.1, -0.2, -0.1, 0.2, 0.5, -0.3] |
obs2 = [-0.1, 0.5, 0.2, -0.3, 0.3, -0.2, 0.4, -0.1] |
1×8 | 当前时刻两智能体的观测 |
历史动作(act) | act1_old = [0.2, -0.1] (x右0.2,y下0.1) |
act2_old = [0.3, 0.2] (x右0.3,y上0.2) |
1×2 | 当前时刻两智能体的动作 |
即时奖励(reward) | reward1 = 0.1 |
reward2 = 0.3 |
1×1 | 在自身智能体观测下采取动作带来的协作奖励 |
下一观测(next_obs) | next_obs1 = [0.25, 0.28, 0.12, -0.18, -0.08, 0.18, 0.45, -0.28] |
next_obs2 = [-0.05, 0.52, 0.22, -0.28, 0.28, -0.22, 0.38, -0.12] |
1×8 | 执行当前动作后,两智能体的下一时刻观测 |
终止标志(done) | False 全局标志 |
False 全局标志 |
1×1 | 表示未达到回合结束条件,需计算长期价值 |
3. 步骤2:计算TD目标Q值
TD目标Q值是结合"即时奖励+未来价值估计"计算,依赖目标Actor 和目标Critic计算:
-
生成下一联合动作(next_act) :每个智能体使用自己的目标Actor网络生成目标动作(Agent1用Agent1的目标Actor,Agent2用Agent2的目标Actor),其中目标网络的更新逻辑都是参数缓慢融合主网络参数进行更新,更稳定:
- Agent1目标动作:
target_act1 = [0.28, -0.15]
; - Agent2目标动作:
target_act2 = [0.32, 0.18]
; - 联合下一动作:
next_act_n = [target_act1, target_act2]
。
- Agent1目标动作:
-
计算目标Q值(target_q) :使用当前智能体(Agent1)的目标Critic网络,输入"下一联合观测(next_obs1+next_obs2)+ 下一联合动作(next_act_n)",评估目标Q值:
- 目标Critic输出:
target_q = 0.2
(表示执行next_act_n后,未来能获得的折扣价值约为0.2)。
- 目标Critic输出:
-
计算TD目标Q值(TD_target) :依据分布式执行的思想,虽然训练使用的是多智能体联合"观测"和"动作",但"奖励"使用的是当前智能体(Agent1)的奖励reward1 ,代入公式
TD_target = reward1+ gamma * (1 - done) * target_q = 0.29
,得到TD目标Q值,该值和online Critic网络输出的实际Q值(步骤3.1介绍)相对应,在后面更新网络时计算损失使用。
4. 步骤3:计算Q值损失与Critic参数更新
Critic的损失是"在线Q值(当前Critic输出)与TD目标值"的均方误差(MSE),通过最小化损失优化Critic参数,让价值评估更准确:
-
计算在线Q值(q_online) :用online Critic网络 ,输入"当前联合观测(obs1+obs2)+ 当前联合动作(act1_old+act2_old)",输出当前动作的价值评估计
q_online = 0.25
,与TD目标Q值0.29存在差距。 -
计算Q值损失(q_loss) :损失定义为"在线Q值与TD目标Q值的平方均值"(MSE),公式对应代码中的
tf.reduce_mean(tf.square(q - target_ph))
。 -
梯度回传与参数更新 :用优化器(如Adam)最小化q_loss,同时裁剪梯度(防止梯度爆炸),更新在线Critic网络的参数(q_func_vars),让下次评估时"q_online更接近TD_target"。
二、代码相关定义
代码使用openAI MADDPG开源代码,tensorflow1.x
链接:[https://gitcode.com/gh_mirrors/ma/maddpg?source_module=search_result_repo\]
obs_ph_n / act_ph_n
:智能体的"观测 / 动作"占位符列表,用于接收训练时的批量观测和动作数据。p_func / q_func
:是网络结构模板,负责 "定义网络有几层、每层多少神经元、用什么激活函数" 等结构细节p_train / q_train
:负责 "计算损失、梯度更新、生成可调用函数" 等训练流程p_func_vars/q_func_vars/target_p_func_vars/target_q_func_vars
:是所有网络可训练参数pg_loss
:Actor 策略损失,计算方式为**-tf.reduce_mean(q)**q_loss
:Critic Q 值损失,计算方式为tf.reduce_mean(tf.square(q - target_ph))update_target_p/update_target_q
:目标 Actor/Critic 网络软更新函数,*target = τ*online + (1-τ)target- 封装函数:
1.train
:封装actor和critic的训练函数,actor网络输入(所有智能体的观测 + 动作),输出损失,执行优化。critic网络输入(所有智能体的观测 + 动作+目标Q值),输出损失,执行优化。
2.act
:封装动作生成函数,输入(当前智能体的观测),输出采样动作,二维,表示x和y方向的速度分量。
3.p_values
:封装"动作分布生成函数",输入(当前智能体的观测),输出"动作分布的参数"(而非最终动作),四维,表示x和y方向速度分量的均值和方差。
q_values
:封装"Q值查询函数",输入(所有智能体的
观测、所有智能体的
动作),输出Critic计算的Q值。
5.target_act
:封装目标网络动作生成函数,输入(当前智能体的下一状态观测),输出下一状态采样动作。
target_q_values
:封装目标网络Q值生成函数,输入(所有智能体的
下一状态观测,所有智能体的
下一状态下的动作),输出下一状态下采取动作的Q值。
三、学习过程中遇到的问题
问题 | 解答 |
---|---|
1.Actor网络训练时,为什么需要将所有智能体的观测和动作都输入网络,却又要将对自身智能体的经验依据观测重新生成动作?如何确保这个训练过程仅与自身智能体的Q 值相关,而不受其他智能体的干扰? | Actor网络是分布式训练的,也就是只根据自身智能体的Q值执行梯度下降,而训练时之所以要输入所有智能体的观测和动作,是因为Critic网络是中心化的(这部分在前面有提到过,critic网络的训练是中心化的),会基于全局信息评估 "联合动作的整体价值"。那么为了实现分布式训练,就直接使用其余智能体的观测和动作(均为回放池中的固定值,无梯度),而自身智能体则基于自身观测重新生成动作,此时 Critic 输出的 Q 值变化就仅由自身新动作导致。最终保证训练只与自身相关的关键是梯度传播机制:其他智能体的观测和动作是无梯度的固定值,梯度只能通过 "自身新动作→自身 Actor 参数" 的路径传播,仅更新自身网络参数,从而实现 "用全局 Q 值评估、按自身参数更新" 的分布式训练逻辑。 |
2. | |
3. |