| | |
| |
|
| | import os |
| | import matplotlib.pyplot as plt |
| | import numpy as np |
| | import json |
| | import seaborn as sns; sns.set() |
| | import glob2 |
| | import argparse |
| |
|
| |
|
| | def smooth_reward_curve(x, y): |
| | halfwidth = int(np.ceil(len(x) / 60)) |
| | k = halfwidth |
| | xsmoo = x |
| | ysmoo = np.convolve(y, np.ones(2 * k + 1), mode='same') / np.convolve(np.ones_like(y), np.ones(2 * k + 1), |
| | mode='same') |
| | return xsmoo, ysmoo |
| |
|
| |
|
| | def load_results(file): |
| | if not os.path.exists(file): |
| | return None |
| | with open(file, 'r') as f: |
| | lines = [line for line in f] |
| | if len(lines) < 2: |
| | return None |
| | keys = [name.strip() for name in lines[0].split(',')] |
| | data = np.genfromtxt(file, delimiter=',', skip_header=1, filling_values=0.) |
| | if data.ndim == 1: |
| | data = data.reshape(1, -1) |
| | assert data.ndim == 2 |
| | assert data.shape[-1] == len(keys) |
| | result = {} |
| | for idx, key in enumerate(keys): |
| | result[key] = data[:, idx] |
| | return result |
| |
|
| |
|
| | def pad(xs, value=np.nan): |
| | maxlen = np.max([len(x) for x in xs]) |
| |
|
| | padded_xs = [] |
| | for x in xs: |
| | if x.shape[0] >= maxlen: |
| | padded_xs.append(x) |
| |
|
| | padding = np.ones((maxlen - x.shape[0],) + x.shape[1:]) * value |
| | x_padded = np.concatenate([x, padding], axis=0) |
| | assert x_padded.shape[1:] == x.shape[1:] |
| | assert x_padded.shape[0] == maxlen |
| | padded_xs.append(x_padded) |
| | return np.array(padded_xs) |
| |
|
| |
|
| | parser = argparse.ArgumentParser() |
| | parser.add_argument('dir', type=str) |
| | parser.add_argument('--smooth', type=int, default=1) |
| | args = parser.parse_args() |
| |
|
| | |
| | data = {} |
| | paths = [os.path.abspath(os.path.join(path, '..')) for path in glob2.glob(os.path.join(args.dir, '**', 'progress.csv'))] |
| | for curr_path in paths: |
| | if not os.path.isdir(curr_path): |
| | continue |
| | results = load_results(os.path.join(curr_path, 'progress.csv')) |
| | if not results: |
| | print('skipping {}'.format(curr_path)) |
| | continue |
| | print('loading {} ({})'.format(curr_path, len(results['epoch']))) |
| | with open(os.path.join(curr_path, 'params.json'), 'r') as f: |
| | params = json.load(f) |
| |
|
| | success_rate = np.array(results['test/success_rate']) |
| | epoch = np.array(results['epoch']) + 1 |
| | env_id = params['env_name'] |
| | replay_strategy = params['replay_strategy'] |
| |
|
| | if replay_strategy == 'future': |
| | config = 'her' |
| | else: |
| | config = 'ddpg' |
| | if 'Dense' in env_id: |
| | config += '-dense' |
| | else: |
| | config += '-sparse' |
| | env_id = env_id.replace('Dense', '') |
| |
|
| | |
| | assert success_rate.shape == epoch.shape |
| | x = epoch |
| | y = success_rate |
| | if args.smooth: |
| | x, y = smooth_reward_curve(epoch, success_rate) |
| | assert x.shape == y.shape |
| |
|
| | if env_id not in data: |
| | data[env_id] = {} |
| | if config not in data[env_id]: |
| | data[env_id][config] = [] |
| | data[env_id][config].append((x, y)) |
| |
|
| | |
| | for env_id in sorted(data.keys()): |
| | print('exporting {}'.format(env_id)) |
| | plt.clf() |
| |
|
| | for config in sorted(data[env_id].keys()): |
| | xs, ys = zip(*data[env_id][config]) |
| | xs, ys = pad(xs), pad(ys) |
| | assert xs.shape == ys.shape |
| |
|
| | plt.plot(xs[0], np.nanmedian(ys, axis=0), label=config) |
| | plt.fill_between(xs[0], np.nanpercentile(ys, 25, axis=0), np.nanpercentile(ys, 75, axis=0), alpha=0.25) |
| | plt.title(env_id) |
| | plt.xlabel('Epoch') |
| | plt.ylabel('Median Success Rate') |
| | plt.legend() |
| | plt.savefig(os.path.join(args.dir, 'fig_{}.png'.format(env_id))) |
| |
|