Kaggle competition: Lyft Motion Prediction for Autonomous Vehicles
<SOS> metric: PostProcessorKernel Kaggle data source: lyft-motion-prediction-autonomous-vehicles<data_type_conversions>
!pip install pytorch-pfn-extras==0.3.1
ts = time.time()
matrix = []
cols = ["date_block_num", "shop_id", "item_id"]
for i in range(34):
sales = train[train.date_block_num == i]
matrix.append(np.array(list(product([i], sales.shop_id.unique() , sales.item_id.unique())) , dtype = np.int16))
matrix = pd.DataFrame(np.vstack(matrix), columns = cols)
 matrix["date_block_num"] = matrix["date_block_num"].astype(np.int8)
 matrix["shop_id"] = matrix["shop_id"].astype(np.int8)
 matrix["item_id"] = matrix["item_id"].astype(np.int16)
 matrix.sort_values(cols, inplace = True)
 time.time() - ts<feature_engineering>
py.init_notebook_mode(connected=True)
 pio.templates.default = "plotly_dark"
pd.set_option('max_columns', 50 )
train["revenue"] = train["item_cnt_day"] * train["item_price"]<merge>
rc('animation', html='jshtml')
 print("l5kit version:", l5kit.__version__ )
ts = time.time()
group = train.groupby(["date_block_num", "shop_id", "item_id"] ).agg({"item_cnt_day": ["sum"]})
 group.columns = ["item_cnt_month"]
group.reset_index(inplace = True)
 matrix = pd.merge(matrix, group, on = cols, how = "left")
 matrix["item_cnt_month"] = matrix["item_cnt_month"].fillna(0 ).astype(np.float16)
 time.time() - ts<data_type_conversions>
import torch
from pathlib import Path
import pytorch_pfn_extras as ppe
from math import ceil
from pytorch_pfn_extras.training import IgniteExtensionsManager
from pytorch_pfn_extras.training.triggers import MinValueTrigger
from torch import nn, optim
from torch.utils.data import DataLoader
from torch.utils.data.dataset import Subset
import pytorch_pfn_extras.training.extensions as E
test["date_block_num"] = 34
test["date_block_num"] = test["date_block_num"].astype(np.int8)
 test["shop_id"] = test.shop_id.astype(np.int8)
 test["item_id"] = test.item_id.astype(np.int16 )<concatenate>
class LyftMultiModel(nn.Module):
def __init__(self, cfg: Dict, num_modes=3):
super().__init__()
backbone = resnet18(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, 
)
 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
ts = time.time()
matrix = pd.concat([matrix, test.drop(["ID"],axis = 1)], ignore_index=True, sort=False, keys=cols)
 matrix.fillna(0, inplace = True)
 time.time() - ts<data_type_conversions>
def save_yaml(filepath, content, width=120):
with open(filepath, 'w')as f:
yaml.dump(content, f, width=width)
 def load_yaml(filepath):
with open(filepath, 'r')as f:
content = yaml.safe_load(f)
 return content
class DotDict(dict):

 __getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
ts = time.time()
matrix = pd.merge(matrix, shops, on = ["shop_id"], how = "left")
 matrix = pd.merge(matrix, items, on = ["item_id"], how = "left")
 matrix = pd.merge(matrix, cats, on = ["item_category_id"], how = "left")
 matrix["shop_city"] = matrix["shop_city"].astype(np.int8)
 matrix["shop_category"] = matrix["shop_category"].astype(np.int8)
 matrix["item_category_id"] = matrix["item_category_id"].astype(np.int8)
 matrix["subtype_code"] = matrix["subtype_code"].astype(np.int8)
 matrix["name2"] = matrix["name2"].astype(np.int8)
 matrix["name3"] = matrix["name3"].astype(np.int16)
 matrix["type_code"] = matrix["type_code"].astype(np.int8)
 time.time() - ts<merge>
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)
 pred, confidences = predictor(image)
 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
def lag_feature(df,lags, cols):
for col in cols:
print(col)
 tmp = df[["date_block_num", "shop_id","item_id",col ]]
for i in lags:
shifted = tmp.copy()
shifted.columns = ["date_block_num", "shop_id", "item_id", col + "_lag_"+str(i)]
shifted.date_block_num = shifted.date_block_num + i
df = pd.merge(df, shifted, on=['date_block_num','shop_id','item_id'], how='left')
 return df<merge>
cfg = {
'format_version': 4,
'model_params': {
'model_architecture': 'resnet50',
'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
},
'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': 12,
'shuffle': True,
'num_workers': 4
},
'valid_data_loader': {
'key': 'scenes/validate.zarr',
'batch_size': 32,
'shuffle': False,
'num_workers': 4
},
'test_data_loader': {
'key': 'scenes/test.zarr',
'batch_size': 8,
'shuffle': False,
'num_workers': 4
},
'train_params': {
'max_num_steps': 10000,
'checkpoint_every_n_steps': 5000,
}
}
ts = time.time()
group = matrix.groupby(["date_block_num"] ).agg({"item_cnt_month" : ["mean"]})
 group.columns = ["date_avg_item_cnt"]
group.reset_index(inplace = True)
 matrix = pd.merge(matrix, group, on = ["date_block_num"], how = "left")
 matrix.date_avg_item_cnt = matrix["date_avg_item_cnt"].astype(np.float16)
 matrix = lag_feature(matrix, [1], ["date_avg_item_cnt"])
 matrix.drop(["date_avg_item_cnt"], axis = 1, inplace = True)
 time.time() - ts<merge>
flags_dict = {
"debug": False,
"l5kit_data_folder": "/kaggle/input/lyft-motion-prediction-autonomous-vehicles",
"pred_mode": "multi",
"device": "cuda:0",
"out_dir": "results/multi_train",
"epoch": 2,
"snapshot_freq": 50,
}
ts = time.time()
group = matrix.groupby(['date_block_num', 'item_id'] ).agg({'item_cnt_month': ['mean']})
 group.columns = [ 'date_item_avg_item_cnt' ]
group.reset_index(inplace=True)
 matrix = pd.merge(matrix, group, on=['date_block_num','item_id'], how='left')
 matrix.date_item_avg_item_cnt = matrix['date_item_avg_item_cnt'].astype(np.float16)
 matrix = lag_feature(matrix, [1,2,3], ['date_item_avg_item_cnt'])
 matrix.drop(['date_item_avg_item_cnt'], axis=1, inplace=True)
 time.time() - ts<merge>
flags = DotDict(flags_dict)
 out_dir = Path(flags.out_dir)
 os.makedirs(str(out_dir), exist_ok=True)
 print(f"flags: {flags_dict}")
 save_yaml(out_dir / 'flags.yaml', flags_dict)
 save_yaml(out_dir / 'cfg.yaml', cfg)
 debug = flags.debug
ts = time.time()
group = matrix.groupby(["date_block_num","shop_id"] ).agg({"item_cnt_month" : ["mean"]})
 group.columns = ["date_shop_avg_item_cnt"]
group.reset_index(inplace = True)
 matrix = pd.merge(matrix, group, on = ["date_block_num","shop_id"], how = "left")
 matrix.date_avg_item_cnt = matrix["date_shop_avg_item_cnt"].astype(np.float16)
 matrix = lag_feature(matrix, [1,2,3], ["date_shop_avg_item_cnt"])
 matrix.drop(["date_shop_avg_item_cnt"], axis = 1, inplace = True)
 time.time() - ts<merge>
l5kit_data_folder = "/kaggle/input/lyft-motion-prediction-autonomous-vehicles"
os.environ["L5KIT_DATA_FOLDER"] = l5kit_data_folder
dm = LocalDataManager(None)
 print("Load dataset...")
 default_test_cfg = {
'key': 'scenes/test.zarr',
'batch_size': 32,
'shuffle': False,
'num_workers': 4
}
test_cfg = cfg.get("test_data_loader", default_test_cfg)
 rasterizer = build_rasterizer(cfg, dm)
 test_path = test_cfg["key"]
print(f"Loading from {test_path}")
 test_zarr = ChunkedDataset(dm.require(test_path)).open()
print("test_zarr", type(test_zarr))
test_mask = np.load(f"{l5kit_data_folder}/scenes/mask.npz")["arr_0"]
test_agent_dataset = AgentDataset(cfg, test_zarr, rasterizer, agents_mask=test_mask)
 test_dataset = test_agent_dataset
if debug:
test_dataset = Subset(test_dataset, np.arange(100))
test_loader = DataLoader(
 test_dataset,
shuffle=test_cfg["shuffle"],
batch_size=test_cfg["batch_size"],
num_workers=test_cfg["num_workers"],
pin_memory=True, 
)
 print(test_agent_dataset)
 print("
print("
ts = time.time()
group = matrix.groupby(["date_block_num","shop_id","item_id"] ).agg({"item_cnt_month" : ["mean"]})
 group.columns = ["date_shop_item_avg_item_cnt"]
group.reset_index(inplace = True)
 matrix = pd.merge(matrix, group, on = ["date_block_num","shop_id","item_id"], how = "left")
 matrix.date_avg_item_cnt = matrix["date_shop_item_avg_item_cnt"].astype(np.float16)
 matrix = lag_feature(matrix, [1,2,3], ["date_shop_item_avg_item_cnt"])
 matrix.drop(["date_shop_item_avg_item_cnt"], axis = 1, inplace = True)
 time.time() - ts<merge>
device = torch.device(flags.device)
 if flags.pred_mode == "multi":
predictor = LyftMultiModel(cfg)
 else:
raise ValueError(f"[ERROR] Unexpected value flags.pred_mode={flags.pred_mode}")
 pt_path = "/kaggle/input/lyft-resnet18-baseline/0918_predictor_full.pt"
print(f"Loading from {pt_path}")
 predictor.load_state_dict(torch.load(pt_path))
predictor.to(device )
ts = time.time()
group = matrix.groupby(['date_block_num', 'shop_id', 'subtype_code'] ).agg({'item_cnt_month': ['mean']})
 group.columns = ['date_shop_subtype_avg_item_cnt']
group.reset_index(inplace=True)
 matrix = pd.merge(matrix, group, on=['date_block_num', 'shop_id', 'subtype_code'], how='left')
 matrix.date_shop_subtype_avg_item_cnt = matrix['date_shop_subtype_avg_item_cnt'].astype(np.float16)
 matrix = lag_feature(matrix, [1], ['date_shop_subtype_avg_item_cnt'])
 matrix.drop(['date_shop_subtype_avg_item_cnt'], axis=1, inplace=True)
 time.time() - ts<merge>
timestamps, track_ids, coords, confs = run_prediction(predictor, test_loader )
ts = time.time()
group = matrix.groupby(['date_block_num', 'shop_city'] ).agg({'item_cnt_month': ['mean']})
 group.columns = ['date_city_avg_item_cnt']
group.reset_index(inplace=True)
 matrix = pd.merge(matrix, group, on=['date_block_num', "shop_city"], how='left')
 matrix.date_city_avg_item_cnt = matrix['date_city_avg_item_cnt'].astype(np.float16)
 matrix = lag_feature(matrix, [1], ['date_city_avg_item_cnt'])
 matrix.drop(['date_city_avg_item_cnt'], axis=1, inplace=True)
 time.time() - ts<merge>
csv_path = "submission.csv"
write_pred_csv(
 csv_path,
timestamps=timestamps,
track_ids=track_ids,
coords=coords,
confs=confs)
 print(f"Saved to {csv_path}" )