* joshim5 changes (width and height to WarpFrame wrapper) * match network output with action distribution via a linear layer only if necessary (#167) * support color vs. grayscale option in WarpFrame wrapper (#166) * support color vs. grayscale option in WarpFrame wrapper * Support color in other wrappers * Updated per Peters suggestions * fixing test failures * ppo2 with microbatches (#168) * pass microbatch_size to the model during construction * microbatch fixes and test (#169) * microbatch fixes and test * tiny cleanup * added assertions to the test * vpg-related fix * Peterz joshim5 subclass ppo2 model (#170) * microbatch fixes and test * tiny cleanup * added assertions to the test * vpg-related fix * subclassing the model to make microbatched version of model WIP * made microbatched model a subclass of ppo2 Model * flake8 complaint * mpi-less ppo2 (resolving merge conflict) * flake8 and mpi4py imports in ppo2/model.py * more un-mpying * merge master * updates to the benchmark viewer code + autopep8 (#184) * viz docs and syntactic sugar wip * update viewer yaml to use persistent volume claims * move plot_util to baselines.common, update links * use 1Tb hard drive for results viewer * small updates to benchmark vizualizer code * autopep8 * autopep8 * any folder can be a benchmark * massage games image a little bit * fixed --preload option in app.py * remove preload from run_viewer.sh * remove pdb breakpoints * update bench-viewer.yaml * fixed bug (#185) * fixed bug it's wrong to do the else statement, because no other nodes would start. * changed the fix slightly * Refactor her phase 1 (#194) * add monitor to the rollout envs in her RUN BENCHMARKS her * Slice -> Slide in her benchmarks RUN BENCHMARKS her * run her benchmark for 200 epochs * dummy commit to RUN BENCHMARKS her * her benchmark for 500 epochs RUN BENCHMARKS her * add num_timesteps to her benchmark to be compatible with viewer RUN BENCHMARKS her * add num_timesteps to her benchmark to be compatible with viewer RUN BENCHMARKS her * add num_timesteps to her benchmark to be compatible with viewer RUN BENCHMARKS her * disable saving of policies in her benchmark RUN BENCHMARKS her * run fetch benchmarks with ppo2 and ddpg RUN BENCHMARKS Fetch * run fetch benchmarks with ppo2 and ddpg RUN BENCHMARKS Fetch * launcher refactor wip * wip * her works on FetchReach * her runner refactor RUN BENCHMARKS Fetch1M * unit test for her * fixing warnings in mpi_average in her, skip test_fetchreach if mujoco is not present * pickle-based serialization in her * remove extra import from subproc_vec_env.py * investigating differences in rollout.py * try with old rollout code RUN BENCHMARKS her * temporarily use DummyVecEnv in cmd_util.py RUN BENCHMARKS her * dummy commit to RUN BENCHMARKS her * set info_values in rollout worker in her RUN BENCHMARKS her * bug in rollout_new.py RUN BENCHMARKS her * fixed bug in rollout_new.py RUN BENCHMARKS her * do not use last step because vecenv calls reset and returns obs after reset RUN BENCHMARKS her * updated buffer sizes RUN BENCHMARKS her * fixed loading/saving via joblib * dust off learning from demonstrations in HER, docs, refactor * add deprecation notice on her play and plot files * address comments by Matthias * 1.5 months of codegen changes (#196) * play with resnet * feed_dict version * coinrun prob and more stats * fixes to get_choices_specs & hp search * minor prob fixes * minor fixes * minor * alternative version of rl_algo stuff * pylint fixes * fix bugs, move node_filters to soup * changed how get_algo works * change how get_algo works, probably broke all tests * continue previous refactor * get eval_agent running again * fixing tests * fix tests * fix more tests * clean up cma stuff * fix experiment * minor changes to eval_agent to make ppo_metal use gpu * make dict space work * modify mac makefile to use conda * recurrent layers * play with bn and resnets * minor hp changes * minor * got rid of use_fb argument and jtft (joint-train-fine-tune) functionality built test phase directly into AlgoProb * make new rl algos generateable * pylint; start fixing tests * fixing tests * more test fixes * pylint * fix search * work on search * hack around infinite loop caused by scan * algo search fixes * misc changes for search expt * enable annealing, overriding options of Op * pylint fixes * identity op * achieve use_last_output through masking so it automatically works in other distributions * fix tests * minor * discrete * use_last_output to be just a preference, not a hard constraint * pred delay, pruning * require nontrivial inputs * aliases for get_sm * add probname to probs * fixes * small fixes * fix tests * fix tests * fix tests * minor * test scripts * dualgru network improvements * minor * work on mysterious bugs * rcall gpu-usage command for kube * use cache dir that’s not in code folder, so that it doesn’t get removed by rcall code rsync * add power mode to gpu usage * make sure train/test actually different * remove VR for now * minor fixes * simplify soln_db * minor * big refactor of mpi eda * improve mpieda for multitask * - get rid of timelimit hack - add __del__ to cleanup SubprocVecEnv * get multitask working better * fixes * working on atari, various * annotate ops with whether they’re parametrized * minor * gym version * rand atari prob * minor * SolnDb bugfix and name change * pyspy script * switch conv layers * fix roboschool/bullet3 * nenvs assertion * fix rand atari * get rid of blanket exception catching fix soln_db bug * fix rand_atari * dynamic routing as cmdline arg * slight modifications to test_mpi_map and pyspy-all * max_tries argument for run_until_successs * dedup option in train_mle * simplify soln_db * increase atari horizon for 1 experiment * start implementing reward increment * ent multiplier * create cc dsl other misc fixes * cc ops * q_func -> qs in rl_algos_cc.py * fix PredictDistr * rl_ops_cc fixes, MakeAction op * augment algo agent to support cc stuff * work on ddpg experiments * fix blocking temporarily change logger * allow layer scaling * pylint fixes * spawn_method * isolate ddpg hacks * improve pruning * use spawn for subproc * remove use of python -c in rcall * fix pylint warning * fix static * maybe fix local backend * switch to DummyVecEnv * making some fixes via pylint * pylint fixes * fixing tests * fix tests * fix tests * write scaffolding for SSL in Codegen * logger fix * fix error * add EMA op to sl_ops * save many changes * save * add upsampler * add sl ops, enhance state machine * get ssl search working — some gross hacking * fix session/graph issue * fix importing * work on mle * - scale embeddings in gru model - better exception handling in sl_prob - use emas for test/val - use non-contrib batch_norm layer * improve logging * option to average before dumping in logger * default arguments, etc * new ddpg and identity test * concat fix * minor * move realistic ssl stuff to third-party (underscore to dash) * fixes * remove realistic_ssl_evaluation * pylint fixes * use gym master * try again * pass around args without gin * fix tests * separate line to install gym * rename failing tests that should be ignored * add data aug * ssl improvements * use fixed time limit * try to fix baselines tests * add score_floor, max_walltime, fiddle with lr decay * realistic_ssl * autopep8 * various ssl - enable blocking grad for simplification - kl - multiple final prediction * fix pruning * misc ssl stuff * bring back linear schedule, don’t use allgather for collecting stats (i’ve been getting nondeterministic errors from the old code) * save/load weights in SSL, big stepsize * cleanup SslProb * fix * get rid of kl coef * fix simplification, lower lr * search over hps * minor fixes * minor * static analysis * move files and rename things for improved consistency. still broken, and just saving before making nontrivial changes * various * make tests pass * move coinrun_train to codegen since it depends on codegen * fixes * pylint fixes * improve tests fix some things * improve tests * lint * fix up db_info.py, tests * mostly restore master version of envs directory, except for makefile changes * fix tests * improve printing * minor fixes * fix fixmes * pruning test * fixes * lint * write new test that makes tf graphs of random algos; fix some bugs it caught * add —delete flag to rcall upload-code command * lint * get cifar10 lazily for testing purposes * disable codegen ci tests for now * clean up rl_ops * rename spec classes * td3 with identity test * identity tests without gin files * remove gin.configurable from AlgoAgent * comments about reduction in rl_ops_cc * address @pzhokhov comments * fix tests * more linting * better tests * clean up filtering a bit * fix concat * delayed logger configuration (#208) * delayed logger configuration * fix typo * setters and getters for Logger.DEFAULT as well * do away with fancy property stuff - unable to get it to work with class level methods * grammar and spaces * spaces * use get_current function instead of reading Logger.CURRENT * autopep8 * disable mpi in subprocesses (#213) * lazy_mpi load * cleanups * more lazy mpi * don't pretend that class is a module, just use it as a class * mass-replace mpi4py imports * flake8 * fix previous lazy_mpi imports * silly recursion * try os.environ hack * better prefix test, work with mpich * restored MPI imports * removed commented import in test_with_mpi * restored codegen from master * remove lazy mpi * restored changes from rl-algs * remove extra files * address Chris' comments * use spawn for shmem vec env as well (#2) (#219) * lazy_mpi load * cleanups * more lazy mpi * don't pretend that class is a module, just use it as a class * mass-replace mpi4py imports * flake8 * fix previous lazy_mpi imports * silly recursion * try os.environ hack * better prefix test, work with mpich * restored MPI imports * removed commented import in test_with_mpi * restored codegen from master * remove lazy mpi * restored changes from rl-algs * remove extra files * port mpi fix to shmem vec env * increase the mpi test default timeout * change humanoid hyperparameters, get rid of clip_Frac annealing, as it's apparently dangerous * remove clip_frac schedule from ppo2 * more timesteps in humanoid run * whitespace + RUN BENCHMARKS * baselines: export vecenvs from folder (#221) * baselines: export vecenvs from folder * put missing function back in * add missing imports * more imports * longer mpi timeout? * make default logger configuration the same as call to logger.configure() (#222) * Vecenv refactor (#223) * update karl util * restore pvi flag * change rcall auto cpu behavior, move gin.configurable, add os.makedirs * vecenv refactor * aux buf index fix * add num aux obs * reset level with enter * restore high difficulty flag * bugfix * restore train_coinrun.py * tweaks * renaming * renaming * better arguments handling * more options * options cleanup * game data refactor * more options * args for train_procgen * add close handler to interactive base class * use debug build if debug=True, fix range on aux_obs * add ProcGenEnv to __init__.py, add missing imports to procgen.py * export RemoveDictWrapper and build, update train_procgen.py, move assets download into env creation and replace init_assets_and_build with just build * fix formatting issues * only call global init once * fix path in setup.py * revert part of makefile * ignore IDE files and folders * vec remove dict * export VecRemoveDictObs * remove RemoveDictWrapper * remove IDE files * move shared .h and .cpp files to common folder, update build to use those, dedupe env.cpp * fix missing header * try unified build function * remove old scripts dir * add comment on build * upload libenv with render fixes * tell qthreads to die when we unload the library * pyglet.app.run is garbage * static fixes * whoops * actually vsync is on * cleanup * cleanup * extern C for libenv interface * parse util rcall arg * high difficulty fix * game type enums * ProcGenEnv subclasses * game type cleanup * unrecognized key * unrecognized game type * parse util reorg * args management * typo fix * GinParser * arg tweaks * tweak * restore start_level/num_levels setting * fix create_procgen_env interface * build fix * procgen args in init signature * fix * build fix * fix logger usage in ppo_metal/run_retro * removed unnecessary OrderedDict requirement in subproc_vec_env * flake8 fix * allow for non-mpi tests * mpi test fixes * flake8; removed special logic for discrete spaces in dummy_vec_env * remove forked argument in front of tests - does not play nicely with subprocvecenv in spawned processes; analog of forked in ddpg/test_smoke * Everyrl initial commit & a few minor baselines changes (#226) * everyrl initial commit * add keep_buf argument to VecMonitor * logger changes: set_comm and fix to mpi_mean functionality * if filename not provided, don't create ResultsWriter * change variable syncing function to simplify its usage. now you should initialize from all mpi processes * everyrl coinrun changes * tf_distr changes, bugfix * get_one * bring back get_next to temporarily restore code * lint fixes * fix test * rename profile function * rename gaussian * fix coinrun training script * change random seeding to work with new gym version (#231) * change random seeding to work with new gym version * move seeding to seed() method * fix mnistenv * actually try some of the tests before pushing * more deterministic fixed seq * misc changes to vecenvs and run.py for benchmarks (#236) * misc changes to vecenvs and run.py for benchmarks * dont seed global gen * update more references to assert_venvs_equal * Rl19 (#232) * everyrl initial commit * add keep_buf argument to VecMonitor * logger changes: set_comm and fix to mpi_mean functionality * if filename not provided, don't create ResultsWriter * change variable syncing function to simplify its usage. now you should initialize from all mpi processes * everyrl coinrun changes * tf_distr changes, bugfix * get_one * bring back get_next to temporarily restore code * lint fixes * fix test * rename profile function * rename gaussian * fix coinrun training script * rl19 * remove everyrl dir which appeared in the merge for some reason * readme * fiddle with ddpg * make ddpg work * steps_total argument * gpu count * clean up hyperparams and shape math * logging + saving * configuration stuff * fixes, smoke tests * fix stats * make load_results return dicts -- easier to create the same kind of objects with some other mechanism for passing to downstream functions * benchmarks * fix tests * add dqn to tests, fix it * minor * turned annotated transformer (pytorch) into a script * more refactoring * jax stuff * cluster * minor * copy & paste alec code * sign error * add huber, rename some parameters, snapshotting off by default * remove jax stuff * minor * move maze env * minor * remove trailing spaces * remove trailing space * lint * fix test breakage due to gym update * rename function * move maze back to codegen * get recurrent ppo working * enable both lstm and gru * script to print table of benchmark results * various * fix dqn * add fixup initializer, remove lastrew * organize logging stats * fix silly bug * refactor models * fix mpi usage * check sync * minor * change vf coef, hps * clean up slicing in ppo * minor fixes * caching transformer * docstrings * xf fixes * get rid of 'B' and 'BT' arguments * minor * transformer example * remove output_kind from base class until we have a better idea how to use it * add comments, revert maze stuff * flake8 * codegen lint * fix codegen tests * responded to peter's comments * lint fixes * minor changes to baselines (#243) * minor changes to baselines * fix spaces reference * remove flake8 disable comments and fix import * okay maybe don't add spec to vec_env * Merge branch 'master' of github.com:openai/games the commit. * flake8 complaints in baselines/her * update dmlab30 env (#258) * codegen continuous control experiment pr (#256) * finish cherry-pick td3 test commit * removed graph simplification error ingore * merge delayed logger config * merge updated baselines logger * lazy_mpi load * cleanups * use lazy mpi imports in codegen * more lazy mpi * don't pretend that class is a module, just use it as a class * mass-replace mpi4py imports * flake8 * fix previous lazy_mpi imports * removed extra printouts from TdLayer op * silly recursion * running codegen cc experiment * wip * more wip * use actor is input for critic targets, instead of the action taken * batch size 100 * tweak update parameters * tweaking td3 runs * wip * use nenvs=2 for contcontrol (to be comparable with ppo_metal) * wip. Doubts about usefulness of actor in critic target * delayed actor in ActorLoss * score is average of last 100 * skip lack of losses or too many action distributions * 16 envs for contcontrol, replay buffer size equal to horizon (no point in making it longer) * syntax * microfixes * minifixes * run in process logic to bypass tensorflow freezes/failures (per Oleg's suggestion) * squash-merge master, resolve conflicts * remove erroneous file * restore normal MPI imports * move wrappers around a little bit * autopep8 * cleanups * cleanup mpi_eda, autopep8 * make activation function of action distribution customizable * cleanups; preparation for a pr * syntax * merge latest master, resolve conflicts * wrap MPI import with try/except * allow import of modules through env id im baselines cmd_util * flake8 complaints * only wrap box action spaces with ClipActionsWrapper * flake8 * fixes to algo_prob according to Oleg's suggestions * use apply_without_scope flag in ActorLoss * remove extra line in algo/core.py * Rl19 metalearning (#261) * rl19 metalearning and dict obs * master merge arch fix * lint fixes * view fixes * load vars tweaks * user config cleanup * documentation and revisions * pass train comm to rl19 * cleanup * Symshapes - gives codegen ability to evaluate same algo on envs with different ob/ac shapes (#262) * finish cherry-pick td3 test commit * removed graph simplification error ingore * merge delayed logger config * merge updated baselines logger * lazy_mpi load * cleanups * use lazy mpi imports in codegen * more lazy mpi * don't pretend that class is a module, just use it as a class * mass-replace mpi4py imports * flake8 * fix previous lazy_mpi imports * removed extra printouts from TdLayer op * silly recursion * running codegen cc experiment * wip * more wip * use actor is input for critic targets, instead of the action taken * batch size 100 * tweak update parameters * tweaking td3 runs * wip * use nenvs=2 for contcontrol (to be comparable with ppo_metal) * wip. Doubts about usefulness of actor in critic target * delayed actor in ActorLoss * score is average of last 100 * skip lack of losses or too many action distributions * 16 envs for contcontrol, replay buffer size equal to horizon (no point in making it longer) * syntax * microfixes * minifixes * run in process logic to bypass tensorflow freezes/failures (per Oleg's suggestion) * random physics for mujoco * random parts sizes with range 0.4 * add notebook with results into x/peterz * variations of ant * roboschool use gym.make kwargs * use float as lowest score after rank transform * rcall from master * wip * re-enable dynamic routing * wip * squash-merge master, resolve conflicts * remove erroneous file * restore normal MPI imports * move wrappers around a little bit * autopep8 * cleanups * cleanup mpi_eda, autopep8 * make activation function of action distribution customizable * cleanups; preparation for a pr * syntax * merge latest master, resolve conflicts * wrap MPI import with try/except * allow import of modules through env id im baselines cmd_util * flake8 complaints * only wrap box action spaces with ClipActionsWrapper * flake8 * fixes to algo_prob according to Oleg's suggestions * use apply_without_scope flag in ActorLoss * remove extra line in algo/core.py * multi-task support * autopep8 * symbolic suffix-shapes (not B,T yet) * test_with_mpi -> with_mpi rename * remove extra blank lines in algo/core * remove extra blank lines in algo/core * remove more blank lines * symbolify shapes in existing algorithms * minor output changes * cleaning up merge conflicts * cleaning up merge conflicts * cleaning up more merge conflicts * restore mpi_map.py from master * remove tensorflow dependency from VecEnv * make tests use single-threaded session for determinism of KfacOptimizer (#298) * make tests use single-threaded session for determinism of KfacOptimizer * updated comment in kfac.py * remove unused sess_config * add score calculator wrapper, forward property lookups on vecenv wrap… (#300) * add score calculator wrapper, forward property lookups on vecenv wrapper, misc cleanup * tests * pylint * fix vec monitor infos * Workbench (#303) * begin workbench * cleanup * begin procgen config integration * arg tweaks * more args * parameter saving * begin procgen enjoy * tweaks * more workbench * more args sync/restore * cleanup * merge in master * rework args priority * more workbench * more loggign * impala cnn * impala lstm * tweak * tweaks * rl19 time logging * misc fixes * faster pipeline * update local.py * sess and log config tweaks * num processes * logging tweaks * difficulty reward wrapper * logging fixes * gin tweaks * tweak * fix * task id * param loading * more variable loading * entrypoint * tweak * ksync * restore lstm * begin rl19 support * tweak * rl19 rnn * more rl19 integration * fix * cleanup * restore rl19 rnn * cleanup * cleanup * wrappers.get_log_info * cleanup * cleanup * directory cleanup * logging, num_experiments * fixes * cleanup * gin fixes * fix local max gpu * resid nx * num machines and download params * rename * cleanup * create workbench * more reorg * fix * more logging wrappers * lint fix * restore train procgen * restore train procgen * pylint fix * better wrapping * config sweep * args sweep * test workers * mpi_weight * train test comm and high difficulty fix * enjoy show returns * removing gin, procgen_parser * removing gin * procgen args * config fixes * cleanup * cleanup * procgen args fix * fix * rcall syncing * lint * rename mpi_weight * use username for sync * fixes * microbatch fix * Grad clipping in MpiAdamOptimizer, transformer changes (#304) * transformer mnist experiments * version that only builds one model * work on inverted mnist * Add grad clipping to MpiAdamOptimizer * various * transformer changes, loading * get rid of soft labels * transformer baseline * minor * experiments involving all possible training sets * vary training * minor * get ready for fine-tuning expers * lint * minor * Add jrl19 as backend for workbench (#324) enable jrl in workbench minor logger changes * extra functionality in baselines.common.plot_util (#310) * get plot_util from mt_experiments branch * add labels * unit tests for plot_util * Fixed sequence env minor (#333) minor changes to FixedSequenceEnv to allow full score * fix tests (#335) * Procgen Benchmark Updates (#328) * directory cleanup * logging, num_experiments * fixes * cleanup * gin fixes * fix local max gpu * resid nx * tweak * num machines and download params * rename * cleanup * create workbench * more reorg * fix * more logging wrappers * lint fix * restore train procgen * restore train procgen * pylint fix * better wrapping * whackamole walls * config sweep * tweak * args sweep * tweak * test workers * mpi_weight * train test comm and high difficulty fix * enjoy show returns * better joint training * tweak * Add —update to args and add gin-config to requirements.txt * add username to download_file * removing gin, procgen_parser * removing gin * procgen args * config fixes * cleanup * cleanup * procgen args fix * fix * rcall syncing * lint * rename mpi_weight * begin composable game * more composable game * tweak * background alpha * use username for sync * fixes * microbatch fix * lure composable game * merge * proc trans update * proc trans update (#307) * finetuning experiment * Change is_local to use `use_rcall` and fix error of `enjoy.py` with multiple ends * graphing help * add --local * change args_dict['env_name'] to ENV_NAME * finetune experiments * tweak * tweak * reorg wrappers, remove is_local * workdir/local fixes * move finetune experiments * default dir and graphing * more graphing * fix * pooled syncing * tweaks * dir fix * tweak * wrapper mpi fix * wind and turrets * composability cleanup * radius cleanup * composable reorg * laser gates * composable tweaks * soft walls * tweak * begin swamp * more swamp * more swamp * fix * hidden mines * use maze layout * tweak * laser gate tweaks * tweaks * tweaks * lure/propel updates * composable midnight * composable coinmaze * composability difficulty * tweak * add step to save_params * composable offsets * composable boxpush * composable combiner * tweak * tweak * always choose correct number of mechanics * fix * rcall local fix * add steps when dump and save parmas * loading rank 1,2,3.. error fix * add experiments.py * fix loading latest weight with no -rest * support more complex run_id and add more examples * fix typo * move post_run_id into experiments.py * add hp_search example * error fix * joint experiments in progress * joint hp finished * typo * error fix * edit experiments * Save experiments set up in code and save weights per step (#319) * add step to save_params * add steps when dump and save parmas * loading rank 1,2,3.. error fix * add experiments.py * fix loading latest weight with no -rest * support more complex run_id and add more examples * fix typo * move post_run_id into experiments.py * add hp_search example * error fix * joint experiments in progress * joint hp finished * typo * error fix * edit experiments * tweaks * graph exp WIP * depth tweaks * move save_all * fix * restore_dir name * restore depth * choose max mechanics * use override mode * tweak frogger * lstm default * fix * patience is composable * hunter is composable * fixed asset seed cleanup * minesweeper is composable * eggcatch is composable * tweak * applesort is composable * chaser game * begin lighter * lighter game * tractor game * boxgather game * plumber game * hitcher game * doorbell game * lawnmower game * connecter game * cannonaim * outrun game * encircle game * spinner game * tweak * tweak * detonator game * driller * driller * mixer * conveyor * conveyor game * joint pcg experiments * fixes * pcg sweep experiment * cannonaim fix * combiner fix * store save time * laseraim fix * lightup fix * detonator tweaks * detonator fixes * driller fix * lawnmower calibration * spinner calibration * propel fix * train experiment * print load time * system independent hashing * remove gin configurable * task ids fix * test_pcg experiment * connecter dense reward * hard_pcg * num train comms * mpi splits envs * tweaks * tweaks * graph tweaks * graph tweaks * lint fix * fix tests * load bugfix * difficulty timeout tweak * tweaks * more graphing * graph tweaks * tweak * download file fix * pcg train envs list * cleanup * tweak * manually name impala layers * tweak * expect fps * backend arg * args tweak * workbench cleanup * move graph files * workbench cleanup * split env name by comma * workbench cleanup * ema graph * remove Dict * use tf.io.gfile * comments for auto-killing jobs * lint fix * write latest file when not saving all and load it when step=None * ci/runtests.sh - pass all folders to pytest (#342) * ci/runtests.sh - pass all folders to pytest * mpi_optimizer_test precision 1e-4 * fixes to tests * search for tests in the entire jax folder, also remove unnecessary humor * delete unnecessary stuff (#338) * Add initializer for process-level setup in SubprocVecEnv (#276) * Add initializer for process-level setup in SubprocVecEnv Use case: run logger.configure() in each subprocess * Add option to force dummy vec env * Procgen fixes (#352) * tweak * documentation * rely on log_comm, remove mpi averaging from wrappers * pass comm for ppo2 initialization * ppo2 logging * experiment tweaks * auto launch tensorboard when using local backend * graph tweaks * pass caller to config * configure logger and tensorboard * make parent dir if necessary * parentdir tweak * JRL PPO test with delayed identity env (#355) * add a custom delay to identity_env * min reward 0.8 in delayed identity test * seed the tests, perfect score on delayed_identity_test * delay=1 in delayed_identity_test * flake8 complaints * increased number of steps in fixed_seq_test * seed identity tests to ensure reproducibility * docstrings * (onp, np) -> (np, jp), switch jax code to use mark_slow decorator (#363) switch to mark_slow decorator * fix tests - add matplotlib to setup_requires, put mpi4py import in try-except * test fixes
435 lines
18 KiB
Python
435 lines
18 KiB
Python
import matplotlib.pyplot as plt
|
|
import os.path as osp
|
|
import json
|
|
import os
|
|
import numpy as np
|
|
import pandas
|
|
from collections import defaultdict, namedtuple
|
|
from baselines.bench import monitor
|
|
from baselines.logger import read_json, read_csv
|
|
|
|
def smooth(y, radius, mode='two_sided', valid_only=False):
|
|
'''
|
|
Smooth signal y, where radius is determines the size of the window
|
|
|
|
mode='twosided':
|
|
average over the window [max(index - radius, 0), min(index + radius, len(y)-1)]
|
|
mode='causal':
|
|
average over the window [max(index - radius, 0), index]
|
|
|
|
valid_only: put nan in entries where the full-sized window is not available
|
|
|
|
'''
|
|
assert mode in ('two_sided', 'causal')
|
|
if len(y) < 2*radius+1:
|
|
return np.ones_like(y) * y.mean()
|
|
elif mode == 'two_sided':
|
|
convkernel = np.ones(2 * radius+1)
|
|
out = np.convolve(y, convkernel,mode='same') / np.convolve(np.ones_like(y), convkernel, mode='same')
|
|
if valid_only:
|
|
out[:radius] = out[-radius:] = np.nan
|
|
elif mode == 'causal':
|
|
convkernel = np.ones(radius)
|
|
out = np.convolve(y, convkernel,mode='full') / np.convolve(np.ones_like(y), convkernel, mode='full')
|
|
out = out[:-radius+1]
|
|
if valid_only:
|
|
out[:radius] = np.nan
|
|
return out
|
|
|
|
def one_sided_ema(xolds, yolds, low=None, high=None, n=512, decay_steps=1., low_counts_threshold=1e-8):
|
|
'''
|
|
perform one-sided (causal) EMA (exponential moving average)
|
|
smoothing and resampling to an even grid with n points.
|
|
Does not do extrapolation, so we assume
|
|
xolds[0] <= low && high <= xolds[-1]
|
|
|
|
Arguments:
|
|
|
|
xolds: array or list - x values of data. Needs to be sorted in ascending order
|
|
yolds: array of list - y values of data. Has to have the same length as xolds
|
|
|
|
low: float - min value of the new x grid. By default equals to xolds[0]
|
|
high: float - max value of the new x grid. By default equals to xolds[-1]
|
|
|
|
n: int - number of points in new x grid
|
|
|
|
decay_steps: float - EMA decay factor, expressed in new x grid steps.
|
|
|
|
low_counts_threshold: float or int
|
|
- y values with counts less than this value will be set to NaN
|
|
|
|
Returns:
|
|
tuple sum_ys, count_ys where
|
|
xs - array with new x grid
|
|
ys - array of EMA of y at each point of the new x grid
|
|
count_ys - array of EMA of y counts at each point of the new x grid
|
|
|
|
'''
|
|
|
|
low = xolds[0] if low is None else low
|
|
high = xolds[-1] if high is None else high
|
|
|
|
assert xolds[0] <= low, 'low = {} < xolds[0] = {} - extrapolation not permitted!'.format(low, xolds[0])
|
|
assert xolds[-1] >= high, 'high = {} > xolds[-1] = {} - extrapolation not permitted!'.format(high, xolds[-1])
|
|
assert len(xolds) == len(yolds), 'length of xolds ({}) and yolds ({}) do not match!'.format(len(xolds), len(yolds))
|
|
|
|
|
|
xolds = xolds.astype('float64')
|
|
yolds = yolds.astype('float64')
|
|
|
|
luoi = 0 # last unused old index
|
|
sum_y = 0.
|
|
count_y = 0.
|
|
xnews = np.linspace(low, high, n)
|
|
decay_period = (high - low) / (n - 1) * decay_steps
|
|
interstep_decay = np.exp(- 1. / decay_steps)
|
|
sum_ys = np.zeros_like(xnews)
|
|
count_ys = np.zeros_like(xnews)
|
|
for i in range(n):
|
|
xnew = xnews[i]
|
|
sum_y *= interstep_decay
|
|
count_y *= interstep_decay
|
|
while True:
|
|
if luoi >= len(xolds):
|
|
break
|
|
xold = xolds[luoi]
|
|
if xold <= xnew:
|
|
decay = np.exp(- (xnew - xold) / decay_period)
|
|
sum_y += decay * yolds[luoi]
|
|
count_y += decay
|
|
luoi += 1
|
|
else:
|
|
break
|
|
sum_ys[i] = sum_y
|
|
count_ys[i] = count_y
|
|
|
|
ys = sum_ys / count_ys
|
|
ys[count_ys < low_counts_threshold] = np.nan
|
|
|
|
return xnews, ys, count_ys
|
|
|
|
def symmetric_ema(xolds, yolds, low=None, high=None, n=512, decay_steps=1., low_counts_threshold=1e-8):
|
|
'''
|
|
perform symmetric EMA (exponential moving average)
|
|
smoothing and resampling to an even grid with n points.
|
|
Does not do extrapolation, so we assume
|
|
xolds[0] <= low && high <= xolds[-1]
|
|
|
|
Arguments:
|
|
|
|
xolds: array or list - x values of data. Needs to be sorted in ascending order
|
|
yolds: array of list - y values of data. Has to have the same length as xolds
|
|
|
|
low: float - min value of the new x grid. By default equals to xolds[0]
|
|
high: float - max value of the new x grid. By default equals to xolds[-1]
|
|
|
|
n: int - number of points in new x grid
|
|
|
|
decay_steps: float - EMA decay factor, expressed in new x grid steps.
|
|
|
|
low_counts_threshold: float or int
|
|
- y values with counts less than this value will be set to NaN
|
|
|
|
Returns:
|
|
tuple sum_ys, count_ys where
|
|
xs - array with new x grid
|
|
ys - array of EMA of y at each point of the new x grid
|
|
count_ys - array of EMA of y counts at each point of the new x grid
|
|
|
|
'''
|
|
xs, ys1, count_ys1 = one_sided_ema(xolds, yolds, low, high, n, decay_steps, low_counts_threshold=0)
|
|
_, ys2, count_ys2 = one_sided_ema(-xolds[::-1], yolds[::-1], -high, -low, n, decay_steps, low_counts_threshold=0)
|
|
ys2 = ys2[::-1]
|
|
count_ys2 = count_ys2[::-1]
|
|
count_ys = count_ys1 + count_ys2
|
|
ys = (ys1 * count_ys1 + ys2 * count_ys2) / count_ys
|
|
ys[count_ys < low_counts_threshold] = np.nan
|
|
return xs, ys, count_ys
|
|
|
|
Result = namedtuple('Result', 'monitor progress dirname metadata')
|
|
Result.__new__.__defaults__ = (None,) * len(Result._fields)
|
|
|
|
def load_results(root_dir_or_dirs, enable_progress=True, enable_monitor=True, verbose=False):
|
|
'''
|
|
load summaries of runs from a list of directories (including subdirectories)
|
|
Arguments:
|
|
|
|
enable_progress: bool - if True, will attempt to load data from progress.csv files (data saved by logger). Default: True
|
|
|
|
enable_monitor: bool - if True, will attempt to load data from monitor.csv files (data saved by Monitor environment wrapper). Default: True
|
|
|
|
verbose: bool - if True, will print out list of directories from which the data is loaded. Default: False
|
|
|
|
|
|
Returns:
|
|
List of Result objects with the following fields:
|
|
- dirname - path to the directory data was loaded from
|
|
- metadata - run metadata (such as command-line arguments and anything else in metadata.json file
|
|
- monitor - if enable_monitor is True, this field contains pandas dataframe with loaded monitor.csv file (or aggregate of all *.monitor.csv files in the directory)
|
|
- progress - if enable_progress is True, this field contains pandas dataframe with loaded progress.csv file
|
|
'''
|
|
import re
|
|
if isinstance(root_dir_or_dirs, str):
|
|
rootdirs = [osp.expanduser(root_dir_or_dirs)]
|
|
else:
|
|
rootdirs = [osp.expanduser(d) for d in root_dir_or_dirs]
|
|
allresults = []
|
|
for rootdir in rootdirs:
|
|
assert osp.exists(rootdir), "%s doesn't exist"%rootdir
|
|
for dirname, dirs, files in os.walk(rootdir):
|
|
if '-proc' in dirname:
|
|
files[:] = []
|
|
continue
|
|
monitor_re = re.compile(r'(\d+\.)?(\d+\.)?monitor\.csv')
|
|
if set(['metadata.json', 'monitor.json', 'progress.json', 'progress.csv']).intersection(files) or \
|
|
any([f for f in files if monitor_re.match(f)]): # also match monitor files like 0.1.monitor.csv
|
|
# used to be uncommented, which means do not go deeper than current directory if any of the data files
|
|
# are found
|
|
# dirs[:] = []
|
|
result = {'dirname' : dirname}
|
|
if "metadata.json" in files:
|
|
with open(osp.join(dirname, "metadata.json"), "r") as fh:
|
|
result['metadata'] = json.load(fh)
|
|
progjson = osp.join(dirname, "progress.json")
|
|
progcsv = osp.join(dirname, "progress.csv")
|
|
if enable_progress:
|
|
if osp.exists(progjson):
|
|
result['progress'] = pandas.DataFrame(read_json(progjson))
|
|
elif osp.exists(progcsv):
|
|
try:
|
|
result['progress'] = read_csv(progcsv)
|
|
except pandas.errors.EmptyDataError:
|
|
print('skipping progress file in ', dirname, 'empty data')
|
|
else:
|
|
if verbose: print('skipping %s: no progress file'%dirname)
|
|
|
|
if enable_monitor:
|
|
try:
|
|
result['monitor'] = pandas.DataFrame(monitor.load_results(dirname))
|
|
except monitor.LoadMonitorResultsError:
|
|
print('skipping %s: no monitor files'%dirname)
|
|
except Exception as e:
|
|
print('exception loading monitor file in %s: %s'%(dirname, e))
|
|
|
|
if result.get('monitor') is not None or result.get('progress') is not None:
|
|
allresults.append(Result(**result))
|
|
if verbose:
|
|
print('successfully loaded %s'%dirname)
|
|
|
|
if verbose: print('loaded %i results'%len(allresults))
|
|
return allresults
|
|
|
|
COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'yellow', 'black', 'purple', 'pink',
|
|
'brown', 'orange', 'teal', 'lightblue', 'lime', 'lavender', 'turquoise',
|
|
'darkgreen', 'tan', 'salmon', 'gold', 'darkred', 'darkblue']
|
|
|
|
|
|
def default_xy_fn(r):
|
|
x = np.cumsum(r.monitor.l)
|
|
y = smooth(r.monitor.r, radius=10)
|
|
return x,y
|
|
|
|
def default_split_fn(r):
|
|
import re
|
|
# match name between slash and -<digits> at the end of the string
|
|
# (slash in the beginning or -<digits> in the end or either may be missing)
|
|
match = re.search(r'[^/-]+(?=(-\d+)?\Z)', r.dirname)
|
|
if match:
|
|
return match.group(0)
|
|
|
|
def plot_results(
|
|
allresults, *,
|
|
xy_fn=default_xy_fn,
|
|
split_fn=default_split_fn,
|
|
group_fn=default_split_fn,
|
|
average_group=False,
|
|
shaded_std=True,
|
|
shaded_err=True,
|
|
figsize=None,
|
|
legend_outside=False,
|
|
resample=0,
|
|
smooth_step=1.0,
|
|
tiling='vertical',
|
|
xlabel=None,
|
|
ylabel=None
|
|
):
|
|
'''
|
|
Plot multiple Results objects
|
|
|
|
xy_fn: function Result -> x,y - function that converts results objects into tuple of x and y values.
|
|
By default, x is cumsum of episode lengths, and y is episode rewards
|
|
|
|
split_fn: function Result -> hashable - function that converts results objects into keys to split curves into sub-panels by.
|
|
That is, the results r for which split_fn(r) is different will be put on different sub-panels.
|
|
By default, the portion of r.dirname between last / and -<digits> is returned. The sub-panels are
|
|
stacked vertically in the figure.
|
|
|
|
group_fn: function Result -> hashable - function that converts results objects into keys to group curves by.
|
|
That is, the results r for which group_fn(r) is the same will be put into the same group.
|
|
Curves in the same group have the same color (if average_group is False), or averaged over
|
|
(if average_group is True). The default value is the same as default value for split_fn
|
|
|
|
average_group: bool - if True, will average the curves in the same group and plot the mean. Enables resampling
|
|
(if resample = 0, will use 512 steps)
|
|
|
|
shaded_std: bool - if True (default), the shaded region corresponding to standard deviation of the group of curves will be
|
|
shown (only applicable if average_group = True)
|
|
|
|
shaded_err: bool - if True (default), the shaded region corresponding to error in mean estimate of the group of curves
|
|
(that is, standard deviation divided by square root of number of curves) will be
|
|
shown (only applicable if average_group = True)
|
|
|
|
figsize: tuple or None - size of the resulting figure (including sub-panels). By default, width is 6 and height is 6 times number of
|
|
sub-panels.
|
|
|
|
|
|
legend_outside: bool - if True, will place the legend outside of the sub-panels.
|
|
|
|
resample: int - if not zero, size of the uniform grid in x direction to resample onto. Resampling is performed via symmetric
|
|
EMA smoothing (see the docstring for symmetric_ema).
|
|
Default is zero (no resampling). Note that if average_group is True, resampling is necessary; in that case, default
|
|
value is 512.
|
|
|
|
smooth_step: float - when resampling (i.e. when resample > 0 or average_group is True), use this EMA decay parameter (in units of the new grid step).
|
|
See docstrings for decay_steps in symmetric_ema or one_sided_ema functions.
|
|
|
|
'''
|
|
|
|
if split_fn is None: split_fn = lambda _ : ''
|
|
if group_fn is None: group_fn = lambda _ : ''
|
|
sk2r = defaultdict(list) # splitkey2results
|
|
for result in allresults:
|
|
splitkey = split_fn(result)
|
|
sk2r[splitkey].append(result)
|
|
assert len(sk2r) > 0
|
|
assert isinstance(resample, int), "0: don't resample. <integer>: that many samples"
|
|
if tiling == 'vertical' or tiling is None:
|
|
nrows = len(sk2r)
|
|
ncols = 1
|
|
elif tiling == 'horizontal':
|
|
ncols = len(sk2r)
|
|
nrows = 1
|
|
elif tiling == 'symmetric':
|
|
import math
|
|
N = len(sk2r)
|
|
largest_divisor = 1
|
|
for i in range(1, int(math.sqrt(N))+1):
|
|
if N % i == 0:
|
|
largest_divisor = i
|
|
ncols = largest_divisor
|
|
nrows = N // ncols
|
|
figsize = figsize or (6 * ncols, 6 * nrows)
|
|
|
|
f, axarr = plt.subplots(nrows, ncols, sharex=False, squeeze=False, figsize=figsize)
|
|
|
|
groups = list(set(group_fn(result) for result in allresults))
|
|
|
|
default_samples = 512
|
|
if average_group:
|
|
resample = resample or default_samples
|
|
|
|
for (isplit, sk) in enumerate(sorted(sk2r.keys())):
|
|
g2l = {}
|
|
g2c = defaultdict(int)
|
|
sresults = sk2r[sk]
|
|
gresults = defaultdict(list)
|
|
idx_row = isplit // ncols
|
|
idx_col = isplit % ncols
|
|
ax = axarr[idx_row][idx_col]
|
|
for result in sresults:
|
|
group = group_fn(result)
|
|
g2c[group] += 1
|
|
x, y = xy_fn(result)
|
|
if x is None: x = np.arange(len(y))
|
|
x, y = map(np.asarray, (x, y))
|
|
if average_group:
|
|
gresults[group].append((x,y))
|
|
else:
|
|
if resample:
|
|
x, y, counts = symmetric_ema(x, y, x[0], x[-1], resample, decay_steps=smooth_step)
|
|
l, = ax.plot(x, y, color=COLORS[groups.index(group) % len(COLORS)])
|
|
g2l[group] = l
|
|
if average_group:
|
|
for group in sorted(groups):
|
|
xys = gresults[group]
|
|
if not any(xys):
|
|
continue
|
|
color = COLORS[groups.index(group) % len(COLORS)]
|
|
origxs = [xy[0] for xy in xys]
|
|
minxlen = min(map(len, origxs))
|
|
def allequal(qs):
|
|
return all((q==qs[0]).all() for q in qs[1:])
|
|
if resample:
|
|
low = max(x[0] for x in origxs)
|
|
high = min(x[-1] for x in origxs)
|
|
usex = np.linspace(low, high, resample)
|
|
ys = []
|
|
for (x, y) in xys:
|
|
ys.append(symmetric_ema(x, y, low, high, resample, decay_steps=smooth_step)[1])
|
|
else:
|
|
assert allequal([x[:minxlen] for x in origxs]),\
|
|
'If you want to average unevenly sampled data, set resample=<number of samples you want>'
|
|
usex = origxs[0]
|
|
ys = [xy[1][:minxlen] for xy in xys]
|
|
ymean = np.mean(ys, axis=0)
|
|
ystd = np.std(ys, axis=0)
|
|
ystderr = ystd / np.sqrt(len(ys))
|
|
l, = axarr[idx_row][idx_col].plot(usex, ymean, color=color)
|
|
g2l[group] = l
|
|
if shaded_err:
|
|
ax.fill_between(usex, ymean - ystderr, ymean + ystderr, color=color, alpha=.4)
|
|
if shaded_std:
|
|
ax.fill_between(usex, ymean - ystd, ymean + ystd, color=color, alpha=.2)
|
|
|
|
|
|
# https://matplotlib.org/users/legend_guide.html
|
|
plt.tight_layout()
|
|
if any(g2l.keys()):
|
|
ax.legend(
|
|
g2l.values(),
|
|
['%s (%i)'%(g, g2c[g]) for g in g2l] if average_group else g2l.keys(),
|
|
loc=2 if legend_outside else None,
|
|
bbox_to_anchor=(1,1) if legend_outside else None)
|
|
ax.set_title(sk)
|
|
# add xlabels, but only to the bottom row
|
|
if xlabel is not None:
|
|
for ax in axarr[-1]:
|
|
plt.sca(ax)
|
|
plt.xlabel(xlabel)
|
|
# add ylabels, but only to left column
|
|
if ylabel is not None:
|
|
for ax in axarr[:,0]:
|
|
plt.sca(ax)
|
|
plt.ylabel(ylabel)
|
|
|
|
return f, axarr
|
|
|
|
def regression_analysis(df):
|
|
xcols = list(df.columns.copy())
|
|
xcols.remove('score')
|
|
ycols = ['score']
|
|
import statsmodels.api as sm
|
|
mod = sm.OLS(df[ycols], sm.add_constant(df[xcols]), hasconst=False)
|
|
res = mod.fit()
|
|
print(res.summary())
|
|
|
|
def test_smooth():
|
|
norig = 100
|
|
nup = 300
|
|
ndown = 30
|
|
xs = np.cumsum(np.random.rand(norig) * 10 / norig)
|
|
yclean = np.sin(xs)
|
|
ys = yclean + .1 * np.random.randn(yclean.size)
|
|
xup, yup, _ = symmetric_ema(xs, ys, xs.min(), xs.max(), nup, decay_steps=nup/ndown)
|
|
xdown, ydown, _ = symmetric_ema(xs, ys, xs.min(), xs.max(), ndown, decay_steps=ndown/ndown)
|
|
xsame, ysame, _ = symmetric_ema(xs, ys, xs.min(), xs.max(), norig, decay_steps=norig/ndown)
|
|
plt.plot(xs, ys, label='orig', marker='x')
|
|
plt.plot(xup, yup, label='up', marker='x')
|
|
plt.plot(xdown, ydown, label='down', marker='x')
|
|
plt.plot(xsame, ysame, label='same', marker='x')
|
|
plt.plot(xs, yclean, label='clean', marker='x')
|
|
plt.legend()
|
|
plt.show()
|
|
|
|
|