diff --git a/.gitignore b/.gitignore index 188d871..57d902a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.pyc .ipynb_checkpoints/ __pycache__/ +data/ \ No newline at end of file diff --git a/loader/data_loader.py b/loader/data_loader.py new file mode 100644 index 0000000..c04cd96 --- /dev/null +++ b/loader/data_loader.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import logging +from torch.utils.data import Dataset +import os +import scipy.io as sio +#from skimage.transform import resize +#from skimage.transform import rotate +from PIL import Image +import numpy as np +from scipy import optimize + +np.set_printoptions(threshold=np.inf, suppress=True) +import random +import copy +import math + + +class OffroadLoader(Dataset): + def __init__(self, grid_size, train=True, demo=None, datadir='/root/medirl/data/', pre_train=False, tangent=False, + more_kinematic=None): + assert grid_size % 2 == 0, "grid size must be even number" + self.grid_size = grid_size + if train: + self.data_dir = datadir + 'train_data/' + else: + self.data_dir = datadir + 'test_data/' + + if demo is not None: + self.data_dir = datadir + '/irl_data/' + demo + + items = os.listdir(self.data_dir) + self.data_list = [] + for item in items: + self.data_list.append(self.data_dir + '/' + item) + + #self.data_normalization = sio.loadmat(datadir + '/irl_data/train-data-mean-std.mat') + self.pre_train = pre_train + + # kinematic related feature + self.center_idx = self.grid_size / 2 + + + def __getitem__(self, index): + data_mat = sio.loadmat(self.data_list[index]) + feat, robot_state_feat, past_traj, future_traj = data_mat['feat'].copy(), data_mat['robot_state_data'], data_mat['past_traj'], data_mat['future_traj'] + # visualize rgb + feat = np.vstack((feat, np.expand_dims(feat[2], axis=0))) + feat = np.vstack((feat, np.expand_dims(feat[3], axis=0))) + feat = np.vstack((feat, np.expand_dims(feat[4], axis=0))) + # normalize features locally + for i in range(5): + feat[i] = (feat[i] - np.mean(feat[i])) / np.std(feat[i]) + # normalize robot state feature locally + robot_state_feat = (robot_state_feat - np.mean(robot_state_feat, axis=0, keepdims=True)) / np.std(robot_state_feat, axis=0, keepdims=True) + + + if self.pre_train: + target = data_mat['feat'][1].copy() # copy the variance layer first + target[target < 0.5] = 0.0 + target[target >= 0.5] = -1.0 + return feat, target + + future_traj = self.auto_pad_future(future_traj[:, :2]) + past_traj = self.auto_pad_past(past_traj[:, :2]) + + return feat, past_traj, future_traj, robot_state_feat + + def __len__(self): + return len(self.data_list) + + def auto_pad_past(self, traj): + """ + add padding (NAN) to traj to keep traj length fixed. + traj shape needs to be fixed in order to use batch sampling + :param traj: numpy array. (traj_len, 2) + :return: + """ + fixed_len = self.grid_size + if traj.shape[0] >= self.grid_size: + traj = traj[traj.shape[0]-self.grid_size:, :] + #raise ValueError('traj length {} must be less than grid_size {}'.format(traj.shape[0], self.grid_size)) + pad_len = self.grid_size - traj.shape[0] + pad_array = np.full((pad_len, 2), np.nan) + output = np.vstack((traj, pad_array)) + return output + + def auto_pad_future(self, traj): + """ + add padding (NAN) to traj to keep traj length fixed. + traj shape needs to be fixed in order to use batch sampling + :param traj: numpy array. (traj_len, 2) + :return: + """ + fixed_len = self.grid_size + if traj.shape[0] >= self.grid_size: + traj = traj[:self.grid_size, :] + #raise ValueError('traj length {} must be less than grid_size {}'.format(traj.shape[0], self.grid_size)) + pad_len = self.grid_size - traj.shape[0] + pad_array = np.full((pad_len, 2), np.nan) + output = np.vstack((traj, pad_array)) + return output \ No newline at end of file diff --git a/loader/single_data_loader.py b/loader/single_data_loader.py new file mode 100644 index 0000000..b866b07 --- /dev/null +++ b/loader/single_data_loader.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import logging +from torch.utils.data import Dataset +import os +import scipy.io as sio +#from skimage.transform import resize +#from skimage.transform import rotate +from PIL import Image +import numpy as np +from scipy import optimize +from IPython import embed +np.set_printoptions(threshold=np.inf, suppress=True) +import random +import copy +import math + + +class OffroadLoader(Dataset): + def __init__(self, grid_size, train=True, demo=None, datadir='/root/medirl/data/', pre_train=False, tangent=False, + more_kinematic=None): + assert grid_size % 2 == 0, "grid size must be even number" + self.grid_size = grid_size + self.image_fol = datadir + "demo_0" + #self.data_normalization = sio.loadmat(datadir + '/irl_data/train-data-mean-std.mat') + self.pre_train = pre_train + + # kinematic related feature + self.center_idx = self.grid_size / 2 + + + def __getitem__(self, index): + goal_sink_feat = np.array(Image.open(self.image_fol+"/goal_sink.png")) + semantic_img_feat = np.array(Image.open(self.image_fol+"/semantic_img.png"))[:,:,0:3] + with open(self.image_fol+"/trajectory.npy", 'rb') as f: + traj = np.load(f) + # visualize rgb + feat = np.concatenate((goal_sink_feat, semantic_img_feat), axis = 2).T + # normalize features locally + for i in range(6): + feat[i] = (feat[i] - np.mean(feat[i])) / np.std(feat[i]) + + + + + return feat, traj + + def __len__(self): + return len(self.data_list) + + def auto_pad_past(self, traj): + """ + add padding (NAN) to traj to keep traj length fixed. + traj shape needs to be fixed in order to use batch sampling + :param traj: numpy array. (traj_len, 2) + :return: + """ + fixed_len = self.grid_size + if traj.shape[0] >= self.grid_size: + traj = traj[traj.shape[0]-self.grid_size:, :] + #raise ValueError('traj length {} must be less than grid_size {}'.format(traj.shape[0], self.grid_size)) + pad_len = self.grid_size - traj.shape[0] + pad_array = np.full((pad_len, 2), np.nan) + output = np.vstack((traj, pad_array)) + return output + + def auto_pad_future(self, traj): + """ + add padding (NAN) to traj to keep traj length fixed. + traj shape needs to be fixed in order to use batch sampling + :param traj: numpy array. (traj_len, 2) + :return: + """ + fixed_len = self.grid_size + if traj.shape[0] >= self.grid_size: + traj = traj[:self.grid_size, :] + #raise ValueError('traj length {} must be less than grid_size {}'.format(traj.shape[0], self.grid_size)) + pad_len = self.grid_size - traj.shape[0] + pad_array = np.full((pad_len, 2), np.nan) + output = np.vstack((traj, pad_array)) + return output \ No newline at end of file diff --git a/mdp/offroad_grid.py b/mdp/offroad_grid.py index e8db667..99bd191 100644 --- a/mdp/offroad_grid.py +++ b/mdp/offroad_grid.py @@ -31,9 +31,9 @@ class OffroadGrid(object): """ def __init__(self, grid_size, discount): - self.actions = ((0, 1), (1, 0), (0, -1), (-1, 0)) # 0->RIGHT, 1->UP, 2->LEFT, 3->DOWN + # self.actions = ((0, 1), (1, 0), (0, -1), (-1, 0)) # 0->RIGHT, 1->UP, 2->LEFT, 3->DOWN # 0->RIGHT, 1->RIGHT-UP, 2->UP, 3->LEFT-UP, 4->LEFT, 5->LEFT-DOWN, 6->DOWN, 7-RIGHT-DOWN - # self.actions = ((0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)) + self.actions = ((0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)) self.n_actions = len(self.actions) self.n_states = grid_size ** 2 self.grid_size = grid_size @@ -61,7 +61,7 @@ def load_feat(self, feat): feat_vector = feat[:, x, y] self.feat_mat.append(feat_vector) - self.feat_mat = np.stack(self.feat_mat, axis=0) + self.feat_mat = feat def find_feat_expect(self, traj): """ diff --git a/mdp/test_offroad_grid.py b/mdp/test_offroad_grid.py index 14ddc1e..793cf16 100644 --- a/mdp/test_offroad_grid.py +++ b/mdp/test_offroad_grid.py @@ -1,10 +1,11 @@ import unittest import visdom -from irl.mdp.offroad_grid import OffroadGrid +import sys +sys.path.append("/root/medirl/") +from mdp.offroad_grid import OffroadGrid import numpy as np import numpy.random as rn -from loader.offroad_loader import OffroadLoader, get_max_min_feature, get_mean_feature - +from loader.single_data_loader import OffroadLoader def make_random_model(): grid_size = rn.randint(2, 15) @@ -18,11 +19,11 @@ def __init__(self, *args, **kwargs): self.vis = visdom.Visdom() def test_main(self): - grid_size = 30 + grid_size = 32 discount = 0.9 model = OffroadGrid(grid_size, discount) loader = OffroadLoader(grid_size=grid_size) - feat, traj = loader[1] + feat, traj = loader[0] print(traj) traj[np.isnan(traj)] = 0.0 # replace nan as 0.0 self.vis.heatmap(X=traj, opts=dict(colormap='Electric', title='height_mean')) diff --git a/requirements.txt b/requirements.txt index 5ef45bc..61bc785 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,10 @@ -- jupyter -- cython --- numpy=1.15.4 +-- numpy==1.15.4 -- numba==0.50.1 --- matplotlib=2.1.2 --- scipy=1.0.0 +-- matplotlib==2.1.2 +-- scipy==1.0.0 -- seaborn==0.9.0 --- tqdm=4.19.4 --- visdom==0.1.8.3 \ No newline at end of file +-- tqdm==4.19.4 +-- visdom==0.1.8.3 +-- scikit-image==0.14.1 \ No newline at end of file