405. Lyft Motion Prediction for Autonomous Vehicles | lyft-motion-prediction-autonomous-vehicles
首先:这是一场精彩的比赛!这大概是我参加过的 Kaggle 比赛中数据最稳定的一次——感谢组织者。祝贺所有的获胜者,也祝贺每一位努力工作并完成比赛的人。
很高兴能与 @rytisva88 和 @sheriytm 合作——谢谢你们两位!
我相信我的队友们会单独发帖,所以我在这里只分享我自己工作流程中的一些观察。非常有兴趣听听大家是如何解决这个问题的,因为这个问题有很大的空间尝试不同的方法!
为了追求速度,我最终使用了两种较小的输入尺寸:128 + 5 通道,196 + 5 通道。
阅读其他人的评论和解决方案后,我发现一些我认为是成功关键的因素实际上并不是!我相信从不同团队中挑选出有效的想法结合起来,可能会产生非常有趣的成果。
在这场比赛中,成功似乎有一个主要关键:你能访问多少数据,以及你如何对其进行采样。
早期就很明显,在训练时对场景进行分组会带来显著的提升:在进入下一次迭代之前,从每个场景中选择一个智能体,分数会有所提高。
将这一想法贯彻到 train_full.zarr 中带来了下一个突破:在 train_full.zarr 的切片版本上进行训练产生了进一步的改进。
性能的下一个飞跃来自于对 train_full.zarr 的多个切片进行训练。(你可以修改 l5kit 代码来创建仅包含少量历史帧的轻量级切片。这可以大大节省内存/磁盘空间。)
我们讨论过为什么使用 train_full.zarr 的切片版本训练比随机访问索引能带来如此大的性能提升。从早期的实验来看,确保场景的多样性似乎很重要:就像我们在训练时可能强制类别平衡一样,强制场景多样性(或许更根本地,驾驶员多样性?)似乎很重要。
尽可能多地覆盖数据很重要,尽可能长时间地训练也很重要。train_full.zarr 的单个切片(约 82.5 万个样本)可以向模型展示 12 次,之后它才停止学习。显然,如果你能向模型展示不同的样本,效果会好得多!但这似乎是硬性限制。
保持模型尽可能小意味着它可以更快地迭代这些样本。我最终使用的模型输入是光栅尺寸 128 和 196,history_num_frames = 5,浓缩为五个输入通道:
sum(agent_history), agent_current, sum(ego_history), ego_current, sum(semantic_map)
我最初使用的是 Resnet18,后来在 @rytisva88 的建议下切换到了 Resnest50,它使 nll 提高了约 -1。(顺便说一句,@rytisva88 拥有我们组中表现最好的单一模型)。
对语义地图进行求和意味着红色和绿色交通信号被同等对待。令人惊讶的是,这似乎效果很好。可能是因为只有黄色提供了交通流中尚未包含的额外信息。
通过观察预测轨迹,很明显模型最终是在对加速度进行押注:通常,模式 0、1、2 代表由不同智能体速度产生的轨迹。
一旦明确了这是关键,就可以研究如何采样数据以平衡这些情况。
包含大量智能体的场景表明有交通拥堵。显然,僵死的交通流移动不多,会导致大量重复的输入。模型实施了一种采样方案,即对包含大量智能体的场景进行欠采样。采样比例为:min(1, 7/agent_count)。因此,包含 14 个智能体的场景在每次训练迭代中只选择其中 50% 的智能体,依此类推。
这最初是个棘手的问题:基于置信度值的模型平均不起作用。然而,当考虑到加速度的重要性时,集成的路径就讲得通了:按覆盖距离对模型模式进行排序,然后平均结果。实施这一方法后,所有模型都可以非常快速地集成,并产生了积极的结果。我们还尝试在这里加入曲率,但没有产生任何影响:距离才是关键。
最终的集成在验证集上优化了权重。加权方案包含了距离和置信度值。
我们团队解决方案的贡献代码可以在 这里 找到。