Skip to content

Commit

Permalink
Merge pull request #3 from h2r/samp_eff
Browse files Browse the repository at this point in the history
merge Samp_eff branch into main
  • Loading branch information
ahmedjaafar6 authored Sep 13, 2024
2 parents 99920c3 + 614ba11 commit 70d2e25
Show file tree
Hide file tree
Showing 76 changed files with 726 additions and 2,349 deletions.
57 changes: 55 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,57 @@ __pycache__/
/models/main_models/alfred/exp/*
!/models/main_models/alfred/exp/.gitkeep
/models/main_models/alfred/data/feats_discrete_relative_foldz/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_1b/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_1/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_2/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_2b/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_3/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_3b/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_4/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_4b/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_5/*
/models/main_models/alfred/data/feats_discrete_relative_high_scene_low_num_5b/*
/models/main_models/alfred/data/feats_discrete_relative_low_scene_high_num_1/*
/models/main_models/alfred/data/feats_discrete_relative_low_scene_high_num_2/*
/models/main_models/alfred/data/feats_discrete_relative_low_scene_high_num_3/*
/models/main_models/alfred/data/feats_discrete_relative_low_scene_high_num_4/*
/models/main_models/alfred/data/feats_discrete_relative_low_scene_high_num_5/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_high_1/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_high_2/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_high_3/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_high_4/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_high_5/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_low_1/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_low_2/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_low_3/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_low_4/*
/models/main_models/alfred/data/feats_discrete_relative_task_div_low_5/*
/models/main_models/alfred/data/splits/split_keys_discrete_relative_foldz.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_1.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_2.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_3.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_4.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_5.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_1b.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_2b.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_3b.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_4b.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_high_scene_low_num_5b.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_low_scene_high_num_1.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_low_scene_high_num_2.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_low_scene_high_num_3.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_low_scene_high_num_4.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_low_scene_high_num_5.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_high_1.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_high_2.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_high_3.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_high_4.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_high_5.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_low_1.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_low_2.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_low_3.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_low_4.json
/models/main_models/alfred/data/splits/split_keys_discrete_relative_task_div_low_5.json
/models/main_models/alfred/data/vis_feats/*
!/models/main_models/alfred/data/vis_feats/.gitkeep
/dataset/*
Expand Down Expand Up @@ -126,6 +176,7 @@ venv/
ENV/
env.bak/
venv.bak/
test/

# Spyder project settings
.spyderproject
Expand All @@ -146,12 +197,14 @@ dmypy.json
.pyre/

# Extras
models/main_models/checkpoints/*
models/main_models/rt1/checkpoints/*
models/main_models/datasets/*
models/main_models/rt1/val_losses/*
models/main_models/wandb/
models/main_models/rt1_dataset/*
models/main_models/traj_rollouts/*
models/main_models/rt1/traj_rollouts/*
models/main_models/run_rt1_main.sh
models/main_models/rt1_ft_env
/modespot/
Trajectories/
sim_commands.npy
115 changes: 115 additions & 0 deletions cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.cluster import AgglomerativeClustering, DBSCAN
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
from matplotlib.patches import Ellipse
import numpy as np
import json
from collections import defaultdict
from sklearn.metrics import davies_bouldin_score
import h5py
from sklearn.metrics import silhouette_score


model = SentenceTransformer("all-mpnet-base-v2") # all-MiniLM-L6-v2, , all-distilroberta-v1, sentence-t5-base,all-MiniLM-L12-v2,all-mpnet-base-v2

READ = False

if READ:
path = "/users/ajaafar/data/shared/lanmp/sim_dataset.hdf5"
commands=[]
# Open the HDF5 file
with h5py.File(path, 'r') as hdf_file:
# Iterate through each trajectory group
for trajectory_name, trajectory_group in hdf_file.items():
# Iterate through each timestep group within the trajectory
for timestep_name, timestep_group in trajectory_group.items():
# Read and decode the JSON metadata
metadata = json.loads(timestep_group.attrs['metadata'])
commands.append(metadata['nl_command'])
break

np.save("sim_commands.npy", commands)
else:
commands = np.load('sim_commands.npy', allow_pickle=True).tolist()

# Convert the commands to embeddings
embeddings = model.encode(commands)

# Compute the cosine similarity matrix
# sim_mat = cosine_similarity(embeddings)
# print(sim_mat)

# Apply Agglomerative Clustering
clustering = AgglomerativeClustering(n_clusters=None, metric='cosine', linkage='average', distance_threshold=0.3)
clusters = clustering.fit_predict(embeddings)

# Calculate the silhouette score
silhouette_avg = silhouette_score(embeddings, clusters, metric='cosine')
print(f'Silhouette Score: {silhouette_avg}')

# Calculate the Davies-Bouldin index
db_index = davies_bouldin_score(embeddings, clusters)
print(f'Davies-Bouldin Index: {db_index}')

# Create a defaultdict with lists as default values
cluster_dict = defaultdict(list)

# Populate the dictionary
for string, cluster_id in zip(commands, clusters):
cluster_dict[int(cluster_id)].append(string)

cluster_dict = dict(cluster_dict)
print(f'num clusters: {len(cluster_dict.keys())}')

#save dict
# with open('cluster_dict.json', 'w') as f:
# json.dump(cluster_dict, f)

# Find the cluster with the longest list
sorted_clusters = sorted(cluster_dict, key=lambda k: len(cluster_dict[k]), reverse=True)

tot = 0
# for i in [0,1,2,3,4,5,6,7,8,9]: #low number of clusters #240
# for i in range(14, 106): #high number of clusters #238
for i in range(10,14): #test 46
print(f"{len(cluster_dict[sorted_clusters[i]])} elements.")
tot += len(cluster_dict[sorted_clusters[i]])

print(f"{tot} total")
breakpoint()

# Apply t-SNE for dimensionality reduction
reduced_embeddings = TSNE(n_components=2, metric='cosine', perplexity=175).fit_transform(embeddings)

# Plot the t-SNE results
plt.figure(figsize=(10, 8))
for cluster in np.unique(clusters):
cluster_points = reduced_embeddings[clusters == cluster]
plt.scatter(cluster_points[:, 0], cluster_points[:, 1], label=f'Cluster {cluster}')

# Calculate the ellipse for each cluster
if len(cluster_points) > 1: # Ellipse requires at least 2 points
cov = np.cov(cluster_points, rowvar=False)
mean = np.mean(cluster_points, axis=0)

# Eigen decomposition of covariance matrix
eigenvalues, eigenvectors = np.linalg.eigh(cov)
order = eigenvalues.argsort()[::-1]
eigenvalues, eigenvectors = eigenvalues[order], eigenvectors[:, order]

# Compute width, height and angle of ellipse
angle = np.degrees(np.arctan2(*eigenvectors[:, 0][::-1]))
width, height = 2 * np.sqrt(eigenvalues)

# Draw the ellipse
ellipse = Ellipse(xy=mean, width=width, height=height, angle=angle, edgecolor='black', facecolor='none', lw=2)
plt.gca().add_patch(ellipse)

plt.title('t-SNE with Cluster Ellipses')
plt.xlabel('t-SNE Dimension 1')
plt.ylabel('t-SNE Dimension 2')
plt.legend()
plt.grid(True)
plt.show()
1 change: 1 addition & 0 deletions models/main_models/alfred/cluster_dict.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions models/main_models/alfred/command_key_dict.json

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions models/main_models/alfred/data/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import progressbar
from vocab import Vocab
from model.seq2seq import Module as model
from models.utils.data_utils import split_data, env_folds, task_gen, div, remove_spaces_and_lower
from models.utils.data_utils import split_data, env_folds, task_gen, div, remove_spaces_and_lower, cluster
import h5py
import numpy as np

Expand Down Expand Up @@ -61,6 +61,8 @@ def preprocess_splits(self, splits, folds, div_runs):
train_keys, test_keys = task_gen(self.args.data)
elif self.args.splits_folds == 'div':
train_keys, test_keys = div(self.args.data, div_runs['train_envs'], div_runs['test_env'])
elif self.args.splits_folds == 'cluster':
train_keys, test_keys = cluster(self.args.data, low_div=self.args.low_div)
else:
train_keys, test_keys = env_folds(self.args.data, folds['train_envs'], folds['test_envs'])
split_keys_dict = {'train':train_keys, 'test':test_keys}
Expand Down Expand Up @@ -150,7 +152,7 @@ def find_min_max(self, state_body, state_ee):
self.max_vals[i] = actions[i]
if actions[i] < self.min_vals[i]:
self.min_vals[i] = actions[i]

def get_deltas(self, state_body, state_ee, next_state_body, next_state_ee):
state_body_delta = np.subtract(next_state_body, state_body)
state_ee_delta = np.subtract(next_state_ee, state_ee)
Expand Down Expand Up @@ -179,9 +181,9 @@ def process_actions(self, task, traj):
state_body = traj_json_dict['steps'][0]['state_body']
state_ee = traj_json_dict['steps'][0]['state_ee']
# action_high = traj_json_dict['steps'][0]['action']
# grasp_drop = self.grasp_drop['NoOP']
# up_down = self.up_down['NoOP']

# grasp_drop = self.grasp_drop['NoOP']
# up_down = self.up_down['NoOP']
# if action_high == 'PickupObject':
# grasp_drop = self.grasp_drop['PickupObject']
# elif action_high == 'ReleaseObject':
Expand Down Expand Up @@ -214,8 +216,8 @@ def process_actions(self, task, traj):
mode = self.mode['look']
elif action_high in ['PickupObject', 'ReleaseObject']:
mode = self.mode['ee']
grasp_drop = self.grasp_drop['NoOp']

grasp_drop = self.grasp_drop['NoOp']
up_down = self.up_down['NoOp']
base = self.base['NoOp']
arm = [0]*3 #noop index
Expand Down Expand Up @@ -245,9 +247,9 @@ def process_actions(self, task, traj):

if traj is None:
self.find_min_max(state_body, state_ee)

if not self.args.class_mode and traj is not None: #regression
# TODO normalization here
# TODO normalization here
traj['num']['action_low'].append(
{'state_body': state_body, 'state_ee': state_ee, 'grasp_drop': grasp_drop, 'up_down': up_down}
)
Expand All @@ -263,7 +265,7 @@ def get_indices():
if bin_indx == len(self.bins[i]):
bin_indx = len(self.bins[i])-1
final_action_indices.append(int(bin_indx-1)) #subtract since digitize returns 1-based indexing

#final_action_indices [mode, base_action, yaw, xee, yee, zee, grasp_drop, lookup_lookdown]
nonlocal rotate
nonlocal arm
Expand All @@ -280,8 +282,8 @@ def get_indices():
if i != len(traj_steps)-1:
get_indices()
else:
get_indices()
get_indices()

if traj is not None:
#append end/stop action index of bins
traj['num']['action_low'].append(
Expand Down
4 changes: 2 additions & 2 deletions models/main_models/alfred/data/splits/div_runs.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"train_envs": ["FloorPlan_Train8_1", "FloorPlan_Train1_3", "FloorPlan_Train5_1", "FloorPlan_Train12_3"] ,
"test_env": "FloorPlan_Train7_5"
"train_envs": ["FloorPlan_Train8_1", "FloorPlan_Train5_1,", "FloorPlan_Train12_3"],
"test_env": "FloorPlan_Train1_3"
}
9 changes: 5 additions & 4 deletions models/main_models/alfred/models/train/train_seq2seq.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
parser.add_argument('--splits', help='json file containing train/val/test splits', default='data/splits/splits.json')
parser.add_argument('--folds', help='json file containing train/test env folds', default='data/splits/env_folds.json')
parser.add_argument('--div_runs', help='json file containing train/test env div', default='data/splits/div_runs.json')
parser.add_argument('--splits_folds', help='splits or folds', default='div')
parser.add_argument('--splits_folds', help='splits or folds', default='splits')
parser.add_argument('--low_div', help='low diversity if true, else high', action='store_true')
parser.add_argument('--split_keys', help='json file containing split trajectories', default='data/splits/split_keys.json')
parser.add_argument('--preprocess', help='store preprocessed data to json files', action='store_true')
parser.add_argument('--save_every_epoch', help='save model after every epoch (warning: consumes a lot of space)', action='store_true')
Expand All @@ -40,7 +41,7 @@


# hyper parameters
parser.add_argument('--batch', help='batch size', default=8, type=int) #the number of trajs in a batch.
parser.add_argument('--batch', help='batch size', default=8, type=int) #the number of trajs in a batch.
parser.add_argument('--epoch', help='number of epochs', default=20, type=int)
parser.add_argument('--lr', help='optimizer learning rate', default=1e-4, type=float)
parser.add_argument('--decay_epoch', help='num epoch to adjust learning rate', default=10, type=int)
Expand Down Expand Up @@ -74,7 +75,7 @@
# debugging
parser.add_argument('--fast_epoch', help='fast epoch during debugging', action='store_true')
parser.add_argument('--dataset_fraction', help='use fraction of the dataset for debugging (0 indicates full size)', default=0, type=float)

# args and init
args = parser.parse_args()
args.dout = args.dout.format(**vars(args))
Expand All @@ -100,7 +101,7 @@
# preprocess and save
if args.preprocess:
print("\nPreprocessing dataset and saving to %s folders ... This will take a while. Do this once as required." % args.pp_folder)
dataset = Dataset(args, None)
dataset = Dataset(args, None)
dataset.preprocess_splits(splits, folds, div_runs)
vocab = torch.load(os.path.join(args.dout, "%s.vocab" % args.pp_folder))
else:
Expand Down
Loading

0 comments on commit 70d2e25

Please sign in to comment.