Kaggle competition: Lyft Motion Prediction for Autonomous Vehicles
<SOS> metric: PostProcessorKernel Kaggle data source: lyft-motion-prediction-autonomous-vehicles<categorify>
!pip install -U torch==1.7.0
cols = agg_col
matchMean = match[cols].mean().rename(columns=lambda s: '_matchMean.' + s ).reset_index()
all_data = pd.merge(all_data, reduce_mem_usage(matchMean))
print(all_data.shape)
 del matchMean
gc.collect()
for c in cols:
all_data['_percMean.' + c] = all_data[c] / all_data['_matchMean.' + c]
all_data.drop(['_matchMean.' + c], axis=1, inplace=True)
 fillInf(all_data, 0 )<merge>
warnings.filterwarnings("ignore")
 print(l5kit.__version__ )
killMinorRank = all_data[['matchId','_min.kills','_max.killPlace']].copy()
killMinorRank['_rank.minor.killPlace'] = killMinorRank.groupby(['matchId','_min.kills'] ).rank().values
all_data = pd.merge(all_data, killMinorRank)
 del killMinorRank
gc.collect()<sort_values>
def memory(verbose=True):
mem = psutil.virtual_memory()
gb = 1024*1024*1024
if verbose:
print('Physical memory:',
'%.2f GB(used),'%(( mem.total - mem.available)/ gb),
'%.2f GB(available)'%(( mem.available)/ gb), '/',
'%.2f GB'%(mem.total / gb))
return(mem.total - mem.available)/ gb
def gc_memory(verbose=True):
m = gc.collect()
if verbose:
print('GC:', m, end=' | ')
 memory()
memory() ;
null_cnt = all_data.isnull().sum().sort_values()
print(null_cnt[null_cnt > 0])
 all_data.head()<count_values>
def set_seed(seed):
random.seed(seed)
 np.random.seed(seed)
 os.environ["PYTHONHASHSEED"] = str(seed)
 torch.manual_seed(seed)
 torch.cuda.manual_seed(seed)
 set_seed(42 )
mapper = lambda x: 'solo' if('solo' in x)else 'duo' if('duo' in x)or('crash' in x)else 'squad'
all_data['matchTypeCat'] = all_data['matchType'].map(mapper)
 print(all_data['matchTypeCat'].value_counts() )<count_unique_values>
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': 128,
'shuffle': False,
'num_workers': 4,
},
'train_params': {
'steps': 12000,
'update_steps': 100,
'checkpoint_steps': 3000,
}
}
constant_column = [col for col in all_data.columns if all_data[col].nunique() == 1]
print('drop columns:', constant_column)
 all_data.drop(constant_column, axis=1, inplace=True )<feature_engineering>
DIR_INPUT = cfg["data_path"]
os.environ["L5KIT_DATA_FOLDER"] = DIR_INPUT
dm = LocalDataManager()
cols = [col for col in all_data.columns if col not in ['Id','matchId','groupId']]
for i, t in all_data.loc[:, cols].dtypes.iteritems() :
if t == object:
all_data[i] = pd.factorize(all_data[i])[0]<prepare_x_and_y>
%%time
rasterizer = build_rasterizer(cfg, dm )
X_train = all_data[all_data['winPlacePerc'].notnull() ].reset_index(drop=True)
 X_test = all_data[all_data['winPlacePerc'].isnull() ].drop(['winPlacePerc'], axis=1 ).reset_index(drop=True)
 del all_data
gc.collect()
Y_train = X_train.pop('winPlacePerc')
 X_test_grp = X_test[['matchId','groupId']].copy()
X_train.drop(['matchId','groupId'], axis=1, inplace=True)
 X_test.drop(['matchId','groupId'], axis=1, inplace=True)
 print(X_train.shape, X_test.shape )<create_dataframe>
%%time
train_cfg = cfg["train_data_loader"]
train_zarr = ChunkedDataset(dm.require(train_cfg["key"])).open(cached=False)
 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"],
pin_memory=True, prefetch_factor=8, 
)
 print(train_dataset )
print(pd.DataFrame([[val for val in dir() ], [sys.getsizeof(eval(val)) for val in dir() ]],
index=['name','size'] ).T.sort_values('size', ascending=False ).reset_index(drop=True)[:10] )<choose_model_class>
%%time
test_cfg = cfg["test_data_loader"]
test_zarr = ChunkedDataset(dm.require(test_cfg["key"])).open(cached=False)
 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"],
pin_memory=False, prefetch_factor=4, 
)
 print(test_dataset )
params={'learning_rate': 0.05,
'objective':'mae',
'metric':'mae',
'num_leaves': 31,
'verbose': 0,
'random_state':42,
'bagging_fraction': 0.7,
'feature_fraction': 0.7
}
mts = list()
fis = list()
pred = np.zeros(X_test.shape[0])
 for mt in X_train['matchTypeCat'].unique() :
idx = X_train[X_train['matchTypeCat'] == mt].index
reg = lgb.LGBMRegressor(**params, n_estimators=1000)
 reg.fit(X_train.loc[idx], Y_train.loc[idx])
 idx = X_test[X_test['matchTypeCat'] == mt].index
pred[idx] = reg.predict(X_test.loc[idx], num_iteration=reg.best_iteration_)
 mts.append(mt)
 fis.append(reg.feature_importances_ )<merge>
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
X_test_grp['winPlacePerc'] = pred
group = X_test_grp.groupby(['matchId'])
 X_test_grp['winPlacePerc'] = pred
X_test_grp['_rank.winPlacePerc'] = group['winPlacePerc'].rank(method='min')
 X_test = pd.concat([X_test, X_test_grp], axis=1)
 sub_match = X_test_grp[['matchId','_rank.winPlacePerc']].groupby(['matchId'])
 sub_group = group.count().reset_index() ['matchId'].to_frame()
X_test = pd.merge(X_test, sub_group )<feature_engineering>
def forward(data, model, device, criterion=pytorch_neg_multi_log_likelihood_batch, compute_loss=True):
inputs = data["image"].to(device)
 target_availabilities = data["target_availabilities"].to(device)
 targets = data["target_positions"].to(device)
 preds, confidences = model(inputs)
 loss = criterion(targets, preds, confidences, target_availabilities)if compute_loss else 0
return loss, preds, confidences
fullgroup =(X_test['numGroups'] == X_test['maxPlace'])
 subset = X_test.loc[fullgroup]
X_test.loc[fullgroup, 'winPlacePerc'] =(subset['_rank.winPlacePerc'].values - 1)/(subset['maxPlace'].values - 1)
 subset = X_test.loc[~fullgroup]
gap = 1.0 /(subset['maxPlace'].values - 1)
 new_perc = np.around(subset['winPlacePerc'].values / gap)* gap
X_test.loc[~fullgroup, 'winPlacePerc'] = new_perc<feature_engineering>
%%time
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
 model = LyftMultiModel(cfg)
 weight_path = cfg["model_params"]["weight_path"]
if weight_path:
model.load_state_dict(torch.load(weight_path))
model.to(device)
 optimizer = optim.Adam(model.parameters() , lr=cfg["model_params"]["lr"])
 print(f'device {device}' )
X_test.loc[~fullgroup, '_pred.winPlacePerc'] = np.around(X_test.loc[~fullgroup, 'winPlacePerc'].values / gap)+ 1
_=
X_test.loc[~fullgroup &(X_test['matchId'] == '000b598b79aa5e'),
['matchId','groupId','winPlacePerc','maxPlace','numGroups','_pred.winPlacePerc','_rank.winPlacePerc']
].sort_values(['matchId','_pred.winPlacePerc'] )<groupby>
print(model )
_=<feature_engineering>
%%time
if cfg["model_params"]["train"]:
tr_it = iter(train_dataloader)
 n_steps = cfg["train_params"]["steps"]
progress_bar = tqdm_notebook(range(1, 1 + n_steps), mininterval=5.)
losses = []
iterations = []
metrics = []
memorys = []
times = []
model_name = cfg["model_params"]["model_name"]
update_steps = cfg['train_params']['update_steps']
checkpoint_steps = cfg['train_params']['checkpoint_steps']
t_start = time.time()
torch.set_grad_enabled(True)
 for i in progress_bar:
try:
data = next(tr_it)
 except StopIteration:
tr_it = iter(train_dataloader)
 data = next(tr_it)
 model.train()
loss, _, _ = forward(data, model, device)
 optimizer.zero_grad()
loss.backward()
optimizer.step()
loss_v = loss.item()
losses.append(loss_v)
 if i % update_steps == 0:
mean_losses = np.mean(losses)
 timespent =(time.time() - t_start)/ 60
print('i: %5d'%i,
'loss: %10.5f'%loss_v, 'loss(avg): %10.5f'%mean_losses,
'%.2fmins'%timespent, end=' | ')
 mem = memory()
if i % checkpoint_steps == 0:
torch.save(model.state_dict() , f'{model_name}_{i}.pth')
 torch.save(optimizer.state_dict() , f'{model_name}_optimizer_{i}.pth')
 iterations.append(i)
 metrics.append(mean_losses)
 memorys.append(mem)
 times.append(timespent)
 torch.save(model.state_dict() , f'{model_name}_final.pth')
 torch.save(optimizer.state_dict() , f'{model_name}_optimizer_final.pth')
 results = pd.DataFrame({
'iterations': iterations,
'metrics(avg)': metrics,
'elapsed_time(mins)': times,
'memory(GB)': memorys,
})
 results.to_csv(f'train_metrics_{model_name}_{n_steps}.csv', index=False)
 print(f'Total training time is {(time.time() - t_start)/ 60} mins')
 memory()
display(results )
X_test.loc[X_test['maxPlace'] == 0, 'winPlacePerc'] = 0
X_test.loc[X_test['maxPlace'] == 1, 'winPlacePerc'] = 1
X_test.loc[(X_test['maxPlace'] > 1)&(X_test['numGroups'] == 1), 'winPlacePerc'] = 0
X_test['winPlacePerc'].describe()<save_to_csv>
print('Number of batches for predictoin:', int(np.ceil(len(test_dataset)/ cfg['test_data_loader']['batch_size'])) )
test = pd.read_csv('.. /input/test_V2.csv')
 submission = pd.merge(test, X_test[['matchId','groupId','winPlacePerc']])
 submission = submission[['Id','winPlacePerc']]
submission.to_csv("submission.csv", index=False )<set_options>
%%time
if cfg["model_params"]["predict"]:
model.eval()
torch.set_grad_enabled(False)
 future_coords_offsets_pd = []
timestamps = []
confidences_list = []
agent_ids = []
memorys_pred = []
t0 = time.time()
times_pred = []
iterations_pred = []
for i, data in enumerate(tqdm_notebook(test_dataloader, mininterval=5.)):
_, preds, confidences = forward(data, model, device, compute_loss=False)
 rotation = data["world_from_agent"][:, :2, :2].float().to(device)
 preds = torch.sum(preds[:, :, :, None, :] * rotation[:, None, None, :, :], dim=-1 ).cpu().numpy()
future_coords_offsets_pd.append(preds.copy())
 confidences_list.append(confidences.cpu().numpy().copy())
 timestamps.append(data["timestamp"].numpy().copy())
 agent_ids.append(data["track_id"].numpy().copy())
 if i%50 == 0:
t =(( time.time() - t0)/ 60)
 print('%4d'%i, '%6.2fmins'%t, end=' | ')
 mem = memory()
iterations_pred.append(i)
 memorys_pred.append(mem)
 times_pred.append(t)
 print('Total timespent: %6.2fmins'%(( time.time() - t0)/ 60))
memory()
warnings.filterwarnings('ignore')
 %matplotlib inline
py.init_notebook_mode(connected=True)
 warnings.filterwarnings("ignore")
 print(os.listdir(".. /input"))
debug = False
if debug == True:
df_train = pd.read_csv('.. /input/train_V2.csv', nrows=10000)
 df_test = pd.read_csv('.. /input/test_V2.csv')
 else:
df_train = pd.read_csv('.. /input/train_V2.csv')
 df_test = pd.read_csv('.. /input/test_V2.csv')
<filter>
%%time
pred_path = 'submission.csv'
write_pred_csv(
 pred_path,
timestamps=np.concatenate(timestamps),
track_ids=np.concatenate(agent_ids),
coords=np.concatenate(future_coords_offsets_pd),
confs=np.concatenate(confidences_list),
)
<filter><EOS> 
df_sub = pd.read_csv(pred_path)
 df_sub = df_sub.set_index(['timestamp', 'track_id'])
 display(df_sub )