Kaggle competition: Lyft Motion Prediction for Autonomous Vehicles
<SOS> metric: PostProcessorKernel Kaggle data source: lyft-motion-prediction-autonomous-vehicles<init_hyperparams>
TL_FACE_DTYPE,
filter_agents_by_labels,
filter_tl_faces_by_frames,
get_agents_slice_from_frames,
get_tl_faces_slice_from_frames, 
)
 def generate_kinetic_agent_sample(
 state_index: int,
frames: np.ndarray,
agents: np.ndarray,
tl_faces: np.ndarray,
selected_track_id: Optional[int],
raster_size: Tuple[int, int],
pixel_size: np.ndarray,
ego_center: np.ndarray,
history_num_frames: int,
history_step_size: int,
future_num_frames: int,
future_step_size: int,
filter_agents_threshold: float,
rasterizer: Optional[Rasterizer] = None,
perturbation: Optional[Perturbation] = None, 
)-> dict:

 agent_velocity = None
history_slice = get_history_slice(state_index, history_num_frames, history_step_size, include_current_state=True)
 future_slice = get_future_slice(state_index, future_num_frames, future_step_size)
 history_frames = frames[history_slice].copy()
future_frames = frames[future_slice].copy()
sorted_frames = np.concatenate(( history_frames[::-1], future_frames))
agent_slice = get_agents_slice_from_frames(sorted_frames[0], sorted_frames[-1])
 agents = agents[agent_slice].copy()
history_frames["agent_index_interval"] -= agent_slice.start
future_frames["agent_index_interval"] -= agent_slice.start
history_agents = filter_agents_by_frames(history_frames, agents)
 future_agents = filter_agents_by_frames(future_frames, agents)
 try:
tl_slice = get_tl_faces_slice_from_frames(history_frames[-1], history_frames[0])
 history_frames["traffic_light_faces_index_interval"] -= tl_slice.start
history_tl_faces = filter_tl_faces_by_frames(history_frames, tl_faces[tl_slice].copy())
 except ValueError:
history_tl_faces = [np.empty(0, dtype=TL_FACE_DTYPE)for _ in history_frames]
if perturbation is not None:
history_frames, future_frames = perturbation.perturb(
 history_frames=history_frames, future_frames=future_frames 
)
 cur_frame = history_frames[0]
cur_agents = history_agents[0]
if selected_track_id is None:
agent_centroid = cur_frame["ego_translation"][:2]
agent_velocity = np.array([0, 0], dtype=np.float32)
 agent_yaw = rotation33_as_yaw(cur_frame["ego_rotation"])
 agent_extent = np.asarray(( EGO_EXTENT_LENGTH, EGO_EXTENT_WIDTH, EGO_EXTENT_HEIGHT))
selected_agent = None
else:
try:
agent = filter_agents_by_track_id(
 filter_agents_by_labels(cur_agents, filter_agents_threshold), selected_track_id 
)[0]
except IndexError:
raise ValueError(f" track_id {selected_track_id} not in frame or below threshold")
 agent_centroid = agent["centroid"]
agent_velocity = agent["velocity"]
agent_yaw = float(agent["yaw"])
 agent_extent = agent["extent"]
selected_agent = agent
input_im =(
 None
if not rasterizer
else rasterizer.rasterize(history_frames, history_agents, history_tl_faces, selected_agent)
)
 world_to_image_space = world_to_image_pixels_matrix(
 raster_size,
pixel_size,
ego_translation_m=agent_centroid,
ego_yaw_rad=agent_yaw,
ego_center_in_image_ratio=ego_center, 
)
 future_coords_offset, future_vel_offset, future_accel_offset, _, future_yaws_offset, future_availability = _create_targets_for_deep_prediction(
 future_num_frames, future_frames, selected_track_id, future_agents, agent_centroid[:2], agent_velocity[:2],
agent_yaw, 
)
 history_coords_offset, history_vel_offset, history_accel_offset, history_jerk_offset, history_yaws_offset, \
history_availability = _create_targets_for_deep_prediction(history_num_frames + 1, history_frames,
selected_track_id, history_agents, agent_centroid[:2], agent_velocity[:2], agent_yaw, 
)
 estimated_future_positions = _extrapolate_targets(future_num_frames, history_num_frames, history_coords_offset,
history_vel_offset, history_accel_offset, history_jerk_offset)
 error_arr = np.abs(estimated_future_positions - future_coords_offset[10:])
 error = np.average(error_arr)
 return {
"image": input_im,
"target_positions": future_coords_offset,
"target_velocities": future_vel_offset,
"target_accelerations": future_accel_offset,
"target_yaws": future_yaws_offset,
"target_availabilities": future_availability,
"history_positions": history_coords_offset,
"history_velocities": history_vel_offset,
"history_accelerations": history_accel_offset,
"history_yaws": history_yaws_offset,
"history_availabilities": history_availability,
"estimated_future_positions": estimated_future_positions,
"world_to_image": world_to_image_space,
"centroid": agent_centroid,
"yaw": agent_yaw,
"extent": agent_extent,
}
def _extrapolate_targets(future_num_frames: int, history_num_frames: int, position_history: np.ndarray,
vel_history: np.ndarray, accel_history: np.ndarray, jerk_history: np.ndarray)-> np.ndarray:

 dt = 0.1
start_time = len(position_history)* dt
predict_frames = future_num_frames - history_num_frames
time_arr = np.arange(dt, predict_frames * dt + dt, dt)
 avg_vel = np.array([np.average(vel_history.T[0]), np.average(vel_history.T[1])])
 avg_acc = np.array([np.average(accel_history.T[0]), np.average(accel_history.T[1])])
 avg_jrk = np.array([np.average(jerk_history.T[0]), np.average(jerk_history.T[1])])
 pos = np.array([position_history[-1]] ).T
vel = np.array([avg_vel] ).T
accel = np.array([avg_acc] ).T
jerk = np.array([avg_jrk] ).T
res = pos * np.ones(time_arr.shape)+ vel * time_arr +(accel * time_arr ** 2)/2 +(jerk * time_arr ** 3)/ 6
return res.T
def _create_targets_for_deep_prediction(
 num_frames: int,
frames: np.ndarray,
selected_track_id: Optional[int],
agents: List[np.ndarray],
agent_current_centroid: np.ndarray,
agent_current_velocity: np.ndarray,
agent_current_yaw: float, 
)-> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]:

 num_avail = 0
num_unavail = 0
last_avail_index = -1
last_unavail_index = -1
coords_offset = np.zeros(( num_frames, 2), dtype=np.float32)
 vel_offset = np.zeros(( num_frames, 2), dtype=np.float32)
 accel_offset = np.zeros(( num_frames, 2), dtype=np.float32)
 jerk_offset = np.zeros(( num_frames, 2), dtype=np.float32)
 yaws_offset = np.zeros(( num_frames, 1), dtype=np.float32)
 availability = np.zeros(( num_frames,), dtype=np.float32)
 for i,(frame, agents)in enumerate(zip(frames, agents)) :
if selected_track_id is None:
agent_centroid = frame["ego_translation"][:2]
agent_yaw = rotation33_as_yaw(frame["ego_rotation"])
 agent_velocity = np.array([0, 0], dtype=np.float32)
 num_avail = num_avail + 1
else:
try:
agent = filter_agents_by_track_id(agents, selected_track_id)[0]
num_avail = num_avail + 1
except IndexError:
availability[i] = 0.0
last_unavail_index = i
num_unavail = num_unavail + 1
continue
agent_centroid = agent["centroid"]
agent_velocity = agent["velocity"]
agent_yaw = agent["yaw"]
coords_offset[i] = agent_centroid - agent_current_centroid
if num_avail == 1:
vel_offset[i] = agent_current_velocity
accel_offset[i] = np.array([0, 0], dtype=np.float32)
 jerk_offset[i] = np.array([0, 0], dtype=np.float32)
 elif last_unavail_index == -1:
dx = coords_offset[i] - coords_offset[i - 1]
dt = 0.1
vel_offset[i] = dx / dt
accel_offset[i] =(vel_offset[i] - vel_offset[i - 1])/ dt
jerk_offset[i] =(accel_offset[i] - accel_offset[i - 1])/ dt
elif last_unavail_index == i - 1:
prev_vel = vel_offset[last_avail_index]
prev_pos = coords_offset[last_avail_index]
pos = coords_offset[i]
dx = pos - prev_pos
dt =(i - last_avail_index)* 0.1
vel =(dx / dt)* - prev_vel
vel_offset[i] = vel
accel_offset[i] =(((dx - prev_vel * dt)* 2)**(1/2)) / dt
jerk_offset[i] =(accel_offset[i] - accel_offset[last_avail_index])/ dt
else:
dx = coords_offset[i] - coords_offset[i - 1]
dt = 0.1
vel_offset[i] = dx / dt
accel_offset[i] =(agent_velocity ** 2 - vel_offset[i - 1] ** 2)/(2 * dx)
 jerk_offset[i] =(accel_offset[i] - accel_offset[i - 1])/ dt
yaws_offset[i] = agent_yaw - agent_current_yaw
availability[i] = 1.0
last_avail_index = i
return coords_offset, vel_offset, accel_offset, jerk_offset, yaws_offset, availability
cfg = {
'format_version': 4,
'data_path': "/kaggle/input/lyft-motion-prediction-autonomous-vehicles",
'model_params': {
'model_architecture': 'resnet34',
'history_num_frames': 10,
'history_step_size': 1,
'history_delta_time': 0.1,
'future_num_frames': 50,
'future_step_size': 1,
'future_delta_time': 0.1,
'model_name': "model_resnet34_output",
'lr': 1e-3,
'weight_path': "/kaggle/input/lyft-pretrained-model-hv/model_multi_update_lyft_public.pth",
'train': False,
'predict': True
},
'raster_params': {
'raster_size': [224, 224],
'pixel_size': [0.5, 0.5],
'ego_center': [0.25, 0.5],
'map_type': 'py_semantic',
'satellite_map_key': 'aerial_map/aerial_map.png',
'semantic_map_key': 'semantic_map/semantic_map.pb',
'dataset_meta_key': 'meta.json',
'filter_agents_threshold': 0.5
},
'train_data_loader': {
'key': 'scenes/train.zarr',
'batch_size': 16,
'shuffle': True,
'num_workers': 4
},
'test_data_loader': {
'key': 'scenes/test.zarr',
'batch_size': 32,
'shuffle': False,
'num_workers': 4
},
'train_params': {
'max_num_steps': 101,
'checkpoint_every_n_steps': 20,
}
}<feature_engineering>
MIN_FRAME_HISTORY = 10
MIN_FRAME_FUTURE = 1
class KineticDataset(AgentDataset):
def __init__(
 self,
cfg: dict,
zarr_dataset: ChunkedDataset,
rasterizer: Rasterizer,
perturbation: Optional[Perturbation] = None,
agents_mask: Optional[np.ndarray] = None,
min_frame_history: int = MIN_FRAME_HISTORY,
min_frame_future: int = MIN_FRAME_FUTURE, 
):
assert perturbation is None, "KineticDataset does not support perturbation(yet)"
super(KineticDataset, self ).__init__(cfg, zarr_dataset, rasterizer, perturbation, agents_mask,
min_frame_history, min_frame_future)
 self.sample_function = partial(
 generate_kinetic_agent_sample,
raster_size=cast(Tuple[int, int], tuple(cfg["raster_params"]["raster_size"])) ,
pixel_size=np.array(cfg["raster_params"]["pixel_size"]),
ego_center=np.array(cfg["raster_params"]["ego_center"]),
history_num_frames=cfg["model_params"]["history_num_frames"],
history_step_size=cfg["model_params"]["history_step_size"],
future_num_frames=cfg["model_params"]["future_num_frames"],
future_step_size=cfg["model_params"]["future_step_size"],
filter_agents_threshold=cfg["raster_params"]["filter_agents_threshold"],
rasterizer=rasterizer,
perturbation=perturbation, 
)
 def get_frame(self, scene_index: int, state_index: int, track_id: Optional[int] = None)-> dict:

 frames = self.dataset.frames[get_frames_slice_from_scenes(self.dataset.scenes[scene_index])]
data = self.sample_function(state_index, frames, self.dataset.agents, self.dataset.tl_faces, track_id)
 image = data["image"].transpose(2, 0, 1)
 target_positions = np.array(data["target_positions"], dtype=np.float32)
 target_yaws = np.array(data["target_yaws"], dtype=np.float32)
 history_positions = np.array(data["history_positions"], dtype=np.float32)
 estimated_positions = np.array(data["estimated_future_positions"], dtype=np.float32)
 timestamp = frames[state_index]["timestamp"]
track_id = np.int64(-1 if track_id is None else track_id)
 return {
"image": image,
"target_positions": target_positions,
"target_yaws": target_yaws,
"target_availabilities": data["target_availabilities"],
"history_positions": history_positions,
"history_availabilities": data["history_availabilities"],
"estimated_future_positions": estimated_positions,
"world_to_image": data["world_to_image"],
"track_id": track_id,
"timestamp": timestamp,
"centroid": data["centroid"],
"yaw": data["yaw"],
"extent": data["extent"],
}
DIR_INPUT = cfg["data_path"]
os.environ["L5KIT_DATA_FOLDER"] = DIR_INPUT
dm = LocalDataManager(None )<create_dataframe>
def trim_network_at_index(network: nn.Module, index: int = -1)-> nn.Module:

 assert index < 0, f"Param index must be negative.Received {index}."
return nn.Sequential(*list(network.children())[:index])
 class MnasBackbone(nn.Module):

 def __init__(self, num_in_channels: int = 3):

 super().__init__()
model = mnasnet1_0(pretrained=False)
 layer = model.layers[0]
model.layers[0] = nn.Conv2d(
 in_channels=num_in_channels,
out_channels=layer.out_channels,
kernel_size=layer.kernel_size,
stride=layer.stride,
padding=layer.padding,
bias=False, 
)
 self.backbone = trim_network_at_index(model, -1)
 def forward(self, input_tensor: torch.Tensor)-> torch.Tensor:

 backbone_features = self.backbone(input_tensor)
 return backbone_features.mean([2, 3])
train_cfg = cfg["train_data_loader"]
rasterizer = build_rasterizer(cfg, dm)
 train_zarr = ChunkedDataset(dm.require(train_cfg["key"])).open()
train_dataset = AgentDataset(cfg, train_zarr, rasterizer)
 train_dataloader = DataLoader(train_dataset, shuffle=train_cfg["shuffle"], batch_size=train_cfg["batch_size"],
num_workers=train_cfg["num_workers"])
 print("==================================TRAIN DATA==================================")
 print(train_dataset )<create_dataframe>
ASV_DIM = 3
def calculate_backbone_feature_dim(backbone, input_shape: Tuple[int, int, int])-> int:

 tensor = torch.ones(1, *input_shape)
 output_feat = backbone.forward(tensor)
 return output_feat.shape[-1]
class LyftNet(nn.Module):

 def __init__(self, backbone: nn.Module, num_modes: int, num_targets: int, num_kinetic_dim: int = 3,
n_hidden_layers: int = 4096, input_shape: Tuple[int, int, int] =(3, 500, 500)) :

 super().__init__()
self.ASV_DIM = num_kinetic_dim
self.backbone = backbone
self.num_modes = num_modes
backbone_feature_dim = calculate_backbone_feature_dim(backbone, input_shape)
 self.fc1 = nn.Linear(backbone_feature_dim + self.ASV_DIM, n_hidden_layers, bias=True)
 predictions_per_mode = num_targets
self.num_pred = predictions_per_mode * num_modes
self.future_len = int(num_targets / 2)
 self.norm = nn.BatchNorm1d(self.ASV_DIM)
 self.fc2 = nn.Linear(n_hidden_layers, int(self.num_pred + num_modes))
def forward(self, image_tensor: torch.Tensor,
agent_state_vector: torch.Tensor)-> torch.Tensor:

 backbone_features = self.backbone(image_tensor)
 features = torch.cat([backbone_features, self.norm(agent_state_vector)], dim=1)
 predictions = self.fc2(self.fc1(features))
bs, _ = predictions.shape
pred, confidences = torch.split(predictions, self.num_pred, dim=1)
 pred = pred.view(bs, self.num_modes, self.future_len, 2)
 assert confidences.shape ==(bs, self.num_modes)
 confidences = torch.softmax(confidences, dim=1)
 if math.isnan(confidences[0][0].item()):
print("Oh no, not the naan")
 print(agent_state_vector)
 return pred, confidences
test_cfg = cfg["test_data_loader"]
rasterizer = build_rasterizer(cfg, dm)
 test_zarr = ChunkedDataset(dm.require(test_cfg["key"])).open()
test_mask = np.load(f"{DIR_INPUT}/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 DATA==================================")
 print(test_dataset )<choose_model_class>
class LyftManager:
def __init__(self, config, data_path, device, num_modes=3, verbose=False):
self.cfg = config
self.data_path = data_path
self.device = device
self.verbose = verbose
num_history_channels =(self.cfg["model_params"]["history_num_frames"] + 1)* 2
num_in_channels = 3 + num_history_channels
self.backbone = MnasBackbone(num_in_channels=num_in_channels)
 raster_size = self.cfg["raster_params"]["raster_size"]
num_targets = 2 * self.cfg["model_params"]["future_num_frames"]
self.future_len = self.cfg["model_params"]["future_num_frames"]
print("Number of Targets = ", self.future_len)
 self.num_targets = num_targets
self.num_preds = num_targets * num_modes
self.num_modes = num_modes
self.model = LyftNet(self.backbone, num_modes=num_modes, num_kinetic_dim=2 *(self.future_len + 1),
num_targets=num_targets, input_shape=(num_in_channels, raster_size[0], raster_size[1]))
self.model.to(device=self.device)
 def train(self, iterations, lr=1e-3, file_name="lyft-net.pth"):
os.environ["L5KIT_DATA_FOLDER"] = self.data_path
dm = LocalDataManager(None)
 cfg = self.cfg
print(cfg)
 train_cfg = cfg["train_data_loader"]
rasterizer = build_rasterizer(cfg, dm)
 train_zarr = ChunkedDataset(dm.require(train_cfg["key"])).open()
if self.verbose:
print("Dataset Chunked")
 train_dataset = KineticDataset(cfg, train_zarr, rasterizer)
 if self.verbose:
print("Agent Dataset Retrieved")
 train_dataloader = DataLoader(train_dataset,
shuffle=train_cfg["shuffle"],
batch_size=train_cfg["batch_size"],
num_workers=train_cfg["num_workers"])
 print(train_dataset)
 optimizer = optim.Adam(self.model.parameters() , lr=lr)
 criterion = nn.PoissonNLLLoss()
tr_it = iter(train_dataloader)
 progress_bar = tqdm(range(iterations))
losses_train = []
rolling_avg = []
for i in progress_bar:
try:
data = next(tr_it)
 except StopIteration:
tr_it = iter(train_dataloader)
 data = next(tr_it)
 self.model.train()
torch.set_grad_enabled(True)
 position_tensor = data["target_positions"].to(self.device)
 history_position_tensor = data["history_positions"].to(self.device)
 estimated_future_positions = data["estimated_future_positions"].to(self.device)
 imageTensor = data["image"].to(self.device)
 if self.verbose:
print("Image Tensor: ", imageTensor.shape)
 state_vector = torch.cat([estimated_future_positions, history_position_tensor], 1 ).to(self.device)
 state_vector = torch.flatten(state_vector, 1 ).to(self.device)
 if self.verbose:
print("State Vector: ", state_vector.shape)
 pred, conf = self.model.forward(imageTensor, state_vector)
 if self.verbose:
print("Prediction: ", pred.shape)
 print("Probability: ", conf.shape)
 target_availabilities = data["target_availabilities"].unsqueeze(-1 ).to(self.device)
 flattenedTargets = torch.flatten(target_availabilities, 1, 2)
 loss = pytorch_neg_multi_log_likelihood_batch(position_tensor, pred, conf, flattenedTargets)
 optimizer.zero_grad()
loss.backward()
optimizer.step()
losses_train.append(loss.item())
 rolling_avg.append(np.mean(losses_train))
progress_bar.set_description(f"loss: {loss.item() } loss(avg): {np.mean(losses_train)}")
 print("Done Training")
 torch.save(self.model.state_dict() , f"/home/michael/Workspace/Lyft/model/{file_name}")
 def evaluate(self, data_path, file_name="submission.csv"):
os.environ["L5KIT_DATA_FOLDER"] = data_path
dm = LocalDataManager(None)
 cfg = self.cfg
test_cfg = cfg["test_data_loader"]
rasterizer = build_rasterizer(cfg, dm)
 test_zarr = ChunkedDataset(dm.require(test_cfg["key"])).open()
test_mask = np.load(f"{data_path}/scenes/mask.npz")["arr_0"]
test_dataset = KineticDataset(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"])
 test_dataloader = test_dataloader
print(test_dataloader)
 self.model.eval()
torch.set_grad_enabled(False)
 criterion = nn.MSELoss(reduction="none")
 future_coords_offsets_pd = []
timestamps = []
pred_coords = []
confidences_list = []
agent_ids = []
progress_bar = tqdm(test_dataloader)
 for data in progress_bar:
history_position_tensor = data["history_positions"].to(self.device)
 estimated_future_positions = data["estimated_future_positions"].to(self.device)
 imageTensor = data["image"].to(self.device)
 if self.verbose:
print("Image Tensor: ", imageTensor.shape)
 state_vector = torch.cat([estimated_future_positions, history_position_tensor], 1 ).to(self.device)
 state_vector = torch.flatten(state_vector, 1 ).to(self.device)
 if self.verbose:
print("State Vector: ", state_vector.shape)
 pred, confidences = self.model.forward(imageTensor, state_vector)
 timestamps.append(data["timestamp"].numpy().copy())
 agent_ids.append(data["track_id"].numpy().copy())
 pred_coords.append(pred.cpu().numpy().copy())
 confidences_list.append(confidences.cpu().numpy().copy())
 pred_path = f"{os.getcwd() }/{file_name}"
write_pred_csv(pred_path,
timestamps=np.concatenate(timestamps),
track_ids=np.concatenate(agent_ids),
coords=np.concatenate(pred_coords),
confs=np.concatenate(confidences_list))
torch.cuda.empty_cache()
def load(self, checkpoint_path:str):
state_dict = torch.load(checkpoint_path, map_location=self.device)
 self.model.load_state_dict(state_dict)
class LyftMultiModel(nn.Module):
def __init__(self, cfg: Dict, num_modes=3):
super().__init__()
architecture = cfg["model_params"]["model_architecture"]
backbone = eval(architecture )(pretrained=True, progress=True)
 self.backbone = backbone
num_history_channels =(cfg["model_params"]["history_num_frames"] + 1)* 2
num_in_channels = 3 + num_history_channels
self.backbone.conv1 = nn.Conv2d(
 num_in_channels,
self.backbone.conv1.out_channels,
kernel_size=self.backbone.conv1.kernel_size,
stride=self.backbone.conv1.stride,
padding=self.backbone.conv1.padding,
bias=False, 
)
 if architecture == "resnet50":
backbone_out_features = 2048
else:
backbone_out_features = 512
self.future_len = cfg["model_params"]["future_num_frames"]
num_targets = 2 * self.future_len
self.head = nn.Sequential(
 nn.Linear(in_features=backbone_out_features, out_features=4096), 
)
 self.num_preds = num_targets * num_modes
self.num_modes = num_modes
self.logit = nn.Linear(4096, out_features=self.num_preds + num_modes)
 def forward(self, x):
x = self.backbone.conv1(x)
 x = self.backbone.bn1(x)
 x = self.backbone.relu(x)
 x = self.backbone.maxpool(x)
 x = self.backbone.layer1(x)
 x = self.backbone.layer2(x)
 x = self.backbone.layer3(x)
 x = self.backbone.layer4(x)
 x = self.backbone.avgpool(x)
 x = torch.flatten(x, 1)
 x = self.head(x)
 x = self.logit(x)
 bs, _ = x.shape
pred, confidences = torch.split(x, self.num_preds, dim=1)
 pred = pred.view(bs, self.num_modes, self.future_len, 2)
 assert confidences.shape ==(bs, self.num_modes)
 confidences = torch.softmax(confidences, dim=1)
 return pred, confidences<compute_train_metric>
data_path = "/kaggle/input/lyft-motion-prediction-autonomous-vehicles"
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
 config = load_config_data("/kaggle/input/lyftnet/config_lyftnet.yaml")
 config["test_data_loader"]["batch_size"] = 16
config["test_data_loader"]["num_workers"] = 8
checkpoint_path = "/kaggle/input/lyftnet/lyft-net.pth"
manager = LyftManager(config=config, data_path=data_path, device=device, num_modes=3, verbose=False)
 manager.load(checkpoint_path)
 manager.evaluate(data_path=data_path )
<choose_model_class><EOS>