Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

200 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

NOTE: We maintain RLA in https://github.com/polixir/RLAssistant now.

RL experiment Assistant (RLA)

img.png RLA is a tool for managing your RL experiments automatically (e.g., your hyper-parameters, logs, checkpoints, figures, and code, etc.). RLA has decoupled to the training code and only some additional configuration are needed. Before using RLA, we recommend you to read the section "Design Principles of RLA", which will be helpful for you to understand the basic logic of the repo.

The project is still in developing. Welcome to join us. :)

Design Principles of RLA

img.png

The core design principle of RLA is regarding all related information of each Experiment As A complex item in a Database (EaaD). We design RLA to manage the experiments dataset by

  1. formulating, standardizing, and structuring the data items and tables of the "RL experiment database";
  2. provide tools for adding, deleting, modifying, and querying the items in the database.

The following are the detailed designs of EaaD and the implementation of RLA.

Standardizing and Structuring the Experiment Database

After integrating RLA into your project, we create a "database" implicitly configured by rla_config.yaml. Each experiment we run will be indexed and stored as an item into a "table". In particular, RLA includes the following elelments to construct an "RL experiment database".

  1. Database: A database is configured by a YAML file rla_config.yaml. In our practice, we only create one database in one research subject.

  2. Table: We map the concept of Table in standard database systems into the concept of "task" in our research process. There are many similarities between the two concepts. For example, we will create another table/task often when:

    1. the structures of tables are different, e.g., they have different keys. In the research process, different tasks often have totally different types of logs to record. For example, in offline model-based RL, the first task might pretrain a dynamics model the second task might be policy learning with the learned model. In model learning, we are concerned with the MSE of the model; In policy learning, we are concerned with the rewards of policy.
    2. The content of a table is too large which might hurt the speed of querying. Table partition is a common solution. In the research process, we need large memory to load a Tensorboard if the logdir has many runs. We can solve the problem by splitting the runs into different sub-directories.

    In RLA, we need to assign a "task" for each experiment to run.

  3. Data Item: We map the concept of the data item to the complex generated data in an experiment. For each data item, we need to define the index and the value for each item.

    1. Index: We need a unique index to define the item in a table for item adding, deleting, modifying, and querying. In RLA, we define the index of each experiment as: datetime of the experiment (for uniqueness) + ip address (for keeping uniqueness in distributed training) + tracked hyper-parameters (easy to identify and easy to search).
    2. Value: when running an experiment, we generate many data with different structures. Based on our research practice, currently, we formulate and store the following data
      1. Codes and hyper-parameters: Every line of the code and select hyper-parameters to run the experiment. This is a backup for experiment reproducibility.
      2. Recorded variables: We often record many intermediate variables in the process of the experiment, e.g., the rewards, some losses, or learning rates. We record the variables in the key-value formulation and store them in a tensorboard event and a CSV file.
      3. Model checkpoints: We support weights saving of neural networks and related custom variables in Tensorflow and Pytorch framework. We can use the checkpoints to resume experiments or use the results of the experiment to complete downstream tasks.
      4. Other data like figures or videos: It essentially is unstructured intermediate variables in the process of the experiment. We might plot the frame-to-frame video of your agent behavior or some curves to check the process of training. We give some common tools in the RL scenario to generate the related variables and store them in a directory.

Currently, we store the data items in standard file systems and manage the relationships among data items, tables, and database via a predefined directory structure. After running some experiments, the database will be something like this: img.png

  • Here we construct a database in the project "sb_ppo_example".
  • The directory "archive_tester" is to store hyper-parameters and related variables for experiment resuming.
  • The directory "results" is to store other data like figures or videos.
  • The directory "log" is to store recorded variables.
  • The directory "code" is a backup of code for experiment reproducibility.
  • The directory "checkpoint" save weights of neural networks.
  • We have a table named "demo_task", which is the root directory of log/archive_tester/checkpoint/code/results.
  • The "index" of experiments in named in the formulation of ${%Y}/${%m}/${%d}/${%H-%M-%S-%f}_${ip address}_${tracked hyper-parameters}.

Tools to Manage the Database

In standard database systems, the commonly used operations to manage a database are adding, deleting modifying, and querying. We also give similar tools to manage the RLA database.

Adding:

  1. RLA.easy_log.tester.exp_manager is a global object to create experiments and manger the data in the process of experiments.
  2. RLA.easy_log.logger is a module to add recorded variables.
  3. RLA.easy_log.simple_mat_plot is a module to construct other data like figures or videos

Deleting:

  1. rla_scripts.delete_log: a tool to delete a data item by regex;

Modifying:

  1. resume: RLA.easy_log.exp_loader.ExperimentLoader: a class to resume an experiments with different flexible settings.

Querying:

  1. tensorboard: the recorded variables are added to tensorboard events and can be loaded via standard tensorboard tools. img.png
  2. easy_plot: We give some APIs to load and visualize the data in CSV files. The results will be something like this:
    fromRLA.easy_plot.plot_func_v2importplot_funcdata_root='your_project'task='sac_test'regs= [
    '2022/03/01/21-[12]*'
    ]
    _=plot_func(data_root=data_root, task_table_name=task, regs=regs , split_keys=['info', 'van_sac', 'alpha_max'], metrics=['perf/rewards'])

Other principles

The second design principle is easy for integration. It still has a long way to go to achieve it. We give several example projects integrating with RLA in the directory example.

  1. PPO with RLA based on the stable_baselines (tensorflow): example/sb_ppo_example
  2. PPO with RL based on the stable_baselines3 (pytorch): example/sb3_ppo_example

We also list the RL research projects using RLA as follows:

  1. MAPLE
  2. CODAS

Installation

git clone https://github.com/xionghuichen/RLAssistant.git
cd RLAssistant
pip install -e .

Workflow

We build an example project for integrating RLA, which can be seen in ./example/simplest_code. Now we summarize the steps to use it.

Step1: Configuration.

  1. We define the property of the database in rla_config.yaml. You can construct your YAML file based on the template in ./example/simplest_code/rla_config.yaml.

  2. We define the property of the table in exp_manager.config. Before starting your experiment, you should configure the global object RLA.easy_log.tester.exp_manager like this:

    fromRLAimportexp_managerimportoskwargs= {'env_id': 'Hopper-v2', 'lr': 1e-3}
    exp_manager.set_hyper_param(**kwargs) # kwargs are the hyper-parameters for your experimentexp_manager.add_record_param(["env_id"]) # add parts of hyper-parameters to name the index of data items for better readability.task_name='demo_task'# define your taskdefget_package_path():
    returnos.path.dirname(os.path.abspath(__file__))
    rla_data_root=get_package_path() # the place to store the data items.rla_config=os.path.join(get_package_path(), 'rla_config.yaml')
    ignore_file_path=os.path.join(get_package_path(), '.gitignore')
    exp_manager.configure(task_table_name=task_name, ignore_file_path=ignore_file_path,
    rla_config=rla_config, data_root=rla_data_root)
    exp_manager.log_files_gen() # initialize the data items.exp_manager.print_args()

    where ignore_file_path is a gitignore-style file, which is used to ignored files when backing up your project into code folder. It is an optional parameter, and you can use your .gitignore file of your git repository directly.

  3. We add the generated data items to .gitignore to avoid pushing them into our git repo.

    **/archive_tester/****/checkpoint/****/code/****/results/****/log/****/arc/**

Step2: record intermediate variables/checkpoints/other types of data.

Record intermediate scalars

We record scalars by RLA.easy_log.logger:

fromRLAimportloggerimporttensorflowastffromRLAimporttime_step_holderforiinrange(1000):
# time-steps (iterations)time_step_holder.set_time(i)
# scalar variablevalue=1logger.record_tabular("k", value)
# tensorflow summarysummary=tf.Summary()
logger.log_from_tf_summary(summary)

Record checkpoints

We save checkpoints of neural networks by exp_manager.save_checkpoint.

fromRLAimportexp_managerexp_manager.new_saver()
foriinrange(1000):
ifi%10==0:
exp_manager.save_checkpoint()

Record other type of data [under developing]

Currently we can record complex-structure data based on tensorboard:

# from tensorflow summaryimporttensorflowastffromRLAimportloggersummary=tf.Summary()
logger.log_from_tf_summary(summary)
# from tensorboardX writerkwargs= {'tag': 'aa'}
logger.get_tbx_writer().add_audio(**kwargs)

We will develop APIs to record common-used complex-structure data in RLA.easy_log.complex_data_recorder. Now we give a MatplotlibRecorder tool to manage your figures generated by matplotlib:

fromRLAimportMatplotlibRecorderasmprdefplot_func():
importmatplotlib.pyplotaspltplt.plot([1,1,1], [2,2,2])
mpr.pretty_plot_wrapper('func', plot_func, xlabel='x', ylabel='y', title='react test', )

The figure plotted by plot_func will be saved in the "results" directory.

Step3: handle your historical experiments.

The methods to handle the experiments can be splitted into the following modules:

Query

Currently, we develop the query tools based on two common scenarios: result visualization and experiment review.

Result visualization:

  1. Tensorboard: We can use tensorboard/tensorboardX to view the recorded logs. The event of tensorboard will be saved in ${data_root}/log/${task_name}/${index_name}/tb/events. We can view the results in tensorboard by: tensorboard --logdir ${data_root}/log/${task_name}. For example, lanuch tensorboard by tensorboard --logdir ./example/simplest_code/log/demo_task/2022/03. We can see results: img.png
  2. Easy_plot toolkit: We recommend the users maintain their research projects via some jupyter notebooks. You can record your ideas, surmises, related empirical evidence, and benchmark results in a notebook together. We develop high-level APIs to load the CSV files of the experiments (stored in ${data_root}/log/${task_name}/${index_name}/progress.csv) and group the curves by custom keys. We give common user cases of the plotter in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_plot.ipynb The result will be something like this: img.png
  3. View data in "results" directory directly: other type of data are stored in ${data_root}/results/${task_name}/${index_name}img.png

Experiment review:

  1. Given any experiment named as ${task_name}/${index_name}, we can find the line-by-line code in ${data_root}/code/${task_name}/${index_name}. We can configure the files to be stored in BACKUP_CONFIG in rla_config.yaml.
  2. The corresponding hyper-parameters (recorded by exp_manager.set_hyper_param) can be found in ${data_root}/log/${task_name}/${index_name}/backup.txt.

Modify

Usually, it is unnecessary to change the content of experiment logs. In our practice, a common scenario is to load the historical experiment/results to resume the training or give to downstream tasks. In RLA, we develop a tool for different requirements of experiment loading, which is in RLA.easy_log.exp_loader. It can be easily used to:

  1. load a pretrained model for another task (e.g., validation);
  2. resume an experiment;
  3. resume an experiment with other settings.

Batch Management

We manage the items in the database via toolkits in rla_scripts. Currently, the rla_scripts includes

  1. Archive: archive important experiments into an archived database, which will be saved in DATA_ROOT/arc.
  2. Delete: delete all useless experiments at once.
  3. Send to remote [TODO]
  4. Download from remote [TODO]

We can use the above tools after copying the rla_scripts to our research project and modifying the DATA_ROOT in config.py to locate the root of the RLA database. We give several user cases in https://github.com/xionghuichen/RLAssistant/blob/main/test/test_scripts.py

Distributed training & centralized logs

In practice, we might conduct our experiments in multiple physical machines for the same project. Different physical machines separate the experiment data in the database. We develop a simple log-sending tools based on ftplib. We split the physical machines into a main node and slave nodes. For each slave node, we should extra configure the following setign in rla_config.yaml:

SEND_LOG_FILE: True
REMOTE_SETTING:
ftp_server: '114.114.114.114'
username: 'agent'
password: '123'
remote_data_root: 'remote_project/data_root/'
file_transfer_protocol: 'sftp'

where SEND_LOG_FILE is set to True, ftp_server, username and password are the ip address, username and passward of the master node respectively, and file_transfer_protocol is the protocol to send data. remote_data_root defines the data_root of the database in the main node. For the main node, configure the exp_manger by exp_manager.configure(..., is_master_node=True). In our experiment code, we should call the function RLA.easy_log.tester.exp_manager.sync_log_file periodically, for example,

for i in range(1000):
# your trianing code.
exp_manager.sync_log_file()

then the data items we be sent to the remote_data_root of the main node. Since is_master_node is set to True in the main node, the exp_manager.sync_log_file() will be skipped in the main node.

PS:

  1. You might meet "socket.error: [Errno 111] Connection refused" problem in this process. The solution can be found here.

  2. An alternative way is building your own NFS for your physical machines and locate data_root to the NFS.

more demos

We write the usage of RLA as unit tests. You can check the scripts in test folder for more details (include test_plot.py, test_scripts.py, and test_proj/proj/test_manger.py).

TODO

  • support custom data structure saving and loading.
  • support video visualization.
  • add comments and documents to the functions.
  • add an auto integration script.
  • download / upload experiment logs through timestamp.
  • allow sync LOG only or ALL TYPE LOGS.
  • add unit_test to ckp loader.

About

RLA is a tool for managing your RL experiments automatically

Topics

Resources

Stars

71 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages