diff --git a/docs/figs/joyrl_docs/branch_merge.png b/docs/figs/joyrl_docs/branch_merge.png new file mode 100644 index 0000000..87a0769 Binary files /dev/null and b/docs/figs/joyrl_docs/branch_merge.png differ diff --git a/docs/figs/joyrl_docs/tasks_dir.png b/docs/figs/joyrl_docs/tasks_dir.png new file mode 100644 index 0000000..025c6a1 Binary files /dev/null and b/docs/figs/joyrl_docs/tasks_dir.png differ diff --git a/docs/joyrl_docs/basic_concept.md b/docs/joyrl_docs/basic_concept.md index d1b9e79..5deea21 100644 --- a/docs/joyrl_docs/basic_concept.md +++ b/docs/joyrl_docs/basic_concept.md @@ -62,7 +62,7 @@ 如图 6 所示,在线测试器更像是一个独立的模块,它并不影响训练过程,因此在图中特别将其分离出来。
- +
图 6 整体框架
diff --git a/docs/joyrl_docs/general_cfg.md b/docs/joyrl_docs/general_cfg.md index fe95360..3d27543 100644 --- a/docs/joyrl_docs/general_cfg.md +++ b/docs/joyrl_docs/general_cfg.md @@ -44,8 +44,6 @@ class GeneralConfig(object): * `max_step`:每回合最大步数,当为`-1`时,则不限制每回合最大步数,直到环境返回`done=True`或者`truncate=True`,**请根据实际环境情况设置**。 * `collect_traj`:是否收集轨迹,当为`True`时,则收集轨迹,否则不收集轨迹,一般用于模仿学习、逆强化学习等。 * `n_interactors`:交互器数量,默认为`1`,请根据实际情况设置。 -* `interactor_mode`:交互器模式,当`n_interactors>1`时有效,`dummy`或`ray`,默认为`dummy`,当为`dummy`时,每次串行执行交互器,当为`ray`时,每次并行执行交互器收集样本。 -* `learner_mode`:学习器模式,`serial`或`parallel`,默认为`serial`,当为`serial`时,表示每次先执行交互器采样,然后执行学习器更新策略,当为`parallel`时,表示交互器和学习器分别同时进行采样和更新策略。 * `n_learners`:学习器数量,默认为`1`,请根据实际情况设置。 * `online_eval`:是否在线测试,当为`True`时,则在线测试,否则不在线测试。开启在线测试时,会额外输出一个名为`best`的模型,用于保存训练过程中测试效果最好的模型,但不一定是最新的模型。 * `online_eval_episode`:在线测试回合数,请根据实际情况设置。 diff --git a/docs/joyrl_docs/main.md b/docs/joyrl_docs/main.md index 5379817..043955c 100644 --- a/docs/joyrl_docs/main.md +++ b/docs/joyrl_docs/main.md @@ -73,8 +73,6 @@ class GeneralConfig: self.max_step = 200 # number of episodes for testing, set -1 means unlimited steps # multiprocessing settings self.n_interactors = 1 # number of interactors - self.interactor_mode = "dummy" # dummy, only works when learner_mode is serial - self.learner_mode = "serial" # serial, parallel, whether workers and learners are in parallel # online evaluation settings self.online_eval = True # online evaluation or not self.online_eval_episode = 10 # online eval episodes @@ -100,12 +98,3 @@ if __name__ == "__main__": ## 文档 [点击](https://datawhalechina.github.io/joyrl/)查看更详细的教程和`API`文档。 - - -## 算法列表 - -算法讲解请参考[“蘑菇书”](https://github.com/datawhalechina/easy-rl)和[JoyRL Book](https://github.com/datawhalechina/joyrl-book) - -| 名称 | 参考文献 | 作者 | 备注 | -| :--------------: | :----------------------------------------------------------: | :-------------------------------------------: | :---: | -| DQN | [DQN Paper](https://www.cs.toronto.edu/~vmnih/docs/dqn.pdf) | [johnjim0816](https://github.com/johnjim0816) | | diff --git a/docs/joyrl_docs/usage.md b/docs/joyrl_docs/usage.md index 4cd699a..ec3bde0 100644 --- a/docs/joyrl_docs/usage.md +++ b/docs/joyrl_docs/usage.md @@ -4,6 +4,8 @@ ## 快速开始 +### 参数配置简介 + `JoyRL`旨在让用户只需要通过调参就能进行相关的强化学习实践,主要的参数包括: * 通用参数(`GeneralConfig`):跟运行模式相关的参数,如算法名称`algo_name`、环境名称`env_name`、随机种子`seed`等等; @@ -39,8 +41,6 @@ class GeneralConfig: self.env_name = "gym" # name of environment self.algo_name = "DQN" # name of algorithm self.mode = "train" # train, test - self.interactor_mode = "dummy" # dummy, only works when learner_mode is serial - self.learner_mode = "serial" # serial, parallel, whether workers and learners are in parallel self.device = "cpu" # device to use self.seed = 0 # random seed self.max_episode = -1 # number of episodes for training, set -1 to keep running @@ -69,7 +69,157 @@ if __name__ == "__main__": 注意必须以准确的关键字(`kwarg`)形式传入到`joyrl.run`函数中!!! -同时,`JoyRL`自带默认的参数配置,在用户传入自定义参数时,会优先考虑`yaml`文件中的参数,其次是传入的参数类,默认的参数配置优先级最低。用户在配置参数时不需要同时配置所有参数,对于一些不关心的参数使用默认的配置即可。 +同时,`JoyRL`自带默认的参数配置,在用户传入自定义参数时,会优先考虑`yaml`文件中的参数,其次是传入的参数类,默认的参数配置优先级最低。用户在配置参数时不需要同时配置所有参数,对于一些不关心的参数使用默认的配置即可。下面部分我们将介绍几种常用的参数配置方式。 + +### 训练与测试 + +想要训练一个算法,我们首先需要把`mode`改成`train`,并且配置好算法名称`algo_name`和环境名称`env_name`,以及环境的`id`,然后设置`max_episode`和`max_step`,如下: + +```yaml +general_cfg: + algo_name: DQN + env_name: gym + device: cpu + mode: train + max_episode: -1 + max_step: 200 + load_checkpoint: false + load_path: Train_single_CartPole-v1_DQN_20230515-211721 + load_model_step: best + seed: 1 + online_eval: true + online_eval_episode: 10 + model_save_fre: 500 +env_cfg: + id: CartPole-v1 + render_mode: null +``` + +其中`max_episode`表示最大训练回合数,设置为-1时将持续训练直到手动停止,`max_step`表示每回合最大步数,设置为-1时将持续训练直到环境返回`done=True`或者`truncate=True`,**请根据实际环境情况设置,通常来讲每回合的步数过长不利于强化学习训练**。 + +配置好之后,用前面提到的任一种方式运行即可开始训练,训练过程中会在当前目录下生成一个`tasks`文件夹,里面包含了训练过程中的模型文件、日志文件等等,如下: + +
+ +
图 1 tasks文件夹构成
+
+ +其中`logs`文件夹下会保存终端输出的日志,`models`文件夹下会保存训练过程中的模型文件,`tb_logs`文件夹下会保存训练过程中的`tensorboard`文件,例如奖励曲线、损失曲线等等,`results`文件夹下会以`csv`的形式保存奖励、损失等,便于后续单独绘图分析。`videos`文件夹下会保存运行过程中的视频文件,主要在测试过程中使用。`config.yaml`则保存本次运行过程中的参数配置,便于复现训练结果。 + +如果想要测试一个算法,我们只需要把`mode`改成`test`,然后将`load_checkpoint`(是否加载模型文件)改成`True`,并配好模型文件路径`load_path`和模型文件步数`load_model_step`,如下: + +```yaml +mode: test +load_checkpoint: true +load_path: Train_single_CartPole-v1_DQN_20230515-211721 +load_model_step: 1000 +``` + +### 在线测试模式 + +在训练过程中,我们往往需要对策略进行定期的测试,以便于及时发现问题和保存效果最好的模型。因此,`JoyRL`提供了在线测试模式,只需要将`online_eval`设置为`True`,并设置好`online_eval_episode`(测试的回合数),即可开启在线测试模式,如下: + +```yaml +online_eval: true +online_eval_episode: 10 +model_save_fre: 500 +``` + +其中`model_save_fre`表示模型保存频率,开启在线测试模式时,每保存一次模型,就会进行一次在线测试,并且会额外输出一个名为`best`的模型,用于保存训练过程中测试效果最好的模型,但不一定是最新的模型。 + +### 多进程模式 + +`JoyRL`支持多进程模式,但与向量化环境不同,`JoyRL`的多进程模式能够同时异步运行多个交互器和学习器,这样的好处是某一个交互器和学习器出现异常了,不会影响其他交互器和学习器的运行,从而提高训练的稳定性。在`JoyRL`中开启多进程的方式非常简单,只需要将`n_interactors`和`n_learners`设置为大于1的整数即可,如下: + +```yaml +n_interactors: 2 +n_learners: 2 +``` + +注意,目前还不支持多个学习器的模式,即`n_learners`必须设置为1,未来会支持多个学习器的模式。 + +### 网络配置 + +`JoyRL`支持通过配置文件来建立网络,如下: + +```yaml +merge_layers: + - layer_type: linear + layer_size: [256] + activation: relu + - layer_type: linear + layer_size: [256] + activation: relu +``` + +该配置等价为: + +```python +class MLP(nn.Module): + def __init__(self, state_dim,action_dim): + super(MLP, self).__init__() + self.fc1 = nn.Linear(state_dim, 256) + self.fc2 = nn.Linear(256,256) + self.fc3 = nn.Linear(256, action_dim) + def forward(self, x): + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + return self.fc3(x) +``` + +其中输入的`state_dim`和`action_dim`会自动从环境中的状态动作空间中获取,用户只需要配置网络的结构即可。 + +### 多头网络 + +在上一小节配置网络中,会发现网络配置输入是`merge_layers`,这是因为`JoyRL`支持多头网络,即可以同时输入多个网络,然后将多个网络的输出进行合并。例如当状态输入同时包含图像和线性输入时,此时可以分别配置两个网络,然后将两个网络的输出进行合并,这就是多头网络的用法,如下图: + +
+ +
图 2 branch和merge网络
+
+ +其中`branch_layers`表示分支网络,`merge_layers`表示合并网络,`branch_layers`和`merge_layers`的配置方式与`merge_layers`相同,只是需要在每个网络的配置中加入`name`,如下: + +```yaml +branch_layers: + - name: feature_1 + layers: + - layer_type: conv2d + in_channel: 4 + out_channel: 16 + kernel_size: 4 + stride: 2 + activation: relu + - layer_type: pooling + pooling_type: max2d + kernel_size: 2 + stride: 2 + padding: 0 + - layer_type: flatten + - layer_type: norm + norm_type: LayerNorm + normalized_shape: 512 + - layer_type: linear + layer_size: [128] + activation: relu + - name: feature_2 + layers: + - layer_type: linear + layer_size: [128] + activation: relu + - layer_type: linear + layer_size: [128] + activation: relu +merge_layers: + - layer_type: linear + layer_size: [256] + activation: relu + - layer_type: linear + layer_size: [256] + activation: relu +``` + +如果只是配置简单的线性网络,则可以只配置`merge_layers`或者`branch_layers`,而如果是非线性网络例如`CNN`,则只能配置`branch_layers`,因为在逻辑上`merge_layers`只能接收线性输入。 ## 自定义策略