当前位置: 首页 > news >正文

GoalFlow:四、轨迹评分筛选模块(Trajectory Scorer, M3)

GoalFlow 核心算法组件 6.4:轨迹评分筛选模块(Trajectory Scorer, M3)

概述

轨迹评分筛选模块(Trajectory Scorer, M3)是 GoalFlow 系统中负责从多条候选轨迹中选择最优轨迹的核心组件。该模块在推理阶段接收 M0(基础流匹配模块)生成的多条候选轨迹,结合 M1(目标点分解模块)提供的导航目标点,通过距离评分和进度评分的综合考量,筛选出最优轨迹作为最终输出。

核心目标

  • 从多条候选轨迹中筛选出最符合导航目标的轨迹
  • 平衡轨迹的导航准确性和前进进度
  • 提升轨迹预测的鲁棒性和安全性

二、模块架构与核心组件

2.1 模块位置与调用时机

轨迹评分筛选模块位于GoalFlowTrajModel的推理阶段,在 M0 生成多条候选轨迹之后执行:

# ========================== trajectory scorer ========================================ifself._config.use_nearestandnotself._config.fusion:distances=torch.norm(pred_trajs[:,:,8,:2]-navi,dim=-1)scores=distancesifself._config.ep_score_weight>0.0:distances_norm=minmax(distances)progress=torch.norm(pred_trajs[:,:,8,:2],dim=-1)progress_norm=minmax(progress)scores=(1.-self._config.ep_score_weight)*distances_norm-self._config.ep_score_weight*progress_norm min_index=torch.argmin(scores,dim=1)pred_trajs=pred_trajs[torch.arange(batch_size),min_index].unsqueeze(1)

文件位置:navsim/agents/goalflow/goalflow_model_traj.py:395

2.2 输入输出

输入类型说明
pred_trajs(B, anchor_size, num_poses, 3)M0 生成的多条候选轨迹
navi(B, 1, 1, 2)M1 提供的导航目标点
use_nearestbool是否启用轨迹评分筛选
ep_score_weightfloat进度评分权重
输出类型说明
pred_trajs(B, 1, num_poses, 3)筛选后的最优轨迹

2.3 核心数据结构

# 候选轨迹张量结构pred_trajs:torch.Tensor# Shape: (batch_size, anchor_size, num_poses, 3)# - batch_size: 批次大小# - anchor_size: 每个样本生成的轨迹数量(默认128)# - num_poses: 轨迹点数(默认12,包含起始点)# - 3: x, y, heading# 导航目标点navi:torch.Tensor# Shape: (batch_size, 1, 1, 2)# - 2: x, y 坐标

三、轨迹评分算法

3.1 基础距离评分

基础评分策略是计算每条候选轨迹的终点与导航目标点之间的欧几里得距离:

# 提取轨迹第8个时间步的终点位置(对应5.5s时间跨度中的关键预测点)trajectory_endpoints=pred_trajs[:,:,8,:2]# (B, anchor_size, 2)# 计算与导航目标点的距离distances=torch.norm(trajectory_endpoints-navi,dim=-1)# (B, anchor_size)

原理说明

  • 选择第8个时间步(约4.0s处)作为评估点,而非最后一个时间步
  • 这是因为:
    1. 中期预测更能反映轨迹的整体走向
    2. 避免末端噪声对评分的影响
    3. 与 M1 选择导航目标点的时间尺度一致

3.2 综合评分(距离 + 进度)

ep_score_weight > 0时,系统采用综合评分策略,同时考虑距离和进度:

defminmax(t_tensor):"""归一化函数:将张量缩放到 [0, 1] 范围"""batch_min=torch.min(t_tensor,dim=-1).values.unsqueeze(-1)batch_max=torch.max(t_tensor,dim=-1).values.unsqueeze(-1)return(t_tensor-batch_min)/(batch_max-batch_min)# 距离评分(归一化)distances_norm=minmax(distances)# (B, anchor_size)# 进度评分:轨迹终点到原点的距离(归一化)progress=torch.norm(pred_trajs[:,:,8,:2],dim=-1)# (B, anchor_size)progress_norm=minmax(progress)# (B, anchor_size)# 综合评分公式scores=(1.-ep_score_weight)*distances_norm-ep_score_weight*progress_norm

评分公式

score=(1−w)×distance_norm−w×progress_norm\text{score} = (1 - w) \times \text{distance\_norm} - w \times \text{progress\_norm}score=(1w)×distance_normw×progress_norm

其中:

  • www=ep_score_weight(进度权重,范围 [0, 1])
  • distance_norm\text{distance\_norm}distance_norm= 轨迹终点到导航目标点的归一化距离(越小越好)
  • progress_norm\text{progress\_norm}progress_norm= 轨迹终点到原点的归一化距离(越大越好)

设计意图

  • 通过减去进度评分,鼓励选择前进距离更远的轨迹
  • 距离评分确保轨迹朝向导航目标点
  • 进度评分确保车辆持续前进,避免原地徘徊

3.3 最优轨迹选择

根据评分结果选择最优轨迹:

# 选择评分最小的轨迹(距离最小或综合评分最优)min_index=torch.argmin(scores,dim=1)# (B,)# 从候选轨迹中提取最优轨迹pred_trajs=pred_trajs[torch.arange(batch_size),min_index].unsqueeze(1)# Shape: (B, 1, num_poses, 3)

四、融合模式下的轨迹评分

4.1 双轨迹生成机制

fusion=True模式下,系统生成两组轨迹:

  1. 条件轨迹(Conditional Trajectory):使用导航目标点作为条件
  2. 无条件轨迹(Non-Conditional Trajectory):不使用导航目标点(navi_dropout=True)
# 生成条件轨迹fort_curr,t_previnzip(t_shifted[:-1],t_shifted[1:]):net_output_cond=self.denoise(trajs,t_curr,global_feature)trajs=trajs.detach().clone()+net_output_cond*(step/self._config.infer_steps)diffusion_output_cond=self.denormalize_xy_rotation(trajs,N=gt_trajs.shape[-2],times=10)# 生成无条件轨迹fort_curr,t_previnzip(t_shifted[:-1],t_shifted[1:]):net_output_nonavi=self.denoise(trajs,t_curr,global_feature,navi_dropout=True)trajs=trajs.detach().clone()+net_output_nonavi*(step/self._config.infer_steps)diffusion_output_nonavi=self.denormalize_xy_rotation(trajs,N=gt_trajs.shape[-2],times=10)

文件位置:navsim/agents/goalflow/goalflow_model_traj.py:306

4.2 条件轨迹的评分筛选

在融合模式下,条件轨迹也需要进行评分筛选:

ifself._config.use_nearest:# 计算条件轨迹终点与导航目标点的距离distances=torch.norm(diffusion_output_cond[:,:,8,:2]-navi,dim=-1)scores=distancesifself._config.ep_score_weight>0.0:distances_norm=minmax(distances)progress=torch.norm(diffusion_output_cond[:,:,8,:2],dim=-1)progress_norm=minmax(progress)scores=(1.-self._config.ep_score_weight)*distances_norm-self._config.ep_score_weight*progress_norm# 选择最优条件轨迹min_index=torch.argmin(scores,dim=1)pred_trajs_cond=diffusion_output_cond[torch.arange(batch_size),min_index].unsqueeze(1)else:# 直接取平均pred_trajs_cond=torch.mean(diffusion_output_cond,dim=1,keepdim=True)

文件位置:navsim/agents/goalflow/goalflow_model_traj.py:318

4.3 双轨迹融合策略

4.3.1 阈值融合

cond_threshold > 0时,根据无条件轨迹与导航目标点的偏离程度决定是否使用条件轨迹:

ifself._config.cond_threshold>0.0:# 计算无条件轨迹终点与导航目标点的距离distance=torch.norm(pred_trajs_nonavi[:,:,8,:2]-navi,dim=-1).squeeze()# 计算无条件轨迹的前进进度progress=torch.norm(pred_trajs_nonavi[:,:,8,:2],dim=-1).squeeze()# 计算偏离比率deviation_ratio=distance/progress# 构建条件掩码:偏离过大时使用无条件轨迹cond_mask=(deviation_ratio>self._config.cond_threshold)cond_mask=cond_mask.view(-1,1,1,1)# 根据掩码选择轨迹pred_trajs=torch.where(cond_mask,pred_trajs_nonavi,pred_trajs_cond)

设计意图

  • 当无条件轨迹严重偏离导航目标时,切换到条件轨迹
  • 否则使用无条件轨迹,保持轨迹的多样性和鲁棒性
4.3.2 加权融合

cond_threshold <= 0时,采用加权平均融合:

pred_trajs=self._config.beta*pred_trajs_cond+(1.0-self._config.beta)*pred_trajs_nonavi

其中beta是条件轨迹的权重系数,范围 [0, 1]。


五、导航目标点的 Top-k 选择

5.1 目标点评分融合

在 M0 训练阶段,如果使用has_student_navi=True,系统会加载 M1 生成的评分文件,并融合 IM 分数和 DAC 分数:

# 加载 IM 分数和 DAC 分数im_scores=torch.from_numpy(np.load(f'{self._config.score_path}/im/{token[i]}.npy'))dac_scores=torch.from_numpy(np.load(f'{self._config.score_path}/dac/{token[i]}.npy'))# 计算最终评分ifself._config.ep_point_weight>0.0:# 加入距离惩罚goal_distance=torch.norm(cluster_points_tensor[...,:2],dim=-1)goal_distance_norm=minmax(goal_distance)final_scores=(0.1*torch.log(F.softmax(im_scores.squeeze(),dim=-1)+1e-7)+self._config.theta*torch.log(torch.sigmoid(dac_scores.squeeze())+1e-7)+self._config.ep_point_weight*goal_distance_norm)else:final_scores=(0.1*torch.log(F.softmax(im_scores.squeeze(),dim=-1)+1e-7)+self._config.theta*torch.log(torch.sigmoid(dac_scores.squeeze())+1e-7))

文件位置:navsim/agents/goalflow/goalflow_model_traj.py:198

5.2 Top-k 目标点选择

# 选择 Top-k 评分最高的目标点topk_indices=torch.topk(final_scores,self._config.topk).indices topk_indices=topk_indices.unsqueeze(-1).expand(-1,-1,cluster_points_tensor.shape[-1])# 提取对应的目标点坐标navi=torch.gather(cluster_points_tensor,dim=1,index=topk_indices).mean(1)[...,:2].unsqueeze(1)

说明

  • topk参数决定选择多少个导航目标点
  • 多个目标点取平均作为最终导航目标
  • 这增加了导航目标的鲁棒性

六、核心算法举例说明

6.1 场景描述

假设车辆在一条直道上行驶,导航目标点为正前方 50m 处。M0 生成了 128 条候选轨迹,其中大部分朝向目标点,但存在一些异常轨迹:

  • 轨迹 A:准确朝向目标点,终点距离目标点 2m
  • 轨迹 B:略微偏右,终点距离目标点 8m
  • 轨迹 C:严重偏离,终点距离目标点 25m
  • 轨迹 D:朝向目标点但前进距离较短,终点距离目标点 3m

6.2 基础距离评分

# 假设导航目标点 navi = (50, 0)# 各轨迹第8步的终点位置:# A: (48, 0), B: (50, 8), C: (40, 15), D: (30, 0)# 计算距离distances=torch.norm(pred_trajs[:,:,8,:2]-navi,dim=-1)# distances = [2.0, 8.0, 25.0, 20.0]# 选择距离最小的轨迹min_index=torch.argmin(distances)# index = 0 (轨迹 A)

评分结果

轨迹终点位置距离目标点评分排名
A(48, 0)2.0m2.01
B(50, 8)8.0m8.02
D(30, 0)20.0m20.03
C(40, 15)25.0m25.04

选择结果:轨迹 A

6.3 综合评分(距离 + 进度)

假设ep_score_weight = 0.3

# 计算进度(到原点的距离)progress=torch.norm(pred_trajs[:,:,8,:2],dim=-1)# progress = [48.0, 50.79, 42.72, 30.0]# 归一化distances_norm=minmax(distances)# [0.0, 0.26, 1.0, 0.78]progress_norm=minmax(progress)# [0.65, 1.0, 0.48, 0.0]# 综合评分scores=(1-0.3)*distances_norm-0.3*progress_norm# scores = [0.0*0.7 - 0.65*0.3 = -0.195]# [0.26*0.7 - 1.0*0.3 = -0.118]# [1.0*0.7 - 0.48*0.3 = 0.556]# [0.78*0.7 - 0.0*0.3 = 0.546]

评分结果

轨迹距离评分进度评分综合评分排名
B0.261.0-0.1181
A0.00.65-0.1952
D0.780.00.5463
C1.00.480.5564

选择结果:轨迹 B(虽然距离稍远,但前进进度最大)

6.4 融合模式示例

假设fusion=True,beta=0.6,cond_threshold=0.5

# 条件轨迹终点: (48, 0), 无条件轨迹终点: (45, 2)# 计算偏离比率distance=torch.norm(pred_trajs_nonavi[:,:,8,:2]-navi,dim=-1)# = 5.39progress=torch.norm(pred_trajs_nonavi[:,:,8,:2],dim=-1)# = 45.09deviation_ratio=distance/progress# = 0.12# 判断是否超过阈值ifdeviation_ratio>0.5:# 使用无条件轨迹pred_trajs=pred_trajs_nonavielse:# 使用加权融合pred_trajs=0.6*pred_trajs_cond+0.4*pred_trajs_nonavi# pred_trajs[8, :2] = 0.6*(48,0) + 0.4*(45,2) = (46.8, 0.8)

融合结果:由于偏离比率(0.12)小于阈值(0.5),采用加权融合,最终轨迹终点为 (46.8, 0.8)。


七、与其他模块的协作

7.1 模块协作关系图

┌─────────────────────────────────────────────────────────────────────────────┐ │ GoalFlow 模块协作流程 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ M1 (目标点分解) ───────────────────────────────────────────────────────► │ │ │ │ │ ▼ │ │ 导航目标点 (navi) ─────────────────────────────────────────────────────► │ │ │ │ │ │ M0 (基础流匹配) │ │ │ │ │ │ │ ▼ │ │ │ 多条候选轨迹 (anchor_size=128) │ │ │ │ │ │ └─────────────────────────────────────────┼────────────────────────► │ │ ▼ │ │ M3 (轨迹评分筛选) │ │ │ │ │ ▼ │ │ 最优轨迹 (1条) │ │ │ │ │ ▼ │ │ 输出到控制器 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘

7.2 与 M0 的协作

  • M0 生成anchor_size条候选轨迹(默认128条)
  • M3 从这些候选轨迹中筛选出最优轨迹
  • 筛选结果反馈给 M0 的训练过程(通过导航丢弃增强)

7.3 与 M1 的协作

  • M1 提供导航目标点作为评分基准
  • M1 的评分文件(IM分数、DAC分数)用于训练阶段的目标点选择
  • M3 的评分结果可以间接验证 M1 的导航目标点质量

八、关键配置参数

8.1 轨迹评分相关参数

@dataclassclassGoalFlowConfig:# 轨迹评分参数use_nearest:bool=False# 是否使用最近轨迹选择ep_score_weight:float=0.0# 进度评分权重(0~1)ep_point_weight:float=0.0# 导航点距离权重# 轨迹生成参数anchor_size:int=128# 每个样本生成的轨迹数量infer_steps:int=100# 扩散采样步数# 融合参数fusion:bool=False# 是否启用双轨迹融合beta:float=0.0# 条件轨迹权重cond_threshold:float=0.0# 融合阈值# 导航目标点参数topk:int=1# Top-k 目标点选择theta:float=3.0# DAC 分数权重# 归一化参数train_scale:float=0.1# 训练时噪声尺度test_scale:float=0.1# 测试时噪声尺度

文件位置:navsim/agents/goalflow/goalflow_config.py

8.2 参数说明

参数类型默认值说明
use_nearestboolFalse是否启用轨迹评分筛选,设为 True 时从候选轨迹中选择最优
ep_score_weightfloat0.0进度评分权重,越大越倾向于选择前进距离远的轨迹
ep_point_weightfloat0.0导航点距离权重,用于目标点选择时的距离惩罚
anchor_sizeint128扩散采样生成的轨迹数量,越大多样性越好但计算开销越大
fusionboolFalse是否启用条件/无条件轨迹融合
betafloat0.0融合时条件轨迹的权重
cond_thresholdfloat0.0融合阈值,大于0时启用阈值判断融合策略
topkint1导航目标点的 Top-k 选择数量
thetafloat3.0DAC 分数在目标点选择时的权重

九、训练阶段的导航丢弃增强

9.1 增强策略

在 M0 训练阶段,为了增强模型的鲁棒性,系统采用导航丢弃(navi_dropout)策略:

ifself._config.has_navi:flag=random.randint(1,3)ifflag==1:# 正常训练pred=self.denoise(noisy_traj_points,timesteps,global_feature).reshape(batch_size,-1,30)elifflag==2:# 强制丢弃(场景特征置零)pred=self.denoise(noisy_traj_points,timesteps,global_feature,force_dropout=True).reshape(batch_size,-1,30)elifflag==3:# 导航丢弃(导航特征置零)pred=self.denoise(noisy_traj_points,timesteps,global_feature,navi_dropout=True).reshape(batch_size,-1,30)

文件位置:navsim/agents/goalflow/goalflow_model_traj.py:273

9.2 丢弃实现

defdenoise(self,ego_trajectory,sigma,state_features,force_dropout=False,navi_dropout=False):state_features,state_type_embedding=state_features# 导航丢弃:将导航特征置零ifnavi_dropout:state_features[:,-1,:]*=0# 强制丢弃:将所有场景特征置零ifforce_dropout:all_features=all_features*0

文件位置:navsim/agents/goalflow/goalflow_model_traj.py:444

增强效果

  • 正常训练:模型学习在有导航目标时生成准确轨迹
  • 强制丢弃:模型学习在没有场景信息时的鲁棒性
  • 导航丢弃:模型学习在没有导航目标时的自主决策能力

十、数据流程总结

10.1 推理阶段流程

传感器输入(相机 + LiDAR + 状态) │ ▼ M0 扩散采样生成多条候选轨迹 (B, anchor_size, num_poses, 3) │ ▼ 加载 M1 评分文件(IM分数、DAC分数) │ ▼ 选择导航目标点 (navi) │ ▼ ┌─────────────────────────────────────┐ │ M3 轨迹评分筛选 │ │ │ │ 1. 计算距离评分: │ │ distances = norm(endpoint - navi)│ │ │ │ 2. 计算进度评分(可选): │ │ progress = norm(endpoint) │ │ │ │ 3. 综合评分: │ │ scores = (1-w)*dist_norm - w*prog_norm│ │ │ │ 4. 选择最优轨迹: │ │ min_index = argmin(scores) │ │ pred_trajs = pred_trajs[min_index]│ └─────────────────────────────────────┘ │ ▼ 输出最优轨迹

10.2 融合模式流程

M0 生成条件轨迹 (pred_trajs_cond) │ ▼ M3 评分筛选(条件轨迹) │ ▼ M0 生成无条件轨迹 (pred_trajs_nonavi) │ ▼ 计算偏离比率 (distance/progress) │ ├── 偏离 > 阈值 → 使用无条件轨迹 │ └── 偏离 ≤ 阈值 → 加权融合 pred_trajs = beta * pred_trajs_cond + (1-beta) * pred_trajs_nonavi │ ▼ 输出融合后的最优轨迹

十一、技术特点

11.1 多轨迹候选策略

通过扩散模型生成多条候选轨迹(anchor_size=128),增加了轨迹预测的多样性和鲁棒性,避免单一轨迹可能的错误。

11.2 综合评分机制

同时考虑距离准确性和前进进度,平衡了导航精度和行驶效率,避免车辆过度追求目标点而忽视前进。

11.3 双轨迹融合

通过条件/无条件轨迹的融合,结合了导航引导的精确性和自主决策的鲁棒性,提升了复杂场景下的适应性。

11.4 导航丢弃增强

在训练阶段随机丢弃导航特征,增强了模型在导航信号不可靠时的自主决策能力。

11.5 可配置的评分策略

通过ep_score_weightfusionbeta等参数,可以灵活调整评分策略,适应不同场景需求。


十二、核心代码清单

文件路径核心功能
navsim/agents/goalflow/goalflow_model_traj.pyGoalFlowTrajModel,轨迹评分筛选的核心实现
navsim/agents/goalflow/goalflow_config.pyGoalFlowConfig,配置参数定义
navsim/agents/goalflow/goalflow_model_navi.pyGoalFlowNaviModel,生成 IM/DAC 评分供 M3 使用
navsim/planning/script/config/common/agent/goalflow_agent_traj.yaml轨迹模型的配置文件
http://www.jsqmd.com/news/1098947/

相关文章:

  • ps怎么调整图片大小?ps调整图片大小快捷键
  • 虚拟摇杆vJoy:Windows游戏控制器模拟的技术深度解析
  • 查新报告分为哪几种?科技查新、查收查引与专利查新区别
  • 基于 VC++ 与机器人 SDK 的工业多轴示教器软件设计与实现
  • 驾驶行为识别 打电话识别数据集 驾驶注意力监控 驾驶分心识别数据集 危险驾驶行为检测 抽烟打电话 睡觉 吃东西识别图像数据集第10149期
  • Metasploit渗透测试实战:从漏洞利用到后渗透操作详解
  • 车的使用年限,从来不是出厂定的!
  • OpenClaw排坑实录:启动失败、技能失效、模型报错,30个高频问题一次讲透
  • 解决方案|腾讯安全天御金融反电诈产品解决方案
  • 【LeetCode Hot100】189.轮转数组-三种解法以及效果评估
  • 搞定99%安装问题!OpenClaw 完整部署与故障修复
  • G-Helper终极指南:重新定义华硕笔记本硬件控制的轻量级革命
  • 模块 包 循环导入 系统
  • 3PEAK思瑞浦 TPA133A2-VS1R-S MSOP8 电流信号检测放大器
  • AI4C编译调优的终极技巧:提升程序性能30%的秘密
  • NCM音乐格式转换终极指南:5分钟解锁你的音乐收藏
  • Mineradio开源音乐播放器下载安装介绍(附下载链接)
  • 为什么好人没好报?你可能误解了“诚信”
  • 【会议征稿通知 | 西藏大学主办 | JPCS出版 | EI 、Scopus稳定检索】2026年水电系统与能源工程学术会议 (HSEE 2026)
  • 智慧矿场施工状态监测 推土机识别 装载机数据集 挖掘机等工程机械数据集第10096期
  • 实测有效|OpenClaw 闪退卡顿、网关异常根治教程
  • lac_agent自愈链路上篇——crontab守护的那些坑与健康检查实战
  • 计算机毕业设计之基于实训室管理平台的设计与实现
  • 逻辑回归(Logistic Regression)培训课件
  • .NET 8加持:C#上位机调用国产PLC运动控制指令实战
  • 医疗NLP落地实录:从病历结构化到药物发现,三大场景技术选型与合规避坑指南
  • YOLOv8一站式实战:图像分类、目标检测与实例分割全解析
  • 前端入门必学:用CSS实现三角形的常用三种方式
  • Airbnb 亿级流量的限流架构
  • 海上船舶识别数据集 渔船监测 货船识别 游艇数据集 油轮识别图像数据集 船舶类分类和测数据集 数据集第10163期 数字化智能化识别数据集