Python实现DQN时能否为智能体的动作添加执行约束?
可行性说明
完全可以在DQN中实现该约束,DQN的动作选择逻辑和核心的Q网络更新、经验回放、损失计算模块是解耦的,你只需要在动作选择的决策层自定义规则即可,不需要修改原有DQN的核心结构,也不会影响模型的正常收敛。
基于TensorFlow框架的实现方案
- 首先定义约束相关的跟踪变量
提前明确你要求必须执行的特定动作索引、要求执行的总次数n,再维护一个计数器跟踪该动作的已执行次数,你可以根据需求选择是「每个episode都需要执行n次该动作」还是「整个训练/推理周期总共执行n次该动作」,前者需要每个episode重置计数器,后者全程不重置即可。 - 自定义动作选择逻辑
在原有DQN的ε-贪心(训练阶段)或贪心(推理阶段)动作选择逻辑前,优先判断约束是否完成,未完成时直接返回指定动作,完成后再走原有DQN的动作选择逻辑即可。 - 代码示例
import tensorflow as tf from tensorflow.keras import layers # 原有DQN网络定义无需修改 class DQN(tf.keras.Model): def __init__(self, state_dim, action_total): super().__init__() self.hidden1 = layers.Dense(64, activation='relu') self.hidden2 = layers.Dense(64, activation='relu') self.q_output = layers.Dense(action_total) def call(self, input_state): x = self.hidden1(input_state) x = self.hidden2(x) return self.q_output(x) # ------------ 约束相关参数配置 ------------ TARGET_ACTION = 3 # 替换为你要求必须执行的特定动作索引 REQUIRED_EXEC_N = 8 # 替换为要求的执行次数n exec_counter = 0 # 动作执行次数计数器 ACTION_TOTAL = 6 # 替换为你的环境总动作数量 EPSILON = 0.1 # ε-贪心探索率,训练阶段用,推理阶段可设为0 # 初始化DQN模型,这里以状态维度为4举例 q_network = DQN(state_dim=4, action_total=ACTION_TOTAL) def action_selector(current_state): global exec_counter # 优先满足约束:未完成执行次数时直接返回指定动作 if exec_counter < REQUIRED_EXEC_N: exec_counter += 1 return TARGET_ACTION # 约束完成后走原有DQN动作选择逻辑 # 训练阶段ε-贪心 if tf.random.uniform(shape=(), minval=0, maxval=1) < EPSILON: return tf.random.uniform(shape=(), minval=0, maxval=ACTION_TOTAL, dtype=tf.int32).numpy() # 贪心选择Q值最大的动作 current_state = tf.expand_dims(tf.convert_to_tensor(current_state, dtype=tf.float32), axis=0) q_vals = q_network(current_state) return tf.argmax(q_vals, axis=1).numpy()[0] # 每个episode开始时如果需要重置计数器,调用即可 # exec_counter = 0
- 额外注意事项
如果你的约束有附加条件,比如仅在特定状态下才需要优先执行指定动作,只需要在计数器的判断逻辑中增加状态过滤规则即可,其他部分无需修改。DQN的损失计算、经验回放、目标网络更新等核心逻辑完全不需要调整,仅在动作选择层加约束即可,不会影响原有模型的训练效果。
内容的提问来源于stack exchange,提问作者python_interest
相关产品推荐
相关产品推荐

