diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..72f279e Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e7e9d11 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/.idea/MEKF_MAME.iml b/.idea/MEKF_MAME.iml new file mode 100644 index 0000000..8dc09e5 --- /dev/null +++ b/.idea/MEKF_MAME.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..3f1a734 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8656114 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5c99a7d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/adapt.py b/adapt.py index 9965955..d9502d1 100644 --- a/adapt.py +++ b/adapt.py @@ -6,6 +6,7 @@ import joblib import torch import numpy as np +import IPython from dataset.dataset import get_data_loader from adaptation.lookahead import Lookahead from adaptation.mekf import MEKF_MA @@ -107,8 +108,17 @@ def test(params, adaptor='none', adapt_step=1): pred_result = adaptable_prediction(data_loader, model, train_params, device, adaptor, adapt_step) traj_hist, traj_preds, traj_labels, intent_preds, intent_labels, pred_start_pos = pred_result - traj_preds = get_position(traj_preds, pred_start_pos, data_stats) - traj_labels = get_position(traj_labels, pred_start_pos, data_stats) + + + # IPython.embed() + # TODO: what happened to the multiple rollouts in the test set? only just 1 + # Note: traj_preds is 1 rollout's worth, w/ shape (len_rollout, ydim, 2) + # true_mse = torch.nn.MSELoss()(traj_preds * data_stats["data_std"] + data_stats["data_mean"], + # traj_labels * data_stats["data_std"] + data_stats["data_mean"]) + # true_mse = true_mse.cpu().detach().numpy() + + traj_preds = get_position(traj_preds, pred_start_pos, data_stats) # NOTE: converted these to position first! + traj_labels = get_position(traj_labels, pred_start_pos, data_stats) # NOTE!! intent_preds_prob = intent_preds.detach().clone() _, intent_preds = intent_preds.max(1) @@ -121,9 +131,15 @@ def test(params, adaptor='none', adapt_step=1): out_str = 'Evaluation Result: \n' + # out_str += "trajectory_mse: %.5f, \n" % (true_mse) + num, time_step = result['traj_labels'].shape[:2] mse = np.power(result['traj_labels'] - result['traj_preds'], 2).sum() / (num * time_step) out_str += "trajectory_mse: %.4f, \n" % (mse) + # TODO: calling this trajectory loss instead + # out_str += "trajectory_loss: %.4f, \n" % (mse) + + # IPython.embed() acc = (result['intent_labels'] == result['intent_preds']).sum() / len(result['intent_labels']) out_str += "action_acc: %.4f, \n" % (acc) @@ -135,9 +151,11 @@ def test(params, adaptor='none', adapt_step=1): return result -def main(dataset='vehicle_ngsim', model_type='rnn', adaptor='mekf',adapt_step=1): +def main(dataset='vehicle_ngsim', model_type='rnn', adaptor='mekf',adapt_step=1, epoch=1): save_dir = 'output/' + dataset + '/' + model_type + '/' - model_path = save_dir + 'model_1.pkl' + # TODO: default, load model_1 (product of first epoch), but should instead specify best epoch + # model_path = save_dir + 'model_1.pkl' + model_path = save_dir + 'model_%i.pkl' % (epoch) params = hyper_parameters() params._load_parameters(save_dir + 'log/') params.params_dict['train_param']['init_model'] = model_path @@ -146,5 +164,7 @@ def main(dataset='vehicle_ngsim', model_type='rnn', adaptor='mekf',adapt_step=1) if __name__ == '__main__': - main() + # main(adapt_step=50, model_type="fc", epoch=20) + # main(adapt_step=5) + main(adapt_step=50, model_type="fc", epoch=18) diff --git a/dataset/dataset.py b/dataset/dataset.py index 8293ef9..6d6b2d1 100644 --- a/dataset/dataset.py +++ b/dataset/dataset.py @@ -5,6 +5,7 @@ import numpy as np import torch from torch.utils.data.dataset import Dataset +import IPython def data_time_split(data_list,params): input_time_step = params['input_time_step'] @@ -84,7 +85,7 @@ def data_time_split(data_list,params): y_feature = np.array(y_feature) y_intent=np.array(y_intent) x_traj_len = np.array(x_traj_len) - data_ids=np.array(data_ids) + data_ids=np.array(data_ids) # for each window, describes the rollout number that it came from pred_start_pos = x_traj[:,-1] data ={'x_traj':x_traj,'x_speed':x_speed,'x_feature':x_feature, 'y_traj':y_traj,'y_speed':y_speed,'y_feature':y_feature, @@ -108,12 +109,19 @@ def __init__(self, params, mode='train',data_stats={}): self.mode = mode print(mode,'data preprocessing') cache_dir = params['log_dir']+mode+'.cache' - if os.path.exists(cache_dir): + # if os.path.exists(cache_dir): + if False: print('loading data from cache',cache_dir) self.data = joblib.load(cache_dir) + + # print("Just loaded data from saved cache") + # IPython.embed() else: raw_data = joblib.load(params['data_path'])[mode] - self.data = data_time_split(raw_data,params) + self.data = data_time_split(raw_data,params) # This just does windowing + + # print("Just loaded data to create anew") + # IPython.embed() if mode=='train': data_stats['traj_mean'] = np.mean(self.data['x_traj'],axis=(0,1)) @@ -150,6 +158,8 @@ def __init__(self, params, mode='train',data_stats={}): print(mode + '_data size:', len(self.data['x_encoder'])) print('each category counts:') print(Counter(self.data['y_intent'])) + print("In dataset.py") + # IPython.embed() def __getitem__(self, index): x = self.data['x_encoder'][index] diff --git a/parameters.py b/parameters.py index b955096..768279c 100644 --- a/parameters.py +++ b/parameters.py @@ -72,7 +72,7 @@ def train_param(self, param_dict=None): output_time_step=self.output_time_step, inp_feat = self.inp_feat, - traj_intent_loss_ratio=[1, 0.1], # traj loss : intent loss + traj_intent_loss_ratio=[1, 0.0], #TODO: originally [1, 0.1], traj loss : intent loss lr=0.01, lr_schedule='multistep', # multistep lr_decay_epochs=[7, 14], diff --git a/train.py b/train.py index 99f1bf9..2333f02 100644 --- a/train.py +++ b/train.py @@ -4,6 +4,7 @@ import warnings import torch +import IPython from parameters import hyper_parameters from dataset.dataset import get_data_loader from models.model_factory import create_model @@ -26,13 +27,25 @@ def evaluate(model, data_loader, criterion_traj, criterion_intend, params, epoch dat = get_predictions(data_loader, model, device) traj_hist, traj_preds, traj_labels, intent_preds, intent_labels, pred_start_pos = dat + # TODO: replacing loss traj with MSE on de-normalized output loss_traj = criterion_traj(traj_preds, traj_labels) loss_traj = loss_traj.cpu().detach().numpy() + + # loss_traj = criterion_traj(traj_preds*data_stats["data_std"] + data_stats["data_mean"], traj_labels*data_stats["data_std"] + data_stats["data_mean"]) + # loss_traj = loss_traj.cpu().detach().numpy() + traj_preds = get_position(traj_preds, pred_start_pos, data_stats) traj_labels = get_position(traj_labels, pred_start_pos, data_stats) mse = (traj_preds - traj_labels).pow(2).sum().float() / (traj_preds.size(0) * traj_preds.size(1)) mse = mse.cpu().detach().numpy() - out_str += "trajectory_loss: %.4f, trajectory_mse: %.4f, " % (loss_traj, mse) + # IPython.embed() + + # TODO: swapping what Abu calls mse and trajectory_loss + # temp = mse + # mse = loss_traj + # loss_traj = temp + + out_str += "trajectory_loss: %.6f, trajectory_mse: %.6f, " % (loss_traj, mse) loss_intent = criterion_intend(intent_preds, intent_labels) loss_intent = loss_intent.cpu().detach().numpy() @@ -47,7 +60,8 @@ def evaluate(model, data_loader, criterion_traj, criterion_intend, params, epoch log_dir = params['log_dir'] if not os.path.exists(log_dir + '%s.tsv' % mark): - with open(log_dir + 'test.tsv', 'a') as f: + # with open(log_dir + 'test.tsv', 'a') as f: # TODO: bug or intentional? + with open(log_dir + '%s.tsv' % mark, 'a') as f: f.write('epoch\ttraj_loss\tintent_loss\tmse\tacc\n') with open(log_dir + '%s.tsv' % mark, 'a') as f: @@ -77,6 +91,7 @@ def train_on_batch(data, model, optimizer, criterion_traj, criterion_intend, par mse = (pred_traj - y_traj).pow(2).sum().float() / (pred_traj.size(0) * pred_traj.size(1)) mse = mse.cpu().detach().numpy() loss_traj_val = loss_traj.cpu().detach().numpy() + # IPython.embed() out_str += "trajectory_loss: %.4f, trajectory_mse: %.4f, " % (loss_traj_val, mse) _, pred_intent_cls = pred_intent.max(1) @@ -102,6 +117,7 @@ def train(params): train_params = params.train_param() train_loader, valid_loader, test_loader, train_params = get_data_loader(train_params, mode='train') + # IPython.embed() params._save_overwrite_parameters(params_key='train_param', params_value=train_params) train_params['data_mean'] = torch.tensor(train_params['data_stats']['speed_mean'], dtype=torch.float).unsqueeze( @@ -123,6 +139,7 @@ def train(params): print('begin to train') for epoch in range(1, train_params['epochs'] + 1): for i, data in enumerate(train_loader, 0): + # IPython.embed() print_result = True if i % train_params['print_step'] == 0 else False train_on_batch(data, model, optimizer, criterion_traj, criterion_intend, params=train_params, print_result=print_result, epoch=epoch, iter=i) @@ -158,7 +175,9 @@ def train(params): def main(): - params = hyper_parameters(dataset='vehicle_ngsim', model_type='rnn') + # TODO: modify params here + params = hyper_parameters(dataset='vehicle_ngsim', model_type='fc') + # params = hyper_parameters(dataset='vehicle_ngsim', model_type='rnn') params._set_default_dataset_params() params.print_params() train(params) diff --git a/utils/adapt_utils.py b/utils/adapt_utils.py index 428d978..c9f1ef3 100644 --- a/utils/adapt_utils.py +++ b/utils/adapt_utils.py @@ -2,8 +2,14 @@ import numpy as np import torch from .pred_utils import get_prediction_on_batch - -data_size=100 +import IPython + +# TODO: this selects how much data to use +# data_size=100 +# test set size +# 16*128 = 2048 +# data_size=800 +data_size=3000 def batch2iter_data(dataloader, device='cpu',data_size=data_size): traj_hist, traj_labels, intent_labels, start_decodes, pred_start_pos, x_mask = None, None, None, None, None, None @@ -27,6 +33,7 @@ def batch2iter_data(dataloader, device='cpu',data_size=data_size): if data_size>0 and traj_hist.size(0)>data_size: break + print(traj_hist.shape) traj_hist = traj_hist.float().to(device) traj_labels = traj_labels.float().to(device) intent_labels = intent_labels.float().to(device) @@ -35,6 +42,8 @@ def batch2iter_data(dataloader, device='cpu',data_size=data_size): x_mask = x_mask.byte().to(device) data = [traj_hist, traj_labels, intent_labels, start_decodes, pred_start_pos, x_mask] + print("at the end of batch2iterdata") + # IPython.embed() return data @@ -65,9 +74,14 @@ def online_adaptation(dataloader, model, optimizer, params, device, cnt = [0, 0, 0] cost_list = [] post_cost_list=[] + + cost_diff_list = [] + print("In online_adaptation, ln 69") + # IPython.embed() for t in range(len(pred_start_pos)): batch_data = batches[t] _, pred_traj, y_traj, pred_intent, _, _ = get_prediction_on_batch(batch_data, model, device) + # IPython.embed() traj_preds[t] = pred_traj[0].detach() intent_preds[t] = pred_intent[0].detach() @@ -75,6 +89,7 @@ def online_adaptation(dataloader, model, optimizer, params, device, temp_label_list += [y_traj] temp_data_list += [batch_data] if len(temp_pred_list) > adapt_step: + # maintains a buffer of length adapt_step containing the past adapt_step measurements for supervised adaptation temp_pred_list = temp_pred_list[1:] temp_label_list = temp_label_list[1:] temp_data_list = temp_data_list[1:] @@ -92,6 +107,8 @@ def online_adaptation(dataloader, model, optimizer, params, device, err = (Y_tau - Y_hat_tau).detach() curr_cost = err.pow(2).mean().cpu().numpy() update_epoch = 1 + + # IPython.embed() if 0 <= multiepoch_thresh[0] <= multiepoch_thresh[1]: if curr_cost< multiepoch_thresh[0]: update_epoch=1 @@ -132,11 +149,13 @@ def lbfgs_closure(): post_loss = (post_pred_traj - post_y_traj).detach().pow(2).mean().cpu().numpy().round(6) post_cost_list.append(post_loss) + cost_diff_list.append(full_loss-post_loss) if t % 10 == 0: print('finished pred {}, time:{}, partial cost before adapt:{}, partial cost after adapt:{}'.format(t, time() - t1, full_loss,post_loss)) t1 = time() + print("avg cost improvement (should be +): %f +/- %f" % (np.mean(cost_diff_list), np.std(cost_diff_list))) print('avg_cost:', np.mean(cost_list)) print('number of update epoch', cnt) return traj_hist, traj_preds,traj_labels, intent_preds, intent_labels, pred_start_pos