ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

蜂窝网资源分配与深度强化学习:从MDP建模到工程避坑

蜂窝网资源分配与深度强化学习:从MDP建模到工程避坑 简介这是一份来自《通信学报》2019年2月第40卷第2期的学术论文PDF适合无线通信、深度学习及智能资源管理方向的科研人员和研究生研读。论文针对蜂窝网资源分配中的多目标优化问题提出了一种基于深度强化学习的完整算法框架一方面构建深度神经网络DNN优化蜂窝系统传输速率实现前向传输另一方面将能量效率作为奖惩值引入Q-learning机制构造误差函数并通过梯度下降法迭代更新DNN权值形成闭环训练流程。仿真实验表明该算法可自主设定资源分配方案的偏重程度收敛快速在传输速率和系统能耗方面均优于传统博弈论、图论着色等方案。资源共1个PDF文件大小1.09MB内含完整摘要、正文、数学公式、仿真图表及参考文献可帮助读者系统掌握深度强化学习在蜂窝网络资源分配中的建模思路、实现细节与性能评估方法也可作为相关课题的参考文献。目前该资源已有315人学习适合需要快速深入了解该算法或用于论文写作参考的研究者。1. 蜂窝网资源分配遇上深度强化学习先想清楚再动手无线接入网里的资源分配过去靠比例公平、注水算法这类显式优化场景一变就要重新推导目标函数和约束。深度强化学习的思路是把它当成序贯决策问题让智能体通过和仿真环境大量交互自己学出一套功率和频谱分配策略。这篇笔记不推公式讲怎么把深度强化学习落到蜂窝网资源分配这个具体场景问题建模、平台搭建、参数调优以及在真实部署前最容易踩的坑。适合做接入网算法预研的工程师也适合想从单智能体往多小区扩展的研究生。先给结论跑通 demo 不难难在奖励设计和环境仿真这两件事占掉一个项目至少一半时间。2. 把蜂窝网资源分配写成 MDP状态、动作与奖励设计的三个决定深度强化学习在蜂窝网里落地第一个拦路虎不是模型而是问题建模。资源分配在无线网络里天然是序贯决策问题信道随时间变化用户队列长度和业务到达也随时间变化上一时刻的功率分配还会影响下一时刻的干扰水平。把这段交互过程抽象成马尔可夫决策过程是整个方向从论文走向代码的第一道工序。很多实现跑不动、学不会回看根因往往不是神经网络写错了而是 MDP 元素定义得含糊。2.1 从优化问题到 MDP为什么时序决策是更好的描述传统资源分配算法的套路是给定当前信道矩阵、用户速率需求和功率上限建模成一个带约束的优化问题用凸优化或启发式算法求解。这个思路在静态场景下很有效但蜂窝网是动态的——用户移动、业务突发、干扰耦合每一时刻的决策都会影响后续时隙的信道状态和队列积压。深度强化学习的优势在于它不需要显式建模状态转移概率而是用仿真环境充当转移概率让智能体在试错中逼近最优策略。MDP 四元组在蜂窝网资源分配问题里可以这样映射MDP 元素蜂窝网资源分配中的对应物状态 s信道状态信息CSI、用户队列长度、历史平均吞吐、干扰测量值动作 a功率分配矢量、物理资源块PRB调度结果、用户配对方式转移概率 P信道衰落演进、用户移动轨迹、业务到达过程奖励 r系统效用加权吞吐、时延惩罚、能效指标、公平性指标这里最容易被忽略的一点是转移概率不需要写成解析式。环境仿真就是转移概率的实现智能体的每一次 step 都在环境里往前走一个时隙拿到新的观测。这也意味着环境仿真的逼真程度直接决定了训练出来的策略在真实系统里是否可用——这一点后面讲仿真平台时还会展开。2.2 状态空间和动作空间怎么切离散与连续的选择状态空间的设计决定了智能体“看得到什么”。常见做法是把三个向量拼进状态归一化信道增益、归一化队列长度、历史平均吞吐。全量 CSI 矩阵维度太大训练时容易过拟合到特定信道布局所以一般会对信道增益做降采样或者只保留每个用户在自己占用 PRB 上的信道增益。动作空间的选择更容易翻车。PRB 调度是组合问题天然是离散动作功率分配是连续值习惯用连续动作。两者混在一起时不要直接枚举联合动作因为用户数和 PRB 数稍涨动作空间就会爆炸。我一般会采用分层决策上层用决策网络输出功率控制系数下层用一个独立规则模块做 PRB 指派或者反过来。下面是最小环境接口的示例class CellularResourceAllocEnv: def __init__(self, n_ues8, n_prbs10, max_steps200): self.n_ues n_ues self.n_prbs n_prbs self.max_steps max_steps self.time_slot 0 self.channel None self.queue None self.history_throughput None def reset(self): self.time_slot 0 self.channel generate_fading_channel(self.n_ues, self.n_prbs) self.queue np.random.randint(0, 100, sizeself.n_ues) self.history_throughput np.ones(self.n_ues) return self._build_obs() def step(self, action): power_vector, prb_assignment action rate compute_rate(self.channel, power_vector, prb_assignment) reward self._compute_reward(rate, power_vector) self.time_slot 1 self.channel evolve_channel(self.channel) self.queue update_queue(self.queue, rate) done self.time_slot self.max_steps return self._build_obs(), reward, done, {} def _build_obs(self): return np.concatenate([ normalize(self.channel), self.queue / 100.0, self.history_throughput / np.max(self.history_throughput 1e-6) ])这个接口遵守 reset 和 step 协议可以和 DQN、PPO、MADDPG 任意一种算法对接。_build_obs里把队列长度除以 100、历史吞吐做最大值归一化是为了让各维度的量级一致否则神经网络前向计算时数值会被某一维特征主导。generate_fading_channel和evolve_channel是信道模型函数后面仿真平台部分会给出具体实现。2.3 奖励函数是第一行代码先让智能体知道什么是“好”奖励函数是整个方案里最值得先写、也最值得反复改的地方。蜂窝网资源分配最常见的奖励是系统效用的加权组合比如吞吐、公平性和时延。直接用和速率做奖励训练出来的策略会偏向信道条件好的用户牺牲边缘用户体验只用时延做惩罚又可能让智能体通过降低功率来逃避切换开销。因此我习惯用对数速率作为公平性项再叠加队列惩罚和功率惩罚def _compute_reward(self, rate, power_vector): fairness np.sum(np.log(rate 1e-6)) / self.n_ues queue_penalty -0.05 * np.mean(self.queue) power_penalty -0.02 * np.mean(np.square(power_vector)) return fairness queue_penalty power_penalty对数速率来自于比例公平调度的经典结论最大化所有用户对数吞吐之和能够同时兼顾系统吞吐和公平性。加1e-6是为了避免速率为 0 时对数取无穷。队列惩罚项让智能体主动规避积压过重的用户功率惩罚项防止它毫无节制地加大发射功率。三个系数的量级很关键如果奖励绝对值动辄几十Q 值估计会很难收敛一般先让主项对数速率的量级在 1 左右其他项作为微调系数训练过程中再逐步调整。3. DQN、PPO 还是 MADDPG算法选型与仿真平台搭建MDP 定义清楚之后紧接着就是选算法和搭环境。很多教程上来直接给你一段 DQN 代码容易造成错觉好像任何场景都能套同一个算法。实际上算法选型要看动作空间和智能体数量平台搭建要看仿真速度和可复现性。这三件事没想明白后面调参全是血泪。3.1 三种算法怎么分工按状态维度和动作类型选DQN 系列包括 Double DQN、Dueling DQN适合动作空间离散且有限的场景典型应用是 PRB 调度。动作是选哪几个资源块分给哪些用户动作空间不大时效果稳定实现也简单。PPO 适合连续动作空间比如功率分配它通过截断的代理目标函数限制每次更新的步长训练稳定性和样本效率在资源分配任务里表现都不错。MADDPG 适合多小区多智能体场景每个小区独立决策但通过中心化评论家共享全局信息收敛难度更高实现也更复杂。经常有人问多小区场景是不是直接用 MAPPO多智能体 PPO 的思路确实在不少论文里跑出了比 MADDPG 更好的稳定性但代价是智能体之间需要通信或全局状态做价值评估工程复杂度和训练开销都会上一个台阶。我的选型经验是这样算法动作类型适用规模训练稳定性实现难度DQN 系列离散单小区、动作空间有限中等低PPO连续单小区或多小区集中式决策高中MADDPG连续/离散多小区分布式决策低高这里给一个非常主观但实用的判断标准如果你的环境单步交互时间超过 1 毫秒先别想着上 MADDPG优先把 DQN 或 PPO 跑通。多智能体算法的调试成本是单智能体的几倍问题叠加时很难定位到底是哪路梯度在崩。3.2 用 Python 搭一个最小蜂窝网仿真环境信道与速率计算仿真环境是深度强化学习里最被低估的部分。训练过程中 90% 的时间花在智能体和环境的交互上环境计算一次观测和奖励如果耗时太高GPU 再好也等你不动。常见的做法是用 Python 加 NumPy 做一个轻量级仿真环境把信道生成和速率计算向量化不要用 Python 循环去逐用户、逐 PRB 计算。def generate_fading_channel(n_ues, n_prbs, seed42): rng np.random.default_rng(seed) path_loss 128.1 37.6 * rng.uniform(0.1, 0.5, size(n_ues, 1)) shadow rng.normal(0, 8, size(n_ues, n_prbs)) return 10 ** (-(path_loss shadow) / 10) def compute_rate(channel, power_vector, prb_assignment): snr channel * power_vector.reshape(-1, 1) snr snr / (1e-9 1.0) # 简化噪声功率单位线性 rate np.log2(1 snr) return rate * prb_assignment这个信道模型把路径损耗和阴影衰落都折算成线性增益compute_rate用香农公式近似估算每用户在每个 PRB 上的可达速率。prb_assignment如果是 0/1 掩码矩阵点乘之后只会保留被分配到的资源块。注意随机数生成要用default_rng并传入 seed这是可复现实验的第一步。如果你想要更贴近真实系统可以在evolve_channel里加入快衰落系数例如做一阶 AR 模型模拟时变信道但初始版本建议先跑静态信道把问题链路确认好再增加复杂度。3.3 最小训练回路DQN 主循环加经验回放环境搭好之后训练回路可以写得很短。下面是一段 DQN 主循环的骨架它完成四件事与环境交互采样、往经验回放缓冲区写数据、随机采样小批量更新 Q 网络、周期性同步目标网络。from collections import deque buffer deque(maxlen50000) q_net build_dqn(env) target_net build_dqn(env) target_net.load_state_dict(q_net.state_dict()) optimizer torch.optim.Adam(q_net.parameters(), lr3e-4) epsilon 1.0 for episode in range(2000): obs env.reset() total_reward 0.0 for step in range(env.max_steps): if np.random.random() epsilon: action random_action() else: action q_net.select_action(obs) next_obs, reward, done, _ env.step(action) buffer.append((obs, action, reward, next_obs, done)) obs next_obs total_reward reward if len(buffer) 256: batch random.sample(buffer, 256) loss update_q_net(batch, q_net, target_net, optimizer) if step % 200 0: target_net.load_state_dict(q_net.state_dict()) epsilon max(0.02, epsilon * 0.995)代码里的关键点在update_q_net它对每个样本计算target reward gamma * max_target(next_obs)再用当前 Q 网络的预测值和 target 做 MSE 损失。经验回放的deque(maxlen50000)限制了缓冲区上限避免旧经验过多污染新策略的学习目标网络每 200 步同步一次是为了减少自举带来的震荡。epsilon从 1.0 衰减到 0.02前期的随机探索让智能体有机会发现有效动作后期更多依赖学到的策略。这个主循环可以直接跑也适合替换成 PPO 的 rollout 逻辑——换算法时环境接口完全不用改。4. 训练参数怎么设六个必调参数与训练曲线判读算法代码写通之后调参才是真正花时间的地方。深度强化学习算法的超参数不像普通监督学习那样有成熟的自动搜索方案很多时候得靠经验和运气。下面六个参数是我在蜂窝网资源分配任务里最先调的也是影响训练结果最明显的变量。每次只改一个参数记录曲线再动下一个这是最合理的调参节奏。4.1 六个必调参数从学习率到目标网络更新间隔学习率是最敏感、最玄学的一个参数。DQN 和 PPO 都尽量从3e-4起步过大会导致损失震荡过小则收敛慢到让人怀疑代码写错了。折扣因子gamma在资源分配任务里要格外小心信道和业务都是缓变的gamma0.99代表智能体会考虑未来约 100 步的收益如果业务时延要求高gamma0.9可能更合适但代价是策略会变得短视。探索率衰减速度影响最终性能衰减太快会收敛到次优策略太慢会浪费大量训练时间。参数常见取值范围调整方向learning_rate3e-4 ~ 1e-3损失震荡则减半gamma0.9 ~ 0.99时延敏感场景调低epsilon_decay0.99 ~ 0.999收敛慢则调小buffer_size2万 ~ 10万环境随机性强则调大batch_size32 ~ 256显存允许则调大target_update_interval100 ~ 1000 步训练不稳则调小批大小和回放缓冲区大小是硬件约束最强的两个参数。缓冲区大能提供更独立的样本但也会让策略更新反映的是很久之前的状态分布新旧策略差异过大时训练不稳定批大小大能降低梯度方差但每步更新更慢。我在单小区场景从256起步多小区场景会降到128。这些经验值不是铁律但适合作为第一组尝试的组合。4.2 通过损失、奖励和动作熵判断训练状态训练曲线要学会分开看。损失下降不代表策略变好因为 Q 网络的损失是向着不断更新的 target 回归的target 本身也在变化。我更关注三个量每个 episode 的平均奖励、Q 值的量级、动作熵如果用 PPO。平均奖励上升说明策略效果在改善Q 值量级和实际奖励量级偏离过大说明奖励尺度过大或学习率异常动作熵在不收敛时往往先飙升再塌缩这是策略陷入局部最优的常见信号。遇到曲线锯齿非常剧烈时先别急着改网络结构。检查奖励函数是不是出现了极端值比如某用户速率为 0 导致对数项爆炸检查compute_rate是不是产生了 NaN 或无穷大。多数“莫名其妙不收敛”的问题最后都能在环境代码里找到根源而不是算法层。4.3 GPU 计算资源分配在这类任务里为什么不是第一瓶颈训练深度强化学习跑蜂窝网资源分配你会很快发现 GPU 利用率上不去。原因在于训练是串行交互的环境必须等待智能体给出动作智能体必须等待环境返回下一个状态GPU 在大部分时间里处于等待状态。所以这类任务的瓶颈不是 GPU 计算资源不够而是环境交互太慢。常见的加速手段有三种开多个环境进程并行采样提高 GPU 利用率把信道生成和速率计算向量化成矩阵运算避免 Python 循环预先离线生成一批信道轨迹训练时直接回放。这些都是工程上被验证过的做法比换一块显卡有效得多。5. 蜂窝网资源分配训练避坑五个亲眼见过的翻车现场这一章写的是训练过程中最常遇到的五个问题。每一条都是我亲眼在项目里见过的翻车现场现象、原因、解决方式都按实际排查顺序记录。排错时建议按顺序逐条对照能少走很多弯路。5.1 收敛很好但效果不如最大信噪比奖励信号指错了方向现象奖励曲线稳定上升Loss 曲线也收敛了但把学到的策略拿去和最大信噪比调度做对比系统吞吐反而更低。原因奖励函数把“模型认为的好”和“系统真正的好”搞混了。比如只将瞬时吞吐作为奖励智能体学会的是把所有资源押给信道最好的用户牺牲了所有边缘用户和速率反而因为缺乏用户分集增益而下降。解决改用对数速率作为奖励主项并在评估指标里同时记录系统吞吐和 Jain’s fairness index确保策略没有在原问题上跑偏。这是一个非常容易犯的错因为训练过程“看起来正常”恰恰最危险。5.2 损失值像心电图奖励尺度与回放数据在捣乱现象Q 网络损失在几百到几万之间剧烈跳动每 10 步一个尖峰平均奖励曲线也是上蹿下跳。原因最常见的是奖励尺度过大Q 值目标高达几千网络每次更新都在追赶一个剧烈变化的目标其次是回放缓冲区中混入了大量探索早期生成的糟糕样本它们在后期仍然被反复采样拖慢策略更新。解决先把奖励压缩到[-1, 1]左右量级观察 Loss 是否稳定再把缓冲区里早期低奖励样本的采样权重降低或者干脆缩小缓冲区容量。实测中 70% 的震荡问题出在奖励尺度而不是网络结构。5.3 换一个用户数性能立刻崩状态归一化没做好现象训练时用 8 个用户迁移到 12 个用户场景策略表现还不如随机调度。原因神经网络输入层的特征分布发生了偏移。8 用户时的归一化参数是在 8 用户的数据上统计的换到 12 用户后队列长度、信道增益的取值分布全变了网络的隐层输出也跟着失真。解决状态归一化不要用训练集的离线统计量而是使用逐时刻的在线归一化比如队列长度除以当前时隙的最大队列长度信道增益做按行的最大值归一化。这样用户数变化时输入特征的数值范围基本保持一致。5.4 动作空间枚举爆炸把联合动作拆成分层决策现象动作定义为“哪些用户占用哪些 PRB”的联合枚举用户数超过 10、PRB 数超过 10 后动作空间达到几十万维DQN 的 Q 网络输出层大到无法训练训练时间成倍增长。原因联合动作的排列组合是组合爆炸的DQN 这类基于价值的方法要求每个动作有一个输出头动作越多输出维度越大探索效率也越低。解决改成两层策略第一层用策略网络输出每个用户的优先级权值第二层用传统的贪心算法按权值把 PRB 逐个分配给用户。这样既保留了学习能力又把动作空间压缩到用户数规模。PPO 这类基于策略梯度的算法对连续动作空间更友好但分层决策的结构仍然值得保留。5.5 换了随机种子结果天差地别固定种子是工程纪律现象代码完全一样只改了随机种子训练之后性能从 Top 10% 掉到 Bottom 20%。原因深度强化学习对环境初始化、网络初始化和经验采样顺序都高度敏感。蜂窝网场景里信道生成的随机性尤其大一个极端信道布局可能让整轮训练报废。解决固定每一个可能影响随机性的入口——环境生成器的 seed、网络初始化的 seed、PyTorch 和 NumPy 的全局 seed、动作探索的 seed。训练评估时跑 5 到 10 个不同种子取均值不要拿单次结果当结论。随机种子结果是玄学但固定种子是工程纪律两者不矛盾。6. 进阶验证从单小区收敛到多小区分布式单小区训练稳定之后下一步大多是把方案扩展到多小区场景。注意不要直接拿单小区的策略网络去跑多小区因为小区间的干扰耦合会让状态分布完全不同。常见的路径是集中式训练、分布式执行训练时用一个中心化评论家查看所有小区的全局状态执行时每个小区只用自己的局部观测做决策。这个思路在 MADDPG 和 MAPPO 里都有成熟实现核心手段是让执行网络只接收局部观测评估网络把所有小区信息拼接起来。验证一个资源分配算法是否值得投入不能只看平均吞吐。我每次实验会同时记录三个指标小区平均吞吐、Jain’s fairness index、时延 P95/P99 尾部分位数。公平性不足时平均吞吐再高也不可信时延尾部则直接反映业务体验。这三个指标固定后在相同随机种子下对比 DRL 策略和最大信噪比调度、比例公平调度的差距比单看一条 reward 曲线可靠得多。如果 DRL 策略只在和速率上领先但公平性明显劣化说明奖励设计还需要回头调。我现在的习惯是先写奖励函数再写环境最后才写智能体先跑固定信道确认梯度通路再跑时变信道验证泛化能力每次改参数只动一项所有实验结果按 seed 存档。这套流程救过我很多次希望帮到你。本文还有配套的精品资源点击获取
返回列表