(10-3-04)智能行为决策算法:基于自动驾驶大模型的车辆轨迹预测系统(4)推理

10.3.5  推理

经过前面的这些编码工作,我们现在可以使用这个基线模型进行车辆轨迹的预测工作。

(1)下面代码用于配置测试集的数据加载器和数据集。首先加载测试数据集的配置信息,并构建相应的Rasterizer。然后,通过ChunkedDataset加载测试数据,同时使用预定义的掩码(mask)对部分车辆进行过滤,最终创建AgentDataset对象。通过DataLoader设置测试数据加载器,以便后续进行推理测试,并输出测试数据集的信息。

test_cfg = cfg["test_data_loader"]
 
# Rasterizer
rasterizer = build_rasterizer(cfg, dm)
 
# Test dataset/dataloader
test_zarr = ChunkedDataset(dm.require(test_cfg["key"])).open()
test_mask = np.load(f"{PATH_TO_DATA}/scenes/mask.npz")["arr_0"]
test_dataset = AgentDataset(cfg, test_zarr, rasterizer, agents_mask=test_mask)
test_dataloader = DataLoader(test_dataset,
                             shuffle=test_cfg["shuffle"],
                             batch_size=test_cfg["batch_size"],
                             num_workers=test_cfg["num_workers"])
 
print(test_dataset)

执行后会输出:

+------------+------------+------------+-----------------+----------------------+----------------------+----------------------+---------------------+
| Num Scenes | Num Frames | Num Agents | Total Time (hr) | Avg Frames per Scene | Avg Agents per Frame | Avg Scene Time (sec) | Avg Frame frequency |
+------------+------------+------------+-----------------+----------------------+----------------------+----------------------+---------------------+
|   11314    |  1131400   |  88594921  |      31.43      |        100.00        |        78.31         |        10.00         |        10.00        |
+------------+------------+------------+-----------------+----------------------+----------------------+----------------------+---------------------+

(2)定义运行预测的函数run_prediction,接收一个训练好的模型(predictor)和测试数据加载器(data_loader)。在预测过程中,模型对测试数据进行前向传播,得到目标坐标和置信度。如果配置中启用了图像坐标(image_coords),则进行相应的坐标转换。预测结果被存储在各自的列表中,并最终以NumPy数组的形式返回时间戳、轨迹ID、坐标和置信度。函数使用tqdm库显示预测进度。

def run_prediction(predictor, data_loader):
    predictor.eval()
 
    pred_coords_list = []
    confidences_list = []
    timestamps_list = []
    track_id_list = []
 
    with torch.no_grad():
        dataiter = tqdm(data_loader)
        for data in dataiter:
            image = data["image"].to(device)
            inputs = data["image"].to(device)
            target_availabilities = data["target_availabilities"].to(device)
            targets = data["target_positions"].to(device)
            matrix = data["world_to_image"].to(device)
            centroid = data["centroid"].to(device)[:,None,:].to(torch.float)
            
            pred, confidences = predictor(image)
            
            if cfg['test_params']['image_coords']:
                matrix_inv = torch.inverse(matrix)
                pred = pred + bias[:,None,:,:]
                pred = torch.cat([pred,torch.ones((bs,3,tl,1)).to(device)], dim=3)
                pred = torch.stack([torch.matmul(matrix_inv.to(torch.float), pred[:,i].transpose(1,2)) 
                                    for i in range(3)], dim=1)
                pred = pred.transpose(2,3)[:,:,:,:2]
                pred = pred - centroid[:,None,:,:]
 
            pred_coords_list.append(pred.cpu().numpy().copy())
            confidences_list.append(confidences.cpu().numpy().copy())
            timestamps_list.append(data["timestamp"].numpy().copy())
            track_id_list.append(data["track_id"].numpy().copy())
            
    timestamps = np.concatenate(timestamps_list)
    track_ids = np.concatenate(track_id_list)
    coords = np.concatenate(pred_coords_list)
    confs = np.concatenate(confidences_list)
    return timestamps, track_ids, coords, confs

(3)下面的代码片段用于根据LOAD_MODEL标志选择是否加载预训练模型。如果LOAD_MODEL为True,它会创建一个新的LyftModel实例,加载之前保存的模型权重,并将模型移动到可用的计算设备(GPU或CPU)。用户需要设置saved_model_path变量,指定保存的模型路径。

LOAD_MODEL = False
 
if LOAD_MODEL:
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    predictor = LyftModel(cfg)
    saved_model_path = ""
    predictor.load_state_dict(torch.load(saved_model_path))
    predictor.to(device)

(4)根据INFER标志选择是否执行推理。如果INFER为True,它调用run_prediction函数获取测试集上的模型预测结果,然后使用write_pred_csv将时间戳、轨迹ID、坐标和置信度保存为CSV文件(submission.csv)。

from l5kit.evaluation import write_pred_csv
 
INFER = False
 
if INFER:
    timestamps, track_ids, coords, confs = run_prediction(predictor, test_dataloader)
    write_pred_csv('submission.csv',timestamps=timestamps,
    track_ids=track_ids, coords=coords, confs=confs)

6. 训练参数探索

(1)首先看看在配置文件中哪些参数与训练相关,具体实现代码如下所示。

train_dataset[0].keys()

执行后会输出:

dict_keys(['image', 'target_positions', 'target_yaws', 'target_availabilities', 'history_positions', 'history_yaws', 'history_availabilities', 'world_to_image', 'track_id', 'timestamp', 'centroid', 'yaw', 'extent'])

(2)定义函数sample_dataset,功能是使用配置文件和本地数据管理器构建Rasterizer,然后创建了一个代理数据集(AgentDataset)对象。最后,返回数据集中第100个样本的信息,包括图像、目标位置等。

def sample_dataset():
    rasterizer = build_rasterizer(cfg, dm)
    
    train_dataset = AgentDataset(cfg, train_zarr, rasterizer)
    return train_dataset[100]

(3)绘制了六幅图像,每幅图像的Raster尺寸不同。通过循环遍历不同的Raster尺寸(sizes列表),调用sample_dataset函数获取对应Raster尺寸的图像样本,并在图中显示,如图10-8所示。最后,将Raster尺寸重置为默认值[224, 224]。

sizes = [[200, 200], [224, 224], [250, 250], [350, 350], [450, 450], [500, 500]]
 
f, ax = plt.subplots(2, 3, figsize=(20, 12))
ax = ax.flatten()
 
for i in range(6):
    cfg['raster_params']['raster_size'] = sizes[i]
    sample = sample_dataset()
    
    ax[i].imshow(sample['image'][-3:].transpose(1, 2, 0))
    ax[i].get_xaxis().set_visible(False)
    ax[i].get_yaxis().set_visible(False)
    ax[i].set_title(f"Raster size: {sizes[i]}")
 
#reset to default
cfg['raster_params']['raster_size'] = [224, 224]

图10-8  绘制的六幅图像

(4)下面的代码绘制了六幅图像,每幅图像的像素尺寸(pixel size)不同,如图10-9所示。通过循环遍历不同的像素尺寸(sizes列表),调用sample_dataset函数获取对应像素尺寸的图像样本,并在图中显示。最后,将像素尺寸重置为默认值[0.5, 0.5]。

sizes = [[.2, .2,], [.3, .3], [.4, .4], [.5, .5], [.6, .6], [.7, .7]]
 
f, ax = plt.subplots(2, 3, figsize=(20, 12))
ax = ax.flatten()
 
for i in range(6):
    cfg['raster_params']['pixel_size'] = sizes[i]
    sample = sample_dataset()
    
    ax[i].imshow(sample['image'][-3:].transpose(1, 2, 0))
    ax[i].get_xaxis().set_visible(False)
    ax[i].get_yaxis().set_visible(False)
    ax[i].set_title(f"Pixel size: {sizes[i]}")
 
#reset to default
cfg['raster_params']['pixel_size'] = [0.5, 0.5]

图10-9  重设像素后的六幅图像

如果pixel_size = [.5, .5],这意味着最多能够捕捉大小不小于半米的物体:如果物体小于半米,则不会被检测为像素,因此要查看这些物体需要更高的分辨率(较低的 pixel_size)。会发现由 pixel_size 定义的栅格化过程会存在一些固有的不准确性,每个历史位置、车道和其他代理都被编码为像素,如果栅格的 pixel_size = .5,应该期望每个预测位置的每个方向有 .5/4 的平均误差,这可以通过使用较小的 pixel_size 来解决这个问题。例如下面的代码绘制了四幅图像,每幅图像的Raster尺寸和像素尺寸均不同,如图10-10所示。通过循环遍历不同的Raster尺寸和像素尺寸组合(sizes列表),调用sample_dataset函数获取对应的图像样本,并在图中显示。最后,将Raster尺寸和像素尺寸重置为默认值[224, 224]和[0.5, 0.5]。

sizes = [[[200, 200],[.5, .5]], [[250, 250],[.4, .4]], [[350, 350],[.3, .3]], [[500, 500],[.2, .2]]]
 
f, ax = plt.subplots(1, 4, figsize=(20, 12))
ax = ax.flatten()
 
for i in range(4):
    cfg['raster_params']['pixel_size'] = sizes[i][1]
    cfg['raster_params']['raster_size'] = sizes[i][0]
    sample = sample_dataset()
    
    ax[i].imshow(sample['image'][-3:].transpose(1, 2, 0))
    ax[i].get_xaxis().set_visible(False)
    ax[i].get_yaxis().set_visible(False)
    ax[i].set_title(f"Raster/Pixel size: {sizes[i]}")
 
#reset to default
cfg['raster_params']['raster_size'] = [224, 224]

图10-10  4幅图像

  • 32
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值