作者: YumeNeko (Grandmaster)
发布时间: 2025-03-25
竞赛排名: 第 4 名
第四名解决方案 - 模仿学习方法
首先,感谢参与本次竞赛的每一个人。
这是我第一次参加模拟竞赛,看着我的智能体随着时间的推移变得更强,令人无比兴奋。
源代码地址:https://github.com/KASSII/Kaggle_LuxAI-s3
概述
- 我的解决方案基于模仿学习(IL),并结合以下两个 IL 模型的输出来确定每个单位的行为:
- 动作模型(Action Model):预测每个单位将执行哪种移动(包括中心在内的 5 个方向)/ 吸取(Sap)动作。
- 吸取目标模型(Sap Target Model):为每个选择了吸取动作的单位预测吸取目标。
- 对于每个 IL 模型的输入,我使用了可以直接从环境中观察到的信息(如单位位置和能量等),以及通过探索更新地图数据获得的信息(如点位节点等)。
特征提取
- 从每一步获得的观测值中提取 24x24 的地图特征和标量全局特征。
- 对于具有对称性的地图特征,我利用这一属性来获取未观察坐标的信息(标记为“考虑对称性”的特征)。
- 某些特征无法直接观察,因此通过探索进行估算(标记为“估算特征”)。
- 估算逻辑很简单,但难以用文字简洁描述。源代码即将公开,请参考实现细节。
地图特征
| 特征名称 |
估算特征 |
考虑对称性 |
备注 |
| self_unit_pos |
|
|
|
| opp_unit_pos |
|
|
|
| self_energy |
|
|
|
| opp_energy |
|
|
|
| self_enable_move |
|
|
每个己方单位是否有能量执行移动动作(1 表示可能,0 表示不可能) |
| opp_enable_move |
|
|
每个敌方单位是否有能量执行移动动作(1 表示可能,0 表示不可能) |
| self_enable_sap |
|
|
每个己方单位是否有能量执行吸取动作(1 表示可能,0 表示不可能) |
| opp_enable_sap |
|
|
每个敌方单位是否有能量执行吸取动作(1 表示可能,0 表示不可能) |
| tile_type |
✓ |
✓ |
通过估算 nebula_tile_drift_speed,我确定了发生 shifts 的步数,并整合了所有已探索的地块信息。 |
| visible_mask |
|
|
当前步骤中单位可见的地块(1 表示可见,0 表示不可见) |
| map_energy |
|
✓ |
|
| relic_nodes |
|
✓ |
|
| point_prob_map |
✓ |
✓ |
代表估算点位节点位置的概率图,通过探索推断。 |
| pre_self_unit_pos |
|
|
上一步观察到的己方单位位置 |
| pre_opp_unit_pos |
|
|
上一步观察到的敌方单位位置 |
全局特征
| 特征名称 |
估算特征 |
备注 |
| self_reward |
|
当前步骤获得的己方分数 |
| opp_reward |
|
当前步骤获得的敌方分数 |
| match_steps |
|
|
| match_round |
|
|
| self_team_point |
|
当前回合累计获得的己方分数 |
| opp_team_point |
|
当前回合累计获得的敌方分数 |
| self_team_win |
|
己方获胜场数 |
| opp_team_win |
|
敌方获胜场数 |
| unit_move_cost |
|
|
| unit_sap_cost |
|
|
| unit_sap_range |
|
|
| unit_sap_dropoff_factor |
✓ |
从相邻吸取的敌方单位能量减少量估算。此特征仅在估算后使用(详见模型切换部分)。 |
模型切换
unit_sap_dropoff_factor 是性能提升的关键因素。然而,由于它是一个隐藏参数,直到实际执行吸取并观察到敌方单位的能量减少之前,其值仍然未知,因此无法事先使用。
为了解决这个问题,我训练了两个版本的动作模型和吸取目标模型:
- 一个在全局特征中不包含 unit_sap_dropoff_factor
- 一个包含 unit_sap_dropoff_factor
最初使用不包含 unit_sap_dropoff_factor 的模型。一旦估算出该值,我就切换到包含它的模型。这种模型切换方法使得能够在游戏的每个阶段自适应地选择最佳模型。
模仿学习
数据
- 我只使用了 'Frog Parade' 团队的回放进行模仿学习,基于早期实验专注于获胜剧集。
- 由于匹配系统的临时 bug,我通过选择排行榜分数高于特定阈值的对手来过滤剧集。
- 对于动作模型,我使用了过滤后剧集的所有步骤数据,而对于吸取目标模型,我仅提取并使用了单位选择吸取动作的步骤。
网络架构
- 我采用了简单的 UNet 架构,参考了 第一季的第 6 名解决方案。
- 地图特征用作 U-Net 的输入,而全局特征被广播并连接到 U-Net 的瓶颈部分。
各模型详情
1. 动作模型
输入 - 输出
- 输入是上述特征提取部分描述的 15 维地图特征和 12 维全局特征。
- 输出是 (6, 24, 24) 的地图,表示每个坐标处的单位应采取的动作(中心、上、右、下、左、吸取)的概率。
训练
损失函数
- 由于此游戏允许单位重叠,可以视为 6 类多标签分类任务,所以我使用了 BCEWithLogitsLoss。
- 在损失计算期间,我应用了掩码处理,以确保只有存在单位的坐标对应的损失有效。
数据增强
- 以相等概率应用旋转(0°、90°、180°、270°)。
- 垂直翻转
微调
- 首先,我使用 Frog Parade 各种提交 ID 的多个剧集数据集训练基础模型(收集于 2 月中旬至最终周末前,共 19787 集)。
- 接下来,使用最终日期前 Frog Parade 最佳排行榜提交 ID 的剧集(1046 集)对基础模型的权重进行微调。
推理
TTA (测试时增强)
- 我应用了 4 次旋转(0°、90°、180°、270°)和垂直翻转(开/关)的 TTA,平均 8 个输出。
低概率动作阈值处理
- 如果仅根据模型输出的概率选择动作,仍存在选择低概率动作的风险。
- 因此,我修改了选择过程,仅考虑累积概率超过阈值(本例中实验设置为 0.7)的动作。
同一坐标存在多个单位时的概率调整
- 在这个作为多标签任务训练的模型中,当多个单位重叠在同一坐标时,概率图为每个单位的动作输出相等的概率。结果是,即使在单位理想情况下应采取不同动作的情况下,它们也可能概率性地选择相同的动作。
- 我通过采用以下选择方法解决了这个问题:
- 第一个单位通常根据原始概率分布选择动作。
- 所选动作的概率减少 1/(同一坐标的单位数量),并归一化剩余概率。
- 下一个单位根据调整后的概率分布选择动作,降低选择与前一个单位相同动作的可能性。
2. 吸取目标模型
输入 - 输出
全局特征与动作模型中使用的相同(12 维)。
对于地图特征,我排除了过去步骤信息(pre_self_unit_pos, pre_opp_unit_pos),而是添加了 target_unit_sap_area 和 other_unit_sap_area。
- 排除过去步骤信息是因为本地实验表明,移除它会导致更高的胜率。

输出是 (1, 24, 24) 概率分布,其中每个坐标代表目标单位吸取目标的潜在优势。
训练
损失函数
- 由于这可以视为 N 类分类任务(其中 N = 24*24 = 576),我使用了交叉熵损失。
数据增强
微调
推理
- TTA
- 低概率动作阈值处理
- 与动作模型相同。
- 经过一些实验,吸取目标模型的阈值设置为 0.6。
无效尝试
其他数据选择方法
- 我尝试了即使输掉游戏也使用获胜场比赛的数据、混合另一个团队的数据以及其他变体,但没有显示出明显的改进。
长期使用时间序列信息
- 我尝试 Incorporate LSTM 和 Conv3D 以利用长期时间信息,但性能显著下降。
- 虽然利用长期过去信息失败了,但在动作模型中堆叠上一帧的单位位置信息提高了性能,所以我采用了这种方法。
转换为强化学习
- 由于 IL 被证明效果相当好,我尝试使用 IL 模型作为 RL 的预训练权重。然而,RL 方法没有成功。
- 我尝试了各种参数,但结果要么是 IL 策略完全崩溃,要么是没有比默认行为有所改进。
- 经过 2-3 周的试验和错误而没有成功后,我得出结论,以我的资源和实现,几乎不可能训练足够的步数。因此,我最终仅专注于 IL 进行开发。