rl4j调用A3CDiscreteDense.train()抛出数组越界异常,DQN运行正常
问题描述
基于Deeplearning4j生态的RL4J强化学习库开发时,执行A3CDiscreteDense().train()启动离散动作空间A3C训练流程,固定触发如下运行时报错:
Exception in thread "Thread-7" java.lang.ArrayIndexOutOfBoundsException: -1 at java.util.ArrayList.elementData(Unknown Source) at java.util.ArrayList.get(Unknown Source) at org.deeplearning4j.rl4j.learning.async.a3c.discrete.AdvantageActorCriticUpdateAlgorithm.computeGradients(AdvantageActorCriticUpdateAlgorithm.java:63) at org.deeplearning4j.rl4j.learning.async.a3c.discrete.AdvantageActorCriticUpdateAlgorithm.computeGradients(AdvantageActorCriticUpdateAlgorithm.java:32) at org.deeplearning4j.rl4j.learning.async.AsyncThreadDiscrete.trainSubEpoch(AsyncThreadDiscrete.java:130) at org.deeplearning4j.rl4j.learning.async.AsyncThread.handleTraining(AsyncThread.java:192) at org.deeplearning4j.rl4j.learning.async.AsyncThread.run(AsyncThread.java:168)
同一份业务逻辑代码替换为DQN实现运行时,无任何异常表现。
报错根因定位
从堆栈信息可直接定位触发点:
- 异常核心触发位置为
AdvantageActorCriticUpdateAlgorithm类的第63行,是代码尝试对ArrayList执行get(-1)非法取值时,触发数组越界 - 该问题仅在A3C离散训练链路出现,与环境交互逻辑、基础模型搭建流程无关,属于A3C异步更新链路的专属触发问题
排查与修复方向
- 检查离散动作空间的返回值合法性:A3C的优势更新算法会逐帧提取经验序列中当前步执行的动作索引,如果环境返回的动作值没有严格落在
[0, 动作总数-1]的合法区间,甚至返回无效的-1占位值,就会在获取对应动作的策略概率、价值张量时触发越界。DQN链路的离散动作处理逻辑对这类越界值有前置容错,不会直接抛出数组越界异常 - 核对异步训练的单轮子epoch经验收集长度配置:如果A3C异步线程的单轮收集序列长度设置为0,会导致经验队列在计算时序差分优势值时,无法匹配序列末尾的终止状态标记,返回的动作索引位为-1,直接触发越界
- 校验网络输出层与动作空间的维度匹配度:A3C离散任务要求策略输出头的维度严格等于离散动作的总数,如果动作头输出维度和配置的动作总数不匹配,会在张量索引映射过程中出现越界取值
内容的提问来源于stack exchange,提问作者Akash garg
相关产品推荐
相关产品推荐

