diff --git a/projects/README.md b/projects/README.md index fcee9df..276c7e5 100644 --- a/projects/README.md +++ b/projects/README.md @@ -1,4 +1,4 @@ -## 0、写在前面 +## 0. 写在前面 本项目用于学习RL基础算法,主要面向对象为RL初学者、需要结合RL的非专业学习者,尽量做到: **注释详细**,**结构清晰**。 @@ -6,7 +6,7 @@ 未来开发计划包括但不限于:多智能体算法、强化学习Python包以及强化学习图形化编程平台等等。 -## 1、项目说明 +## 1. 项目说明 项目内容主要包含以下几个部分: * [Jupyter Notebook](./notebooks/):使用Notebook写的算法,有比较详细的实战引导,推荐新手食用 @@ -18,7 +18,7 @@ * ```[algorithm_name].py```:即保存算法的脚本,例如```dqn.py```,每种算法都会有一定的基础模块,例如```Replay Buffer```、```MLP```(多层感知机)等等; * ```task.py```: 即保存任务的脚本,基本包括基于```argparse```模块的参数,训练以及测试函数等等,其中训练函数即```train```遵循伪代码而设计,想读懂代码可从该函数入手; * ```utils.py```:该脚本用于保存诸如存储结果以及画图的软件,在实际项目或研究中,推荐大家使用```Tensorboard```来保存结果,然后使用诸如```matplotlib```以及```seabron```来进一步画图。 -## 2、算法列表 +## 2. 算法列表 注:点击对应的名称会跳到[codes](./codes/)下对应的算法中,其他版本还请读者自行翻阅 @@ -26,26 +26,27 @@ | :-------------------------------------: | :----------------------------------------------------------: | :--: | | [Policy Gradient](codes/PolicyGradient) | [Policy Gradient paper](https://proceedings.neurips.cc/paper/1999/file/464d828b85b0bed98e80ade0a5c43b0f-Paper.pdf) | | | DQN-CNN | | 待更 | +| [DoubleDQN](codes/DoubleDQN) | [Double DQN Paper](https://arxiv.org/abs/1509.06461) | | | [SoftQ](codes/SoftQ) | [Soft Q-learning paper](https://arxiv.org/abs/1702.08165) | | | [SAC](codes/SAC) | [SAC paper](https://arxiv.org/pdf/1812.05905.pdf) | | | [SAC-Discrete](codes/SAC) | [SAC-Discrete paper](https://arxiv.org/pdf/1910.07207.pdf) | | | SAC-S | [SAC-S paper](https://arxiv.org/abs/1801.01290) | | | DSAC | [DSAC paper](https://paperswithcode.com/paper/addressing-value-estimation-errors-in) | 待更 | -## 3、算法环境 +## 3. 算法环境 算法环境说明请跳转[env](./codes/envs/README.md) -## 4、运行环境 +## 4. 运行环境 -主要依赖:Python 3.7、PyTorch 1.10.0、Gym 0.21.0。 +主要依赖:Python 3.7、PyTorch 1.10.0、Gym 0.25.2。 -### 4.1、创建Conda环境 +### 4.1. 创建Conda环境 ```bash conda create -n easyrl python=3.7 conda activate easyrl # 激活环境 ``` -### 4.2、安装Torch +### 4.2. 安装Torch 安装CPU版本: ```bash @@ -63,30 +64,49 @@ conda install pytorch==1.10.0 torchvision==0.11.0 torchaudio==0.10.0 cudatoolkit ```bash pip install torch==1.10.0+cu113 torchvision==0.11.0+cu113 torchaudio==0.10.0 --extra-index-url https://download.pytorch.org/whl/cu113 ``` -### 4.3、安装其他依赖 - -项目根目录下执行: -```bash -pip install -r requirements.txt -``` -### 4.4、检验CUDA版本Torch安装 +### 4.3. 检验CUDA版本Torch安装 CPU版本Torch请忽略此步,执行如下Python脚本,如果返回True说明CUDA版本安装成功: ```python import torch print(torch.cuda.is_available()) ``` +### 4.4. 安装Gym -## 5、使用说明 +```bash +pip install gym==0.25.2 +``` +如需安装Atari环境,则需另外安装 -对于[codes](./codes/): -* 运行带有```main.py```脚本 -* 执行[scripts](codes\scripts)下对应的Bash脚本,例如```sh codes/scripts/DQN_task0.sh```,推荐创建名为"easyrl"的conda环境,否则需要更改sh脚本相关信息。对于Windows系统,建议安装Git(不要更改默认安装路径,否则VS Code可能不会显示Git Bash)然后使用git bash终端,而非PowerShell或者cmd终端! +```bash +pip install gym[atari,accept-rom-license]==0.25.2 +``` + +### 4.5. 安装其他依赖 + +项目根目录下执行: +```bash +pip install -r requirements.txt +``` + +## 6.使用说明 + +对于[codes](./codes/),`cd`到对应的算法目录下,例如`DQN`: + +```bash +python task_0.py +``` + +或者加载配置文件: + +```bash +python task0.py --yaml configs/CartPole-v1_DQN_Train.yaml +``` 对于[Jupyter Notebook](./notebooks/): * 直接运行对应的ipynb文件就行 -## 6、友情说明 +## 6. 友情说明 推荐使用VS Code做项目,入门可参考[VSCode上手指南](https://blog.csdn.net/JohnJim0/article/details/126366454) \ No newline at end of file diff --git a/projects/assets/pseudocodes/pseudocodes.pdf b/projects/assets/pseudocodes/pseudocodes.pdf index b34cabc..cfe734a 100644 Binary files a/projects/assets/pseudocodes/pseudocodes.pdf and b/projects/assets/pseudocodes/pseudocodes.pdf differ diff --git a/projects/assets/pseudocodes/pseudocodes.tex b/projects/assets/pseudocodes/pseudocodes.tex index 929453a..7af7feb 100644 --- a/projects/assets/pseudocodes/pseudocodes.tex +++ b/projects/assets/pseudocodes/pseudocodes.tex @@ -38,13 +38,14 @@ \clearpage \section{模版备用} \begin{algorithm}[H] % [H]固定位置 - \floatname{algorithm}{{算法}} + \floatname{algorithm}{{算法}\footnotemark[1]} \renewcommand{\thealgorithm}{} % 去掉算法标号 \caption{} \begin{algorithmic}[1] % [1]显示步数 \STATE 测试 \end{algorithmic} \end{algorithm} +\footnotetext[1]{脚注} \clearpage \section{Q learning算法} \begin{algorithm}[H] % [H]固定位置 @@ -55,7 +56,7 @@ \STATE 初始化Q表$Q(s,a)$为任意值,但其中$Q(s_{terminal},)=0$,即终止状态对应的Q值为0 \FOR {回合数 = $1,M$} \STATE 重置环境,获得初始状态$s_1$ - \FOR {时步 = $1,t$} + \FOR {时步 = $1,T$} \STATE 根据$\varepsilon-greedy$策略采样动作$a_t$ \STATE 环境根据$a_t$反馈奖励$r_t$和下一个状态$s_{t+1}$ \STATE {\bfseries 更新策略:} @@ -134,7 +135,7 @@ \STATE 初始化策略参数$\boldsymbol{\theta} \in \mathbb{R}^{d^{\prime}}($ e.g., to $\mathbf{0})$ \FOR {回合数 = $1,M$} \STATE 根据策略$\pi(\cdot \mid \cdot, \boldsymbol{\theta})$采样一个(或几个)回合的transition - \FOR {时步 = $1,t$} + \FOR {时步 = $0,1,2,...,T-1$} \STATE 计算回报$G \leftarrow \sum_{k=t+1}^{T} \gamma^{k-t-1} R_{k}$ \STATE 更新策略$\boldsymbol{\theta} \leftarrow {\boldsymbol{\theta}+\alpha \gamma^{t}} G \nabla \ln \pi\left(A_{t} \mid S_{t}, \boldsymbol{\theta}\right)$ \ENDFOR @@ -164,6 +165,65 @@ \end{algorithm} \footnotetext[1]{这里结合TD error的特性按照从$t+1$到$1$计算法Advantage更方便} +\clearpage + +\section{PPO-Clip算法} +\begin{algorithm}[H] % [H]固定位置 + \floatname{algorithm}{{PPO-Clip算法}\footnotemark[1]\footnotemark[2]} + \renewcommand{\thealgorithm}{} % 去掉算法标号 + \caption{} + \begin{algorithmic}[1] % [1]显示步数 + \STATE 初始化策略网络(Actor)参数$\theta$和价值网络(Critic)参数$\phi$ + \STATE 初始化Clip参数$\epsilon$ + \STATE 初始化epoch数量$K$ + \STATE 初始化经验回放$D$ + \STATE 初始化总时步数$c=0$ + \FOR {回合数 = $1,2,\cdots,M$} + \STATE 重置环境,获得初始状态$s_0$ + \FOR {时步 $t = 1,2,\cdots,T$} + \STATE 计数总时步$c \leftarrow c+1$ + \STATE 根据策略$\pi_{\theta}$选择$a_t$ + \STATE 环境根据$a_t$反馈奖励$r_t$和下一个状态$s_{t+1}$ + \STATE 存储$(s_t,a_t,r_t,s_{t+1})$到经验回放$D$中 + \IF{$c$被$C$整除\footnotemark[3]} + \FOR {$k= 1,2,\cdots,K$} + \STATE 测试 + \ENDFOR + \STATE 清空经验回放$D$ + \ENDIF + \ENDFOR + \ENDFOR + \end{algorithmic} +\end{algorithm} +\footnotetext[1]{Proximal Policy Optimization Algorithms} +\footnotetext[2]{https://spinningup.openai.com/en/latest/algorithms/ppo.html} +\footnotetext[3]{\bfseries 即每$C$个时步更新策略} +\clearpage +\section{DDPG算法} +\begin{algorithm}[H] % [H]固定位置 + \floatname{algorithm}{{DDPG算法}\footnotemark[1]} + \renewcommand{\thealgorithm}{} % 去掉算法标号 + \caption{} + \begin{algorithmic}[1] % [1]显示步数 + \STATE 初始化critic网络$Q\left(s, a \mid \theta^Q\right)$和actor网络$\mu(s|\theta^{\mu})$的参数$\theta^Q$和$\theta^{\mu}$ + \STATE 初始化对应的目标网络参数,即$\theta^{Q^{\prime}} \leftarrow \theta^Q, \theta^{\mu^{\prime}} \leftarrow \theta^\mu$ + \STATE 初始化经验回放$R$ + \FOR {回合数 = $1,M$} + \STATE 选择动作$a_t=\mu\left(s_t \mid \theta^\mu\right)+\mathcal{N}_t$,$\mathcal{N}_t$为探索噪声 + \STATE 环境根据$a_t$反馈奖励$s_t$和下一个状态$s_{t+1}$ + \STATE 存储transition$(s_t,a_t,r_t,s_{t+1})$到经验回放$R$中 + \STATE 更新环境状态$s_{t+1} \leftarrow s_t$ + \STATE {\bfseries 更新策略:} + \STATE 从$R$中取出一个随机批量的$(s_i,a_i,r_i,s_{i+1})$ + \STATE 求得$y_i=r_i+\gamma Q^{\prime}\left(s_{i+1}, \mu^{\prime}\left(s_{i+1} \mid \theta^{\mu^{\prime}}\right) \mid \theta^{Q^{\prime}}\right)$ + \STATE 更新critic参数,其损失为:$L=\frac{1}{N} \sum_i\left(y_i-Q\left(s_i, a_i \mid \theta^Q\right)\right)^2$ + \STATE 更新actor参数:$\left.\left.\nabla_{\theta^\mu} J \approx \frac{1}{N} \sum_i \nabla_a Q\left(s, a \mid \theta^Q\right)\right|_{s=s_i, a=\mu\left(s_i\right)} \nabla_{\theta^\mu} \mu\left(s \mid \theta^\mu\right)\right|_{s_i}$ + \STATE 软更新目标网络:$\theta^{Q^{\prime}} \leftarrow \tau \theta^Q+(1-\tau) \theta^{Q^{\prime}}$, + $\theta^{\mu^{\prime}} \leftarrow \tau \theta^\mu+(1-\tau) \theta^{\mu^{\prime}}$ + \ENDFOR + \end{algorithmic} +\end{algorithm} +\footnotetext[1]{Continuous control with deep reinforcement learning} \clearpage \section{SoftQ算法} \begin{algorithm}[H] diff --git a/projects/codes/A2C/README.md b/projects/codes/A2C/README.md new file mode 100644 index 0000000..5252838 --- /dev/null +++ b/projects/codes/A2C/README.md @@ -0,0 +1,7 @@ +## 脚本描述 + +* `task0.py`:离散动作任务 + +* `task1.py`:离散动作任务,与`task0.py`唯一的区别就是Actor的激活函数是tanh而不是relu,在`CartPole-v1`上效果更好 + +* `task2.py`:连续动作任务,#TODO待调试 \ No newline at end of file diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/config.yaml b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/config.yaml new file mode 100644 index 0000000..865f5bb --- /dev/null +++ b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/config.yaml @@ -0,0 +1,24 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: CartPole-v1 + eval_eps: 10 + load_checkpoint: true + load_path: Train_CartPole-v1_A2C_20221030-211435 + max_steps: 200 + mode: test + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 1000 +algo_cfg: + actor_hidden_dim: 256 + actor_lr: 0.0003 + batch_size: 64 + buffer_size: 100000 + critic_hidden_dim: 256 + critic_lr: 0.001 + gamma: 0.99 + hidden_dim: 256 + target_update: 4 diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/logs/log.txt b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/logs/log.txt new file mode 100644 index 0000000..0ecfa0a --- /dev/null +++ b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/logs/log.txt @@ -0,0 +1,23 @@ +2022-10-30 21:25:53 - r - INFO: - n_states: 4, n_actions: 2 +2022-10-30 21:25:55 - r - INFO: - Start testing! +2022-10-30 21:25:55 - r - INFO: - Env: CartPole-v1, Algorithm: A2C, Device: cuda +2022-10-30 21:25:56 - r - INFO: - Episode: 1/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 2/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 3/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 4/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 5/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 6/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 7/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 8/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 9/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:56 - r - INFO: - Episode: 10/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 11/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 12/20, Reward: 190.0, Step: 190 +2022-10-30 21:25:57 - r - INFO: - Episode: 13/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 14/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 15/20, Reward: 96.0, Step: 96 +2022-10-30 21:25:57 - r - INFO: - Episode: 16/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 17/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 18/20, Reward: 200.0, Step: 200 +2022-10-30 21:25:57 - r - INFO: - Episode: 19/20, Reward: 112.0, Step: 112 +2022-10-30 21:25:57 - r - INFO: - Episode: 20/20, Reward: 200.0, Step: 200 diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/models/actor_checkpoint.pt b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/models/actor_checkpoint.pt new file mode 100644 index 0000000..89d0854 Binary files /dev/null and b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/models/actor_checkpoint.pt differ diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/models/critic_checkpoint.pt b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/models/critic_checkpoint.pt new file mode 100644 index 0000000..720f388 Binary files /dev/null and b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/models/critic_checkpoint.pt differ diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/results/learning_curve.png b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/results/learning_curve.png new file mode 100644 index 0000000..bfee34b Binary files /dev/null and b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/results/learning_curve.png differ diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/results/res.csv b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/results/res.csv new file mode 100644 index 0000000..ce0e7d1 --- /dev/null +++ b/projects/codes/A2C/Test_CartPole-v1_A2C_20221030-212553/results/res.csv @@ -0,0 +1,21 @@ +episodes,rewards,steps +0,200.0,200 +1,200.0,200 +2,200.0,200 +3,200.0,200 +4,200.0,200 +5,200.0,200 +6,200.0,200 +7,200.0,200 +8,200.0,200 +9,200.0,200 +10,200.0,200 +11,190.0,190 +12,200.0,200 +13,200.0,200 +14,96.0,96 +15,200.0,200 +16,200.0,200 +17,200.0,200 +18,112.0,112 +19,200.0,200 diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/config.yaml b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/config.yaml new file mode 100644 index 0000000..709a1e3 --- /dev/null +++ b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/config.yaml @@ -0,0 +1,25 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: CartPole-v1 + eval_eps: 10 + eval_per_episode: 5 + load_checkpoint: true + load_path: Train_CartPole-v1_A2C_20221031-232138 + max_steps: 200 + mode: test + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 1000 +algo_cfg: + actor_hidden_dim: 256 + actor_lr: 0.0003 + batch_size: 64 + buffer_size: 100000 + critic_hidden_dim: 256 + critic_lr: 0.001 + gamma: 0.99 + hidden_dim: 256 + target_update: 4 diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/logs/log.txt b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/logs/log.txt new file mode 100644 index 0000000..d84edb2 --- /dev/null +++ b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/logs/log.txt @@ -0,0 +1,28 @@ +2022-10-31 23:33:16 - r - INFO: - n_states: 4, n_actions: 2 +2022-10-31 23:33:16 - r - INFO: - Actor model name: ActorSoftmaxTanh +2022-10-31 23:33:16 - r - INFO: - Critic model name: Critic +2022-10-31 23:33:16 - r - INFO: - ACMemory memory name: PGReplay +2022-10-31 23:33:16 - r - INFO: - agent name: A2C +2022-10-31 23:33:17 - r - INFO: - Start testing! +2022-10-31 23:33:17 - r - INFO: - Env: CartPole-v1, Algorithm: A2C, Device: cuda +2022-10-31 23:33:18 - r - INFO: - Episode: 1/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:18 - r - INFO: - Episode: 2/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:18 - r - INFO: - Episode: 3/20, Reward: 186.0, Step: 186 +2022-10-31 23:33:18 - r - INFO: - Episode: 4/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:18 - r - INFO: - Episode: 5/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 6/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 7/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 8/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 9/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 10/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 11/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 12/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 13/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 14/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 15/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 16/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 17/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 18/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:19 - r - INFO: - Episode: 19/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:20 - r - INFO: - Episode: 20/20, Reward: 200.0, Step: 200 +2022-10-31 23:33:20 - r - INFO: - Finish testing! diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/models/actor_checkpoint.pt b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/models/actor_checkpoint.pt new file mode 100644 index 0000000..05bd7b6 Binary files /dev/null and b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/models/actor_checkpoint.pt differ diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/models/critic_checkpoint.pt b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/models/critic_checkpoint.pt new file mode 100644 index 0000000..720f388 Binary files /dev/null and b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/models/critic_checkpoint.pt differ diff --git a/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/results/learning_curve.png b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/results/learning_curve.png new file mode 100644 index 0000000..33274af Binary files /dev/null and b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/results/learning_curve.png differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/testing_results.csv b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/results/res.csv similarity index 54% rename from projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/testing_results.csv rename to projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/results/res.csv index 221744d..571b1e6 100644 --- a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/testing_results.csv +++ b/projects/codes/A2C/Test_CartPole-v1_A2C_20221031-233316/results/res.csv @@ -1,21 +1,21 @@ episodes,rewards,steps 0,200.0,200 1,200.0,200 -2,93.0,93 -3,155.0,155 -4,116.0,116 +2,186.0,186 +3,200.0,200 +4,200.0,200 5,200.0,200 -6,190.0,190 -7,176.0,176 +6,200.0,200 +7,200.0,200 8,200.0,200 9,200.0,200 10,200.0,200 -11,179.0,179 +11,200.0,200 12,200.0,200 -13,185.0,185 -14,191.0,191 +13,200.0,200 +14,200.0,200 15,200.0,200 16,200.0,200 -17,124.0,124 +17,200.0,200 18,200.0,200 -19,172.0,172 +19,200.0,200 diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/config.yaml b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/config.yaml new file mode 100644 index 0000000..7dde5b7 --- /dev/null +++ b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/config.yaml @@ -0,0 +1,23 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: CartPole-v1 + eval_eps: 10 + load_checkpoint: false + load_path: tasks + max_steps: 200 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 1000 +algo_cfg: + actor_hidden_dim: 256 + actor_lr: 0.0003 + batch_size: 64 + buffer_size: 100000 + critic_hidden_dim: 256 + critic_lr: 0.001 + gamma: 0.99 + hidden_dim: 256 diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/logs/log.txt b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/logs/log.txt new file mode 100644 index 0000000..b13b335 --- /dev/null +++ b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/logs/log.txt @@ -0,0 +1,1066 @@ +2022-10-30 21:14:35 - r - INFO: - n_states: 4, n_actions: 2 +2022-10-30 21:14:35 - r - INFO: - Start training! +2022-10-30 21:14:35 - r - INFO: - Env: CartPole-v1, Algorithm: A2C, Device: cuda +2022-10-30 21:14:37 - r - INFO: - Episode: 1/1000, Reward: 25.0, Step: 25 +2022-10-30 21:14:38 - r - INFO: - Current episode 1 has the best eval reward: 29.2 +2022-10-30 21:14:38 - r - INFO: - Episode: 2/1000, Reward: 13.0, Step: 13 +2022-10-30 21:14:38 - r - INFO: - Episode: 3/1000, Reward: 58.0, Step: 58 +2022-10-30 21:14:38 - r - INFO: - Episode: 4/1000, Reward: 10.0, Step: 10 +2022-10-30 21:14:38 - r - INFO: - Episode: 5/1000, Reward: 39.0, Step: 39 +2022-10-30 21:14:38 - r - INFO: - Episode: 6/1000, Reward: 39.0, Step: 39 +2022-10-30 21:14:38 - r - INFO: - Episode: 7/1000, Reward: 25.0, Step: 25 +2022-10-30 21:14:39 - r - INFO: - Episode: 8/1000, Reward: 22.0, Step: 22 +2022-10-30 21:14:39 - r - INFO: - Episode: 9/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:39 - r - INFO: - Episode: 10/1000, Reward: 27.0, Step: 27 +2022-10-30 21:14:39 - r - INFO: - Episode: 11/1000, Reward: 35.0, Step: 35 +2022-10-30 21:14:40 - r - INFO: - Episode: 12/1000, Reward: 26.0, Step: 26 +2022-10-30 21:14:40 - r - INFO: - Episode: 13/1000, Reward: 38.0, Step: 38 +2022-10-30 21:14:40 - r - INFO: - Episode: 14/1000, Reward: 29.0, Step: 29 +2022-10-30 21:14:40 - r - INFO: - Episode: 15/1000, Reward: 50.0, Step: 50 +2022-10-30 21:14:40 - r - INFO: - Episode: 16/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:40 - r - INFO: - Episode: 17/1000, Reward: 52.0, Step: 52 +2022-10-30 21:14:41 - r - INFO: - Current episode 17 has the best eval reward: 32.9 +2022-10-30 21:14:41 - r - INFO: - Episode: 18/1000, Reward: 12.0, Step: 12 +2022-10-30 21:14:41 - r - INFO: - Episode: 19/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:41 - r - INFO: - Episode: 20/1000, Reward: 38.0, Step: 38 +2022-10-30 21:14:41 - r - INFO: - Current episode 20 has the best eval reward: 38.9 +2022-10-30 21:14:41 - r - INFO: - Episode: 21/1000, Reward: 22.0, Step: 22 +2022-10-30 21:14:41 - r - INFO: - Episode: 22/1000, Reward: 36.0, Step: 36 +2022-10-30 21:14:42 - r - INFO: - Episode: 23/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:42 - r - INFO: - Episode: 24/1000, Reward: 35.0, Step: 35 +2022-10-30 21:14:42 - r - INFO: - Episode: 25/1000, Reward: 90.0, Step: 90 +2022-10-30 21:14:42 - r - INFO: - Episode: 26/1000, Reward: 29.0, Step: 29 +2022-10-30 21:14:42 - r - INFO: - Episode: 27/1000, Reward: 16.0, Step: 16 +2022-10-30 21:14:43 - r - INFO: - Episode: 28/1000, Reward: 25.0, Step: 25 +2022-10-30 21:14:43 - r - INFO: - Episode: 29/1000, Reward: 46.0, Step: 46 +2022-10-30 21:14:43 - r - INFO: - Episode: 30/1000, Reward: 33.0, Step: 33 +2022-10-30 21:14:43 - r - INFO: - Episode: 31/1000, Reward: 11.0, Step: 11 +2022-10-30 21:14:43 - r - INFO: - Episode: 32/1000, Reward: 27.0, Step: 27 +2022-10-30 21:14:44 - r - INFO: - Episode: 33/1000, Reward: 32.0, Step: 32 +2022-10-30 21:14:44 - r - INFO: - Current episode 33 has the best eval reward: 39.2 +2022-10-30 21:14:44 - r - INFO: - Episode: 34/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:44 - r - INFO: - Episode: 35/1000, Reward: 11.0, Step: 11 +2022-10-30 21:14:44 - r - INFO: - Episode: 36/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:44 - r - INFO: - Episode: 37/1000, Reward: 51.0, Step: 51 +2022-10-30 21:14:44 - r - INFO: - Episode: 38/1000, Reward: 29.0, Step: 29 +2022-10-30 21:14:45 - r - INFO: - Current episode 38 has the best eval reward: 41.7 +2022-10-30 21:14:45 - r - INFO: - Episode: 39/1000, Reward: 50.0, Step: 50 +2022-10-30 21:14:45 - r - INFO: - Current episode 39 has the best eval reward: 48.5 +2022-10-30 21:14:45 - r - INFO: - Episode: 40/1000, Reward: 19.0, Step: 19 +2022-10-30 21:14:45 - r - INFO: - Episode: 41/1000, Reward: 41.0, Step: 41 +2022-10-30 21:14:45 - r - INFO: - Episode: 42/1000, Reward: 28.0, Step: 28 +2022-10-30 21:14:46 - r - INFO: - Episode: 43/1000, Reward: 71.0, Step: 71 +2022-10-30 21:14:46 - r - INFO: - Episode: 44/1000, Reward: 45.0, Step: 45 +2022-10-30 21:14:46 - r - INFO: - Episode: 45/1000, Reward: 42.0, Step: 42 +2022-10-30 21:14:46 - r - INFO: - Current episode 45 has the best eval reward: 49.6 +2022-10-30 21:14:46 - r - INFO: - Episode: 46/1000, Reward: 39.0, Step: 39 +2022-10-30 21:14:47 - r - INFO: - Episode: 47/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:47 - r - INFO: - Episode: 48/1000, Reward: 14.0, Step: 14 +2022-10-30 21:14:47 - r - INFO: - Episode: 49/1000, Reward: 23.0, Step: 23 +2022-10-30 21:14:47 - r - INFO: - Episode: 50/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:47 - r - INFO: - Episode: 51/1000, Reward: 34.0, Step: 34 +2022-10-30 21:14:48 - r - INFO: - Episode: 52/1000, Reward: 14.0, Step: 14 +2022-10-30 21:14:48 - r - INFO: - Episode: 53/1000, Reward: 41.0, Step: 41 +2022-10-30 21:14:48 - r - INFO: - Episode: 54/1000, Reward: 99.0, Step: 99 +2022-10-30 21:14:48 - r - INFO: - Episode: 55/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:49 - r - INFO: - Episode: 56/1000, Reward: 52.0, Step: 52 +2022-10-30 21:14:49 - r - INFO: - Episode: 57/1000, Reward: 34.0, Step: 34 +2022-10-30 21:14:49 - r - INFO: - Episode: 58/1000, Reward: 73.0, Step: 73 +2022-10-30 21:14:49 - r - INFO: - Episode: 59/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:49 - r - INFO: - Episode: 60/1000, Reward: 27.0, Step: 27 +2022-10-30 21:14:50 - r - INFO: - Episode: 61/1000, Reward: 51.0, Step: 51 +2022-10-30 21:14:50 - r - INFO: - Episode: 62/1000, Reward: 46.0, Step: 46 +2022-10-30 21:14:50 - r - INFO: - Episode: 63/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:50 - r - INFO: - Episode: 64/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:51 - r - INFO: - Episode: 65/1000, Reward: 44.0, Step: 44 +2022-10-30 21:14:51 - r - INFO: - Episode: 66/1000, Reward: 16.0, Step: 16 +2022-10-30 21:14:51 - r - INFO: - Episode: 67/1000, Reward: 39.0, Step: 39 +2022-10-30 21:14:51 - r - INFO: - Episode: 68/1000, Reward: 30.0, Step: 30 +2022-10-30 21:14:51 - r - INFO: - Episode: 69/1000, Reward: 37.0, Step: 37 +2022-10-30 21:14:52 - r - INFO: - Episode: 70/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:52 - r - INFO: - Episode: 71/1000, Reward: 21.0, Step: 21 +2022-10-30 21:14:52 - r - INFO: - Episode: 72/1000, Reward: 13.0, Step: 13 +2022-10-30 21:14:52 - r - INFO: - Episode: 73/1000, Reward: 65.0, Step: 65 +2022-10-30 21:14:53 - r - INFO: - Episode: 74/1000, Reward: 45.0, Step: 45 +2022-10-30 21:14:53 - r - INFO: - Episode: 75/1000, Reward: 45.0, Step: 45 +2022-10-30 21:14:53 - r - INFO: - Episode: 76/1000, Reward: 46.0, Step: 46 +2022-10-30 21:14:53 - r - INFO: - Episode: 77/1000, Reward: 13.0, Step: 13 +2022-10-30 21:14:53 - r - INFO: - Episode: 78/1000, Reward: 33.0, Step: 33 +2022-10-30 21:14:54 - r - INFO: - Episode: 79/1000, Reward: 30.0, Step: 30 +2022-10-30 21:14:54 - r - INFO: - Episode: 80/1000, Reward: 52.0, Step: 52 +2022-10-30 21:14:54 - r - INFO: - Episode: 81/1000, Reward: 27.0, Step: 27 +2022-10-30 21:14:54 - r - INFO: - Episode: 82/1000, Reward: 30.0, Step: 30 +2022-10-30 21:14:55 - r - INFO: - Episode: 83/1000, Reward: 47.0, Step: 47 +2022-10-30 21:14:55 - r - INFO: - Episode: 84/1000, Reward: 56.0, Step: 56 +2022-10-30 21:14:55 - r - INFO: - Episode: 85/1000, Reward: 19.0, Step: 19 +2022-10-30 21:14:55 - r - INFO: - Episode: 86/1000, Reward: 33.0, Step: 33 +2022-10-30 21:14:56 - r - INFO: - Episode: 87/1000, Reward: 25.0, Step: 25 +2022-10-30 21:14:56 - r - INFO: - Episode: 88/1000, Reward: 41.0, Step: 41 +2022-10-30 21:14:56 - r - INFO: - Episode: 89/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:56 - r - INFO: - Episode: 90/1000, Reward: 58.0, Step: 58 +2022-10-30 21:14:56 - r - INFO: - Episode: 91/1000, Reward: 35.0, Step: 35 +2022-10-30 21:14:57 - r - INFO: - Episode: 92/1000, Reward: 23.0, Step: 23 +2022-10-30 21:14:57 - r - INFO: - Episode: 93/1000, Reward: 12.0, Step: 12 +2022-10-30 21:14:57 - r - INFO: - Episode: 94/1000, Reward: 20.0, Step: 20 +2022-10-30 21:14:57 - r - INFO: - Episode: 95/1000, Reward: 10.0, Step: 10 +2022-10-30 21:14:57 - r - INFO: - Episode: 96/1000, Reward: 49.0, Step: 49 +2022-10-30 21:14:58 - r - INFO: - Episode: 97/1000, Reward: 29.0, Step: 29 +2022-10-30 21:14:58 - r - INFO: - Episode: 98/1000, Reward: 35.0, Step: 35 +2022-10-30 21:14:58 - r - INFO: - Episode: 99/1000, Reward: 36.0, Step: 36 +2022-10-30 21:14:58 - r - INFO: - Current episode 99 has the best eval reward: 53.4 +2022-10-30 21:14:58 - r - INFO: - Episode: 100/1000, Reward: 36.0, Step: 36 +2022-10-30 21:14:59 - r - INFO: - Episode: 101/1000, Reward: 16.0, Step: 16 +2022-10-30 21:14:59 - r - INFO: - Episode: 102/1000, Reward: 36.0, Step: 36 +2022-10-30 21:14:59 - r - INFO: - Current episode 102 has the best eval reward: 70.3 +2022-10-30 21:14:59 - r - INFO: - Episode: 103/1000, Reward: 30.0, Step: 30 +2022-10-30 21:15:00 - r - INFO: - Episode: 104/1000, Reward: 76.0, Step: 76 +2022-10-30 21:15:00 - r - INFO: - Episode: 105/1000, Reward: 52.0, Step: 52 +2022-10-30 21:15:00 - r - INFO: - Episode: 106/1000, Reward: 39.0, Step: 39 +2022-10-30 21:15:00 - r - INFO: - Episode: 107/1000, Reward: 52.0, Step: 52 +2022-10-30 21:15:01 - r - INFO: - Episode: 108/1000, Reward: 69.0, Step: 69 +2022-10-30 21:15:01 - r - INFO: - Episode: 109/1000, Reward: 27.0, Step: 27 +2022-10-30 21:15:01 - r - INFO: - Episode: 110/1000, Reward: 14.0, Step: 14 +2022-10-30 21:15:01 - r - INFO: - Episode: 111/1000, Reward: 28.0, Step: 28 +2022-10-30 21:15:01 - r - INFO: - Episode: 112/1000, Reward: 12.0, Step: 12 +2022-10-30 21:15:02 - r - INFO: - Episode: 113/1000, Reward: 26.0, Step: 26 +2022-10-30 21:15:03 - r - INFO: - Episode: 114/1000, Reward: 50.0, Step: 50 +2022-10-30 21:15:03 - r - INFO: - Episode: 115/1000, Reward: 25.0, Step: 25 +2022-10-30 21:15:03 - r - INFO: - Episode: 116/1000, Reward: 53.0, Step: 53 +2022-10-30 21:15:03 - r - INFO: - Episode: 117/1000, Reward: 19.0, Step: 19 +2022-10-30 21:15:04 - r - INFO: - Episode: 118/1000, Reward: 33.0, Step: 33 +2022-10-30 21:15:04 - r - INFO: - Episode: 119/1000, Reward: 34.0, Step: 34 +2022-10-30 21:15:04 - r - INFO: - Episode: 120/1000, Reward: 41.0, Step: 41 +2022-10-30 21:15:04 - r - INFO: - Episode: 121/1000, Reward: 25.0, Step: 25 +2022-10-30 21:15:05 - r - INFO: - Episode: 122/1000, Reward: 18.0, Step: 18 +2022-10-30 21:15:05 - r - INFO: - Episode: 123/1000, Reward: 114.0, Step: 114 +2022-10-30 21:15:05 - r - INFO: - Episode: 124/1000, Reward: 25.0, Step: 25 +2022-10-30 21:15:05 - r - INFO: - Episode: 125/1000, Reward: 46.0, Step: 46 +2022-10-30 21:15:06 - r - INFO: - Episode: 126/1000, Reward: 22.0, Step: 22 +2022-10-30 21:15:06 - r - INFO: - Episode: 127/1000, Reward: 71.0, Step: 71 +2022-10-30 21:15:06 - r - INFO: - Episode: 128/1000, Reward: 30.0, Step: 30 +2022-10-30 21:15:07 - r - INFO: - Episode: 129/1000, Reward: 130.0, Step: 130 +2022-10-30 21:15:07 - r - INFO: - Episode: 130/1000, Reward: 65.0, Step: 65 +2022-10-30 21:15:07 - r - INFO: - Episode: 131/1000, Reward: 55.0, Step: 55 +2022-10-30 21:15:07 - r - INFO: - Episode: 132/1000, Reward: 37.0, Step: 37 +2022-10-30 21:15:08 - r - INFO: - Episode: 133/1000, Reward: 46.0, Step: 46 +2022-10-30 21:15:08 - r - INFO: - Episode: 134/1000, Reward: 65.0, Step: 65 +2022-10-30 21:15:08 - r - INFO: - Episode: 135/1000, Reward: 31.0, Step: 31 +2022-10-30 21:15:08 - r - INFO: - Episode: 136/1000, Reward: 33.0, Step: 33 +2022-10-30 21:15:09 - r - INFO: - Episode: 137/1000, Reward: 39.0, Step: 39 +2022-10-30 21:15:09 - r - INFO: - Episode: 138/1000, Reward: 73.0, Step: 73 +2022-10-30 21:15:09 - r - INFO: - Episode: 139/1000, Reward: 78.0, Step: 78 +2022-10-30 21:15:10 - r - INFO: - Episode: 140/1000, Reward: 36.0, Step: 36 +2022-10-30 21:15:10 - r - INFO: - Episode: 141/1000, Reward: 56.0, Step: 56 +2022-10-30 21:15:10 - r - INFO: - Episode: 142/1000, Reward: 12.0, Step: 12 +2022-10-30 21:15:10 - r - INFO: - Episode: 143/1000, Reward: 36.0, Step: 36 +2022-10-30 21:15:11 - r - INFO: - Episode: 144/1000, Reward: 13.0, Step: 13 +2022-10-30 21:15:11 - r - INFO: - Episode: 145/1000, Reward: 85.0, Step: 85 +2022-10-30 21:15:11 - r - INFO: - Episode: 146/1000, Reward: 34.0, Step: 34 +2022-10-30 21:15:11 - r - INFO: - Episode: 147/1000, Reward: 16.0, Step: 16 +2022-10-30 21:15:12 - r - INFO: - Episode: 148/1000, Reward: 68.0, Step: 68 +2022-10-30 21:15:12 - r - INFO: - Episode: 149/1000, Reward: 94.0, Step: 94 +2022-10-30 21:15:12 - r - INFO: - Episode: 150/1000, Reward: 17.0, Step: 17 +2022-10-30 21:15:13 - r - INFO: - Episode: 151/1000, Reward: 64.0, Step: 64 +2022-10-30 21:15:13 - r - INFO: - Episode: 152/1000, Reward: 33.0, Step: 33 +2022-10-30 21:15:13 - r - INFO: - Episode: 153/1000, Reward: 63.0, Step: 63 +2022-10-30 21:15:13 - r - INFO: - Episode: 154/1000, Reward: 39.0, Step: 39 +2022-10-30 21:15:14 - r - INFO: - Episode: 155/1000, Reward: 72.0, Step: 72 +2022-10-30 21:15:14 - r - INFO: - Episode: 156/1000, Reward: 39.0, Step: 39 +2022-10-30 21:15:14 - r - INFO: - Episode: 157/1000, Reward: 37.0, Step: 37 +2022-10-30 21:15:14 - r - INFO: - Episode: 158/1000, Reward: 18.0, Step: 18 +2022-10-30 21:15:15 - r - INFO: - Episode: 159/1000, Reward: 55.0, Step: 55 +2022-10-30 21:15:15 - r - INFO: - Episode: 160/1000, Reward: 21.0, Step: 21 +2022-10-30 21:15:15 - r - INFO: - Episode: 161/1000, Reward: 54.0, Step: 54 +2022-10-30 21:15:15 - r - INFO: - Episode: 162/1000, Reward: 46.0, Step: 46 +2022-10-30 21:15:16 - r - INFO: - Episode: 163/1000, Reward: 21.0, Step: 21 +2022-10-30 21:15:16 - r - INFO: - Episode: 164/1000, Reward: 26.0, Step: 26 +2022-10-30 21:15:16 - r - INFO: - Episode: 165/1000, Reward: 70.0, Step: 70 +2022-10-30 21:15:17 - r - INFO: - Episode: 166/1000, Reward: 20.0, Step: 20 +2022-10-30 21:15:17 - r - INFO: - Episode: 167/1000, Reward: 41.0, Step: 41 +2022-10-30 21:15:17 - r - INFO: - Episode: 168/1000, Reward: 77.0, Step: 77 +2022-10-30 21:15:17 - r - INFO: - Episode: 169/1000, Reward: 13.0, Step: 13 +2022-10-30 21:15:18 - r - INFO: - Episode: 170/1000, Reward: 66.0, Step: 66 +2022-10-30 21:15:18 - r - INFO: - Episode: 171/1000, Reward: 72.0, Step: 72 +2022-10-30 21:15:18 - r - INFO: - Episode: 172/1000, Reward: 28.0, Step: 28 +2022-10-30 21:15:19 - r - INFO: - Episode: 173/1000, Reward: 68.0, Step: 68 +2022-10-30 21:15:19 - r - INFO: - Episode: 174/1000, Reward: 124.0, Step: 124 +2022-10-30 21:15:19 - r - INFO: - Episode: 175/1000, Reward: 41.0, Step: 41 +2022-10-30 21:15:20 - r - INFO: - Episode: 176/1000, Reward: 54.0, Step: 54 +2022-10-30 21:15:20 - r - INFO: - Episode: 177/1000, Reward: 33.0, Step: 33 +2022-10-30 21:15:20 - r - INFO: - Episode: 178/1000, Reward: 92.0, Step: 92 +2022-10-30 21:15:20 - r - INFO: - Episode: 179/1000, Reward: 23.0, Step: 23 +2022-10-30 21:15:21 - r - INFO: - Episode: 180/1000, Reward: 76.0, Step: 76 +2022-10-30 21:15:21 - r - INFO: - Episode: 181/1000, Reward: 47.0, Step: 47 +2022-10-30 21:15:22 - r - INFO: - Episode: 182/1000, Reward: 89.0, Step: 89 +2022-10-30 21:15:22 - r - INFO: - Episode: 183/1000, Reward: 84.0, Step: 84 +2022-10-30 21:15:22 - r - INFO: - Episode: 184/1000, Reward: 75.0, Step: 75 +2022-10-30 21:15:23 - r - INFO: - Episode: 185/1000, Reward: 64.0, Step: 64 +2022-10-30 21:15:23 - r - INFO: - Episode: 186/1000, Reward: 35.0, Step: 35 +2022-10-30 21:15:23 - r - INFO: - Episode: 187/1000, Reward: 44.0, Step: 44 +2022-10-30 21:15:24 - r - INFO: - Episode: 188/1000, Reward: 46.0, Step: 46 +2022-10-30 21:15:24 - r - INFO: - Episode: 189/1000, Reward: 67.0, Step: 67 +2022-10-30 21:15:25 - r - INFO: - Episode: 190/1000, Reward: 82.0, Step: 82 +2022-10-30 21:15:25 - r - INFO: - Episode: 191/1000, Reward: 55.0, Step: 55 +2022-10-30 21:15:25 - r - INFO: - Episode: 192/1000, Reward: 26.0, Step: 26 +2022-10-30 21:15:26 - r - INFO: - Episode: 193/1000, Reward: 116.0, Step: 116 +2022-10-30 21:15:26 - r - INFO: - Episode: 194/1000, Reward: 116.0, Step: 116 +2022-10-30 21:15:26 - r - INFO: - Episode: 195/1000, Reward: 119.0, Step: 119 +2022-10-30 21:15:27 - r - INFO: - Episode: 196/1000, Reward: 50.0, Step: 50 +2022-10-30 21:15:27 - r - INFO: - Episode: 197/1000, Reward: 43.0, Step: 43 +2022-10-30 21:15:27 - r - INFO: - Episode: 198/1000, Reward: 47.0, Step: 47 +2022-10-30 21:15:28 - r - INFO: - Episode: 199/1000, Reward: 71.0, Step: 71 +2022-10-30 21:15:28 - r - INFO: - Episode: 200/1000, Reward: 53.0, Step: 53 +2022-10-30 21:15:28 - r - INFO: - Current episode 200 has the best eval reward: 86.0 +2022-10-30 21:15:29 - r - INFO: - Episode: 201/1000, Reward: 137.0, Step: 137 +2022-10-30 21:15:29 - r - INFO: - Episode: 202/1000, Reward: 82.0, Step: 82 +2022-10-30 21:15:30 - r - INFO: - Episode: 203/1000, Reward: 120.0, Step: 120 +2022-10-30 21:15:30 - r - INFO: - Current episode 203 has the best eval reward: 92.8 +2022-10-30 21:15:30 - r - INFO: - Episode: 204/1000, Reward: 69.0, Step: 69 +2022-10-30 21:15:31 - r - INFO: - Episode: 205/1000, Reward: 55.0, Step: 55 +2022-10-30 21:15:31 - r - INFO: - Episode: 206/1000, Reward: 62.0, Step: 62 +2022-10-30 21:15:31 - r - INFO: - Episode: 207/1000, Reward: 64.0, Step: 64 +2022-10-30 21:15:32 - r - INFO: - Episode: 208/1000, Reward: 49.0, Step: 49 +2022-10-30 21:15:32 - r - INFO: - Episode: 209/1000, Reward: 32.0, Step: 32 +2022-10-30 21:15:33 - r - INFO: - Episode: 210/1000, Reward: 42.0, Step: 42 +2022-10-30 21:15:33 - r - INFO: - Episode: 211/1000, Reward: 50.0, Step: 50 +2022-10-30 21:15:33 - r - INFO: - Episode: 212/1000, Reward: 93.0, Step: 93 +2022-10-30 21:15:34 - r - INFO: - Episode: 213/1000, Reward: 60.0, Step: 60 +2022-10-30 21:15:34 - r - INFO: - Episode: 214/1000, Reward: 54.0, Step: 54 +2022-10-30 21:15:35 - r - INFO: - Episode: 215/1000, Reward: 68.0, Step: 68 +2022-10-30 21:15:35 - r - INFO: - Episode: 216/1000, Reward: 84.0, Step: 84 +2022-10-30 21:15:35 - r - INFO: - Current episode 216 has the best eval reward: 94.6 +2022-10-30 21:15:36 - r - INFO: - Episode: 217/1000, Reward: 55.0, Step: 55 +2022-10-30 21:15:36 - r - INFO: - Episode: 218/1000, Reward: 70.0, Step: 70 +2022-10-30 21:15:37 - r - INFO: - Episode: 219/1000, Reward: 115.0, Step: 115 +2022-10-30 21:15:37 - r - INFO: - Episode: 220/1000, Reward: 149.0, Step: 149 +2022-10-30 21:15:38 - r - INFO: - Episode: 221/1000, Reward: 68.0, Step: 68 +2022-10-30 21:15:38 - r - INFO: - Episode: 222/1000, Reward: 50.0, Step: 50 +2022-10-30 21:15:38 - r - INFO: - Current episode 222 has the best eval reward: 95.5 +2022-10-30 21:15:39 - r - INFO: - Episode: 223/1000, Reward: 56.0, Step: 56 +2022-10-30 21:15:39 - r - INFO: - Episode: 224/1000, Reward: 61.0, Step: 61 +2022-10-30 21:15:39 - r - INFO: - Episode: 225/1000, Reward: 117.0, Step: 117 +2022-10-30 21:15:40 - r - INFO: - Episode: 226/1000, Reward: 66.0, Step: 66 +2022-10-30 21:15:41 - r - INFO: - Episode: 227/1000, Reward: 127.0, Step: 127 +2022-10-30 21:15:41 - r - INFO: - Episode: 228/1000, Reward: 66.0, Step: 66 +2022-10-30 21:15:42 - r - INFO: - Episode: 229/1000, Reward: 48.0, Step: 48 +2022-10-30 21:15:42 - r - INFO: - Episode: 230/1000, Reward: 36.0, Step: 36 +2022-10-30 21:15:42 - r - INFO: - Episode: 231/1000, Reward: 79.0, Step: 79 +2022-10-30 21:15:43 - r - INFO: - Episode: 232/1000, Reward: 49.0, Step: 49 +2022-10-30 21:15:43 - r - INFO: - Episode: 233/1000, Reward: 55.0, Step: 55 +2022-10-30 21:15:43 - r - INFO: - Episode: 234/1000, Reward: 41.0, Step: 41 +2022-10-30 21:15:43 - r - INFO: - Episode: 235/1000, Reward: 20.0, Step: 20 +2022-10-30 21:15:44 - r - INFO: - Episode: 236/1000, Reward: 40.0, Step: 40 +2022-10-30 21:15:44 - r - INFO: - Episode: 237/1000, Reward: 120.0, Step: 120 +2022-10-30 21:15:44 - r - INFO: - Episode: 238/1000, Reward: 27.0, Step: 27 +2022-10-30 21:15:45 - r - INFO: - Episode: 239/1000, Reward: 51.0, Step: 51 +2022-10-30 21:15:45 - r - INFO: - Episode: 240/1000, Reward: 35.0, Step: 35 +2022-10-30 21:15:45 - r - INFO: - Episode: 241/1000, Reward: 43.0, Step: 43 +2022-10-30 21:15:46 - r - INFO: - Episode: 242/1000, Reward: 54.0, Step: 54 +2022-10-30 21:15:46 - r - INFO: - Episode: 243/1000, Reward: 52.0, Step: 52 +2022-10-30 21:15:46 - r - INFO: - Episode: 244/1000, Reward: 47.0, Step: 47 +2022-10-30 21:15:46 - r - INFO: - Episode: 245/1000, Reward: 63.0, Step: 63 +2022-10-30 21:15:47 - r - INFO: - Episode: 246/1000, Reward: 29.0, Step: 29 +2022-10-30 21:15:47 - r - INFO: - Episode: 247/1000, Reward: 36.0, Step: 36 +2022-10-30 21:15:47 - r - INFO: - Episode: 248/1000, Reward: 58.0, Step: 58 +2022-10-30 21:15:48 - r - INFO: - Episode: 249/1000, Reward: 63.0, Step: 63 +2022-10-30 21:15:48 - r - INFO: - Episode: 250/1000, Reward: 49.0, Step: 49 +2022-10-30 21:15:48 - r - INFO: - Episode: 251/1000, Reward: 70.0, Step: 70 +2022-10-30 21:15:49 - r - INFO: - Episode: 252/1000, Reward: 114.0, Step: 114 +2022-10-30 21:15:49 - r - INFO: - Episode: 253/1000, Reward: 62.0, Step: 62 +2022-10-30 21:15:50 - r - INFO: - Episode: 254/1000, Reward: 73.0, Step: 73 +2022-10-30 21:15:50 - r - INFO: - Current episode 254 has the best eval reward: 96.7 +2022-10-30 21:15:50 - r - INFO: - Episode: 255/1000, Reward: 62.0, Step: 62 +2022-10-30 21:15:51 - r - INFO: - Episode: 256/1000, Reward: 61.0, Step: 61 +2022-10-30 21:15:51 - r - INFO: - Episode: 257/1000, Reward: 115.0, Step: 115 +2022-10-30 21:15:52 - r - INFO: - Episode: 258/1000, Reward: 50.0, Step: 50 +2022-10-30 21:15:52 - r - INFO: - Episode: 259/1000, Reward: 128.0, Step: 128 +2022-10-30 21:15:53 - r - INFO: - Current episode 259 has the best eval reward: 104.8 +2022-10-30 21:15:53 - r - INFO: - Episode: 260/1000, Reward: 200.0, Step: 200 +2022-10-30 21:15:53 - r - INFO: - Episode: 261/1000, Reward: 75.0, Step: 75 +2022-10-30 21:15:54 - r - INFO: - Episode: 262/1000, Reward: 64.0, Step: 64 +2022-10-30 21:15:54 - r - INFO: - Episode: 263/1000, Reward: 33.0, Step: 33 +2022-10-30 21:15:55 - r - INFO: - Episode: 264/1000, Reward: 90.0, Step: 90 +2022-10-30 21:15:55 - r - INFO: - Current episode 264 has the best eval reward: 107.6 +2022-10-30 21:15:56 - r - INFO: - Episode: 265/1000, Reward: 117.0, Step: 117 +2022-10-30 21:15:56 - r - INFO: - Current episode 265 has the best eval reward: 119.4 +2022-10-30 21:15:56 - r - INFO: - Episode: 266/1000, Reward: 60.0, Step: 60 +2022-10-30 21:15:57 - r - INFO: - Episode: 267/1000, Reward: 177.0, Step: 177 +2022-10-30 21:15:57 - r - INFO: - Episode: 268/1000, Reward: 39.0, Step: 39 +2022-10-30 21:15:58 - r - INFO: - Episode: 269/1000, Reward: 40.0, Step: 40 +2022-10-30 21:15:58 - r - INFO: - Episode: 270/1000, Reward: 109.0, Step: 109 +2022-10-30 21:15:59 - r - INFO: - Episode: 271/1000, Reward: 100.0, Step: 100 +2022-10-30 21:16:00 - r - INFO: - Episode: 272/1000, Reward: 99.0, Step: 99 +2022-10-30 21:16:00 - r - INFO: - Episode: 273/1000, Reward: 136.0, Step: 136 +2022-10-30 21:16:01 - r - INFO: - Episode: 274/1000, Reward: 62.0, Step: 62 +2022-10-30 21:16:01 - r - INFO: - Episode: 275/1000, Reward: 100.0, Step: 100 +2022-10-30 21:16:02 - r - INFO: - Current episode 275 has the best eval reward: 120.1 +2022-10-30 21:16:02 - r - INFO: - Episode: 276/1000, Reward: 73.0, Step: 73 +2022-10-30 21:16:03 - r - INFO: - Episode: 277/1000, Reward: 166.0, Step: 166 +2022-10-30 21:16:03 - r - INFO: - Episode: 278/1000, Reward: 74.0, Step: 74 +2022-10-30 21:16:04 - r - INFO: - Current episode 278 has the best eval reward: 121.8 +2022-10-30 21:16:04 - r - INFO: - Episode: 279/1000, Reward: 126.0, Step: 126 +2022-10-30 21:16:05 - r - INFO: - Episode: 280/1000, Reward: 111.0, Step: 111 +2022-10-30 21:16:06 - r - INFO: - Episode: 281/1000, Reward: 198.0, Step: 198 +2022-10-30 21:16:07 - r - INFO: - Episode: 282/1000, Reward: 106.0, Step: 106 +2022-10-30 21:16:07 - r - INFO: - Episode: 283/1000, Reward: 80.0, Step: 80 +2022-10-30 21:16:08 - r - INFO: - Episode: 284/1000, Reward: 74.0, Step: 74 +2022-10-30 21:16:08 - r - INFO: - Episode: 285/1000, Reward: 114.0, Step: 114 +2022-10-30 21:16:09 - r - INFO: - Episode: 286/1000, Reward: 69.0, Step: 69 +2022-10-30 21:16:09 - r - INFO: - Episode: 287/1000, Reward: 98.0, Step: 98 +2022-10-30 21:16:10 - r - INFO: - Episode: 288/1000, Reward: 63.0, Step: 63 +2022-10-30 21:16:10 - r - INFO: - Episode: 289/1000, Reward: 61.0, Step: 61 +2022-10-30 21:16:11 - r - INFO: - Episode: 290/1000, Reward: 49.0, Step: 49 +2022-10-30 21:16:11 - r - INFO: - Episode: 291/1000, Reward: 89.0, Step: 89 +2022-10-30 21:16:12 - r - INFO: - Episode: 292/1000, Reward: 114.0, Step: 114 +2022-10-30 21:16:13 - r - INFO: - Episode: 293/1000, Reward: 103.0, Step: 103 +2022-10-30 21:16:13 - r - INFO: - Episode: 294/1000, Reward: 103.0, Step: 103 +2022-10-30 21:16:14 - r - INFO: - Episode: 295/1000, Reward: 93.0, Step: 93 +2022-10-30 21:16:14 - r - INFO: - Episode: 296/1000, Reward: 137.0, Step: 137 +2022-10-30 21:16:15 - r - INFO: - Episode: 297/1000, Reward: 97.0, Step: 97 +2022-10-30 21:16:16 - r - INFO: - Episode: 298/1000, Reward: 124.0, Step: 124 +2022-10-30 21:16:16 - r - INFO: - Episode: 299/1000, Reward: 147.0, Step: 147 +2022-10-30 21:16:17 - r - INFO: - Episode: 300/1000, Reward: 125.0, Step: 125 +2022-10-30 21:16:18 - r - INFO: - Episode: 301/1000, Reward: 105.0, Step: 105 +2022-10-30 21:16:18 - r - INFO: - Current episode 301 has the best eval reward: 148.8 +2022-10-30 21:16:18 - r - INFO: - Episode: 302/1000, Reward: 113.0, Step: 113 +2022-10-30 21:16:19 - r - INFO: - Current episode 302 has the best eval reward: 150.8 +2022-10-30 21:16:19 - r - INFO: - Episode: 303/1000, Reward: 120.0, Step: 120 +2022-10-30 21:16:20 - r - INFO: - Episode: 304/1000, Reward: 159.0, Step: 159 +2022-10-30 21:16:21 - r - INFO: - Episode: 305/1000, Reward: 190.0, Step: 190 +2022-10-30 21:16:22 - r - INFO: - Current episode 305 has the best eval reward: 183.4 +2022-10-30 21:16:22 - r - INFO: - Episode: 306/1000, Reward: 119.0, Step: 119 +2022-10-30 21:16:23 - r - INFO: - Episode: 307/1000, Reward: 200.0, Step: 200 +2022-10-30 21:16:24 - r - INFO: - Episode: 308/1000, Reward: 148.0, Step: 148 +2022-10-30 21:16:25 - r - INFO: - Episode: 309/1000, Reward: 200.0, Step: 200 +2022-10-30 21:16:26 - r - INFO: - Episode: 310/1000, Reward: 79.0, Step: 79 +2022-10-30 21:16:27 - r - INFO: - Episode: 311/1000, Reward: 115.0, Step: 115 +2022-10-30 21:16:28 - r - INFO: - Episode: 312/1000, Reward: 147.0, Step: 147 +2022-10-30 21:16:29 - r - INFO: - Episode: 313/1000, Reward: 112.0, Step: 112 +2022-10-30 21:16:29 - r - INFO: - Episode: 314/1000, Reward: 125.0, Step: 125 +2022-10-30 21:16:30 - r - INFO: - Episode: 315/1000, Reward: 184.0, Step: 184 +2022-10-30 21:16:31 - r - INFO: - Episode: 316/1000, Reward: 193.0, Step: 193 +2022-10-30 21:16:32 - r - INFO: - Episode: 317/1000, Reward: 117.0, Step: 117 +2022-10-30 21:16:33 - r - INFO: - Episode: 318/1000, Reward: 153.0, Step: 153 +2022-10-30 21:16:34 - r - INFO: - Episode: 319/1000, Reward: 125.0, Step: 125 +2022-10-30 21:16:35 - r - INFO: - Episode: 320/1000, Reward: 184.0, Step: 184 +2022-10-30 21:16:36 - r - INFO: - Episode: 321/1000, Reward: 173.0, Step: 173 +2022-10-30 21:16:36 - r - INFO: - Episode: 322/1000, Reward: 117.0, Step: 117 +2022-10-30 21:16:37 - r - INFO: - Episode: 323/1000, Reward: 47.0, Step: 47 +2022-10-30 21:16:38 - r - INFO: - Episode: 324/1000, Reward: 107.0, Step: 107 +2022-10-30 21:16:38 - r - INFO: - Episode: 325/1000, Reward: 104.0, Step: 104 +2022-10-30 21:16:39 - r - INFO: - Episode: 326/1000, Reward: 114.0, Step: 114 +2022-10-30 21:16:39 - r - INFO: - Episode: 327/1000, Reward: 90.0, Step: 90 +2022-10-30 21:16:40 - r - INFO: - Episode: 328/1000, Reward: 112.0, Step: 112 +2022-10-30 21:16:41 - r - INFO: - Episode: 329/1000, Reward: 70.0, Step: 70 +2022-10-30 21:16:41 - r - INFO: - Episode: 330/1000, Reward: 74.0, Step: 74 +2022-10-30 21:16:42 - r - INFO: - Episode: 331/1000, Reward: 159.0, Step: 159 +2022-10-30 21:16:42 - r - INFO: - Episode: 332/1000, Reward: 39.0, Step: 39 +2022-10-30 21:16:43 - r - INFO: - Episode: 333/1000, Reward: 129.0, Step: 129 +2022-10-30 21:16:44 - r - INFO: - Episode: 334/1000, Reward: 50.0, Step: 50 +2022-10-30 21:16:44 - r - INFO: - Episode: 335/1000, Reward: 74.0, Step: 74 +2022-10-30 21:16:44 - r - INFO: - Episode: 336/1000, Reward: 31.0, Step: 31 +2022-10-30 21:16:45 - r - INFO: - Episode: 337/1000, Reward: 57.0, Step: 57 +2022-10-30 21:16:45 - r - INFO: - Episode: 338/1000, Reward: 71.0, Step: 71 +2022-10-30 21:16:46 - r - INFO: - Episode: 339/1000, Reward: 43.0, Step: 43 +2022-10-30 21:16:46 - r - INFO: - Episode: 340/1000, Reward: 41.0, Step: 41 +2022-10-30 21:16:46 - r - INFO: - Episode: 341/1000, Reward: 64.0, Step: 64 +2022-10-30 21:16:47 - r - INFO: - Episode: 342/1000, Reward: 38.0, Step: 38 +2022-10-30 21:16:47 - r - INFO: - Episode: 343/1000, Reward: 45.0, Step: 45 +2022-10-30 21:16:48 - r - INFO: - Episode: 344/1000, Reward: 120.0, Step: 120 +2022-10-30 21:16:48 - r - INFO: - Episode: 345/1000, Reward: 40.0, Step: 40 +2022-10-30 21:16:48 - r - INFO: - Episode: 346/1000, Reward: 46.0, Step: 46 +2022-10-30 21:16:48 - r - INFO: - Episode: 347/1000, Reward: 57.0, Step: 57 +2022-10-30 21:16:49 - r - INFO: - Episode: 348/1000, Reward: 29.0, Step: 29 +2022-10-30 21:16:49 - r - INFO: - Episode: 349/1000, Reward: 29.0, Step: 29 +2022-10-30 21:16:49 - r - INFO: - Episode: 350/1000, Reward: 50.0, Step: 50 +2022-10-30 21:16:50 - r - INFO: - Episode: 351/1000, Reward: 38.0, Step: 38 +2022-10-30 21:16:50 - r - INFO: - Episode: 352/1000, Reward: 51.0, Step: 51 +2022-10-30 21:16:50 - r - INFO: - Episode: 353/1000, Reward: 49.0, Step: 49 +2022-10-30 21:16:50 - r - INFO: - Episode: 354/1000, Reward: 30.0, Step: 30 +2022-10-30 21:16:51 - r - INFO: - Episode: 355/1000, Reward: 40.0, Step: 40 +2022-10-30 21:16:51 - r - INFO: - Episode: 356/1000, Reward: 45.0, Step: 45 +2022-10-30 21:16:51 - r - INFO: - Episode: 357/1000, Reward: 68.0, Step: 68 +2022-10-30 21:16:52 - r - INFO: - Episode: 358/1000, Reward: 27.0, Step: 27 +2022-10-30 21:16:52 - r - INFO: - Episode: 359/1000, Reward: 18.0, Step: 18 +2022-10-30 21:16:52 - r - INFO: - Episode: 360/1000, Reward: 26.0, Step: 26 +2022-10-30 21:16:52 - r - INFO: - Episode: 361/1000, Reward: 15.0, Step: 15 +2022-10-30 21:16:52 - r - INFO: - Episode: 362/1000, Reward: 65.0, Step: 65 +2022-10-30 21:16:53 - r - INFO: - Episode: 363/1000, Reward: 38.0, Step: 38 +2022-10-30 21:16:53 - r - INFO: - Episode: 364/1000, Reward: 41.0, Step: 41 +2022-10-30 21:16:53 - r - INFO: - Episode: 365/1000, Reward: 61.0, Step: 61 +2022-10-30 21:16:54 - r - INFO: - Episode: 366/1000, Reward: 113.0, Step: 113 +2022-10-30 21:16:54 - r - INFO: - Episode: 367/1000, Reward: 39.0, Step: 39 +2022-10-30 21:16:54 - r - INFO: - Episode: 368/1000, Reward: 60.0, Step: 60 +2022-10-30 21:16:55 - r - INFO: - Episode: 369/1000, Reward: 134.0, Step: 134 +2022-10-30 21:16:56 - r - INFO: - Episode: 370/1000, Reward: 122.0, Step: 122 +2022-10-30 21:16:56 - r - INFO: - Episode: 371/1000, Reward: 34.0, Step: 34 +2022-10-30 21:16:57 - r - INFO: - Episode: 372/1000, Reward: 129.0, Step: 129 +2022-10-30 21:16:57 - r - INFO: - Episode: 373/1000, Reward: 40.0, Step: 40 +2022-10-30 21:16:58 - r - INFO: - Episode: 374/1000, Reward: 128.0, Step: 128 +2022-10-30 21:16:59 - r - INFO: - Episode: 375/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:00 - r - INFO: - Episode: 376/1000, Reward: 108.0, Step: 108 +2022-10-30 21:17:01 - r - INFO: - Episode: 377/1000, Reward: 108.0, Step: 108 +2022-10-30 21:17:02 - r - INFO: - Episode: 378/1000, Reward: 151.0, Step: 151 +2022-10-30 21:17:03 - r - INFO: - Episode: 379/1000, Reward: 79.0, Step: 79 +2022-10-30 21:17:03 - r - INFO: - Episode: 380/1000, Reward: 105.0, Step: 105 +2022-10-30 21:17:04 - r - INFO: - Episode: 381/1000, Reward: 87.0, Step: 87 +2022-10-30 21:17:05 - r - INFO: - Episode: 382/1000, Reward: 94.0, Step: 94 +2022-10-30 21:17:06 - r - INFO: - Episode: 383/1000, Reward: 112.0, Step: 112 +2022-10-30 21:17:07 - r - INFO: - Episode: 384/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:08 - r - INFO: - Episode: 385/1000, Reward: 184.0, Step: 184 +2022-10-30 21:17:08 - r - INFO: - Episode: 386/1000, Reward: 124.0, Step: 124 +2022-10-30 21:17:09 - r - INFO: - Episode: 387/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:11 - r - INFO: - Episode: 388/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:12 - r - INFO: - Episode: 389/1000, Reward: 109.0, Step: 109 +2022-10-30 21:17:12 - r - INFO: - Episode: 390/1000, Reward: 88.0, Step: 88 +2022-10-30 21:17:13 - r - INFO: - Episode: 391/1000, Reward: 104.0, Step: 104 +2022-10-30 21:17:14 - r - INFO: - Episode: 392/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:15 - r - INFO: - Episode: 393/1000, Reward: 84.0, Step: 84 +2022-10-30 21:17:16 - r - INFO: - Episode: 394/1000, Reward: 187.0, Step: 187 +2022-10-30 21:17:17 - r - INFO: - Episode: 395/1000, Reward: 182.0, Step: 182 +2022-10-30 21:17:18 - r - INFO: - Episode: 396/1000, Reward: 148.0, Step: 148 +2022-10-30 21:17:19 - r - INFO: - Episode: 397/1000, Reward: 86.0, Step: 86 +2022-10-30 21:17:20 - r - INFO: - Episode: 398/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:21 - r - INFO: - Episode: 399/1000, Reward: 199.0, Step: 199 +2022-10-30 21:17:22 - r - INFO: - Episode: 400/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:23 - r - INFO: - Episode: 401/1000, Reward: 92.0, Step: 92 +2022-10-30 21:17:23 - r - INFO: - Episode: 402/1000, Reward: 112.0, Step: 112 +2022-10-30 21:17:24 - r - INFO: - Episode: 403/1000, Reward: 86.0, Step: 86 +2022-10-30 21:17:25 - r - INFO: - Episode: 404/1000, Reward: 114.0, Step: 114 +2022-10-30 21:17:26 - r - INFO: - Episode: 405/1000, Reward: 90.0, Step: 90 +2022-10-30 21:17:26 - r - INFO: - Episode: 406/1000, Reward: 101.0, Step: 101 +2022-10-30 21:17:27 - r - INFO: - Episode: 407/1000, Reward: 111.0, Step: 111 +2022-10-30 21:17:28 - r - INFO: - Episode: 408/1000, Reward: 107.0, Step: 107 +2022-10-30 21:17:28 - r - INFO: - Episode: 409/1000, Reward: 120.0, Step: 120 +2022-10-30 21:17:29 - r - INFO: - Episode: 410/1000, Reward: 114.0, Step: 114 +2022-10-30 21:17:30 - r - INFO: - Episode: 411/1000, Reward: 97.0, Step: 97 +2022-10-30 21:17:30 - r - INFO: - Episode: 412/1000, Reward: 95.0, Step: 95 +2022-10-30 21:17:31 - r - INFO: - Episode: 413/1000, Reward: 126.0, Step: 126 +2022-10-30 21:17:32 - r - INFO: - Episode: 414/1000, Reward: 111.0, Step: 111 +2022-10-30 21:17:33 - r - INFO: - Episode: 415/1000, Reward: 120.0, Step: 120 +2022-10-30 21:17:33 - r - INFO: - Episode: 416/1000, Reward: 178.0, Step: 178 +2022-10-30 21:17:34 - r - INFO: - Episode: 417/1000, Reward: 97.0, Step: 97 +2022-10-30 21:17:35 - r - INFO: - Episode: 418/1000, Reward: 144.0, Step: 144 +2022-10-30 21:17:36 - r - INFO: - Episode: 419/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:36 - r - INFO: - Episode: 420/1000, Reward: 190.0, Step: 190 +2022-10-30 21:17:37 - r - INFO: - Episode: 421/1000, Reward: 29.0, Step: 29 +2022-10-30 21:17:38 - r - INFO: - Episode: 422/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:38 - r - INFO: - Episode: 423/1000, Reward: 116.0, Step: 116 +2022-10-30 21:17:39 - r - INFO: - Episode: 424/1000, Reward: 200.0, Step: 200 +2022-10-30 21:17:40 - r - INFO: - Episode: 425/1000, Reward: 107.0, Step: 107 +2022-10-30 21:17:41 - r - INFO: - Episode: 426/1000, Reward: 128.0, Step: 128 +2022-10-30 21:17:41 - r - INFO: - Episode: 427/1000, Reward: 164.0, Step: 164 +2022-10-30 21:17:42 - r - INFO: - Episode: 428/1000, Reward: 30.0, Step: 30 +2022-10-30 21:17:42 - r - INFO: - Episode: 429/1000, Reward: 122.0, Step: 122 +2022-10-30 21:17:43 - r - INFO: - Episode: 430/1000, Reward: 110.0, Step: 110 +2022-10-30 21:17:44 - r - INFO: - Episode: 431/1000, Reward: 105.0, Step: 105 +2022-10-30 21:17:44 - r - INFO: - Episode: 432/1000, Reward: 137.0, Step: 137 +2022-10-30 21:17:45 - r - INFO: - Episode: 433/1000, Reward: 110.0, Step: 110 +2022-10-30 21:17:45 - r - INFO: - Episode: 434/1000, Reward: 111.0, Step: 111 +2022-10-30 21:17:46 - r - INFO: - Episode: 435/1000, Reward: 33.0, Step: 33 +2022-10-30 21:17:46 - r - INFO: - Episode: 436/1000, Reward: 100.0, Step: 100 +2022-10-30 21:17:47 - r - INFO: - Episode: 437/1000, Reward: 131.0, Step: 131 +2022-10-30 21:17:48 - r - INFO: - Episode: 438/1000, Reward: 99.0, Step: 99 +2022-10-30 21:17:48 - r - INFO: - Episode: 439/1000, Reward: 118.0, Step: 118 +2022-10-30 21:17:49 - r - INFO: - Episode: 440/1000, Reward: 98.0, Step: 98 +2022-10-30 21:17:49 - r - INFO: - Episode: 441/1000, Reward: 119.0, Step: 119 +2022-10-30 21:17:50 - r - INFO: - Episode: 442/1000, Reward: 41.0, Step: 41 +2022-10-30 21:17:50 - r - INFO: - Episode: 443/1000, Reward: 107.0, Step: 107 +2022-10-30 21:17:51 - r - INFO: - Episode: 444/1000, Reward: 41.0, Step: 41 +2022-10-30 21:17:52 - r - INFO: - Episode: 445/1000, Reward: 113.0, Step: 113 +2022-10-30 21:17:52 - r - INFO: - Episode: 446/1000, Reward: 113.0, Step: 113 +2022-10-30 21:17:53 - r - INFO: - Episode: 447/1000, Reward: 117.0, Step: 117 +2022-10-30 21:17:54 - r - INFO: - Episode: 448/1000, Reward: 140.0, Step: 140 +2022-10-30 21:17:54 - r - INFO: - Episode: 449/1000, Reward: 133.0, Step: 133 +2022-10-30 21:17:55 - r - INFO: - Episode: 450/1000, Reward: 108.0, Step: 108 +2022-10-30 21:17:56 - r - INFO: - Episode: 451/1000, Reward: 117.0, Step: 117 +2022-10-30 21:17:57 - r - INFO: - Episode: 452/1000, Reward: 40.0, Step: 40 +2022-10-30 21:17:57 - r - INFO: - Episode: 453/1000, Reward: 108.0, Step: 108 +2022-10-30 21:17:58 - r - INFO: - Episode: 454/1000, Reward: 140.0, Step: 140 +2022-10-30 21:17:59 - r - INFO: - Episode: 455/1000, Reward: 133.0, Step: 133 +2022-10-30 21:18:00 - r - INFO: - Episode: 456/1000, Reward: 115.0, Step: 115 +2022-10-30 21:18:00 - r - INFO: - Episode: 457/1000, Reward: 30.0, Step: 30 +2022-10-30 21:18:01 - r - INFO: - Episode: 458/1000, Reward: 119.0, Step: 119 +2022-10-30 21:18:02 - r - INFO: - Episode: 459/1000, Reward: 160.0, Step: 160 +2022-10-30 21:18:02 - r - INFO: - Episode: 460/1000, Reward: 125.0, Step: 125 +2022-10-30 21:18:03 - r - INFO: - Episode: 461/1000, Reward: 161.0, Step: 161 +2022-10-30 21:18:04 - r - INFO: - Episode: 462/1000, Reward: 139.0, Step: 139 +2022-10-30 21:18:05 - r - INFO: - Episode: 463/1000, Reward: 190.0, Step: 190 +2022-10-30 21:18:06 - r - INFO: - Episode: 464/1000, Reward: 149.0, Step: 149 +2022-10-30 21:18:07 - r - INFO: - Episode: 465/1000, Reward: 173.0, Step: 173 +2022-10-30 21:18:08 - r - INFO: - Current episode 465 has the best eval reward: 187.6 +2022-10-30 21:18:08 - r - INFO: - Episode: 466/1000, Reward: 165.0, Step: 165 +2022-10-30 21:18:09 - r - INFO: - Episode: 467/1000, Reward: 82.0, Step: 82 +2022-10-30 21:18:10 - r - INFO: - Episode: 468/1000, Reward: 197.0, Step: 197 +2022-10-30 21:18:11 - r - INFO: - Current episode 468 has the best eval reward: 195.0 +2022-10-30 21:18:12 - r - INFO: - Episode: 469/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:13 - r - INFO: - Episode: 470/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:14 - r - INFO: - Current episode 470 has the best eval reward: 199.4 +2022-10-30 21:18:14 - r - INFO: - Episode: 471/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:16 - r - INFO: - Episode: 472/1000, Reward: 182.0, Step: 182 +2022-10-30 21:18:17 - r - INFO: - Episode: 473/1000, Reward: 118.0, Step: 118 +2022-10-30 21:18:18 - r - INFO: - Episode: 474/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:19 - r - INFO: - Episode: 475/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:20 - r - INFO: - Episode: 476/1000, Reward: 93.0, Step: 93 +2022-10-30 21:18:21 - r - INFO: - Episode: 477/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:23 - r - INFO: - Episode: 478/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:24 - r - INFO: - Episode: 479/1000, Reward: 167.0, Step: 167 +2022-10-30 21:18:25 - r - INFO: - Episode: 480/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:26 - r - INFO: - Episode: 481/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:27 - r - INFO: - Episode: 482/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:28 - r - INFO: - Episode: 483/1000, Reward: 190.0, Step: 190 +2022-10-30 21:18:29 - r - INFO: - Episode: 484/1000, Reward: 86.0, Step: 86 +2022-10-30 21:18:30 - r - INFO: - Episode: 485/1000, Reward: 166.0, Step: 166 +2022-10-30 21:18:31 - r - INFO: - Episode: 486/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:32 - r - INFO: - Episode: 487/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:33 - r - INFO: - Episode: 488/1000, Reward: 172.0, Step: 172 +2022-10-30 21:18:34 - r - INFO: - Episode: 489/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:35 - r - INFO: - Episode: 490/1000, Reward: 102.0, Step: 102 +2022-10-30 21:18:36 - r - INFO: - Episode: 491/1000, Reward: 194.0, Step: 194 +2022-10-30 21:18:37 - r - INFO: - Episode: 492/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:38 - r - INFO: - Episode: 493/1000, Reward: 179.0, Step: 179 +2022-10-30 21:18:39 - r - INFO: - Episode: 494/1000, Reward: 187.0, Step: 187 +2022-10-30 21:18:40 - r - INFO: - Episode: 495/1000, Reward: 200.0, Step: 200 +2022-10-30 21:18:41 - r - INFO: - Episode: 496/1000, Reward: 89.0, Step: 89 +2022-10-30 21:18:41 - r - INFO: - Episode: 497/1000, Reward: 169.0, Step: 169 +2022-10-30 21:18:42 - r - INFO: - Episode: 498/1000, Reward: 28.0, Step: 28 +2022-10-30 21:18:43 - r - INFO: - Episode: 499/1000, Reward: 160.0, Step: 160 +2022-10-30 21:18:44 - r - INFO: - Episode: 500/1000, Reward: 140.0, Step: 140 +2022-10-30 21:18:44 - r - INFO: - Episode: 501/1000, Reward: 37.0, Step: 37 +2022-10-30 21:18:45 - r - INFO: - Episode: 502/1000, Reward: 32.0, Step: 32 +2022-10-30 21:18:45 - r - INFO: - Episode: 503/1000, Reward: 129.0, Step: 129 +2022-10-30 21:18:46 - r - INFO: - Episode: 504/1000, Reward: 22.0, Step: 22 +2022-10-30 21:18:46 - r - INFO: - Episode: 505/1000, Reward: 124.0, Step: 124 +2022-10-30 21:18:46 - r - INFO: - Episode: 506/1000, Reward: 24.0, Step: 24 +2022-10-30 21:18:47 - r - INFO: - Episode: 507/1000, Reward: 115.0, Step: 115 +2022-10-30 21:18:47 - r - INFO: - Episode: 508/1000, Reward: 24.0, Step: 24 +2022-10-30 21:18:48 - r - INFO: - Episode: 509/1000, Reward: 38.0, Step: 38 +2022-10-30 21:18:49 - r - INFO: - Episode: 510/1000, Reward: 24.0, Step: 24 +2022-10-30 21:18:49 - r - INFO: - Episode: 511/1000, Reward: 23.0, Step: 23 +2022-10-30 21:18:49 - r - INFO: - Episode: 512/1000, Reward: 125.0, Step: 125 +2022-10-30 21:18:49 - r - INFO: - Episode: 513/1000, Reward: 22.0, Step: 22 +2022-10-30 21:18:50 - r - INFO: - Episode: 514/1000, Reward: 24.0, Step: 24 +2022-10-30 21:18:50 - r - INFO: - Episode: 515/1000, Reward: 20.0, Step: 20 +2022-10-30 21:18:50 - r - INFO: - Episode: 516/1000, Reward: 25.0, Step: 25 +2022-10-30 21:18:50 - r - INFO: - Episode: 517/1000, Reward: 31.0, Step: 31 +2022-10-30 21:18:50 - r - INFO: - Episode: 518/1000, Reward: 23.0, Step: 23 +2022-10-30 21:18:51 - r - INFO: - Episode: 519/1000, Reward: 30.0, Step: 30 +2022-10-30 21:18:51 - r - INFO: - Episode: 520/1000, Reward: 101.0, Step: 101 +2022-10-30 21:18:51 - r - INFO: - Episode: 521/1000, Reward: 25.0, Step: 25 +2022-10-30 21:18:52 - r - INFO: - Episode: 522/1000, Reward: 22.0, Step: 22 +2022-10-30 21:18:52 - r - INFO: - Episode: 523/1000, Reward: 20.0, Step: 20 +2022-10-30 21:18:52 - r - INFO: - Episode: 524/1000, Reward: 16.0, Step: 16 +2022-10-30 21:18:53 - r - INFO: - Episode: 525/1000, Reward: 104.0, Step: 104 +2022-10-30 21:18:53 - r - INFO: - Episode: 526/1000, Reward: 17.0, Step: 17 +2022-10-30 21:18:53 - r - INFO: - Episode: 527/1000, Reward: 108.0, Step: 108 +2022-10-30 21:18:53 - r - INFO: - Episode: 528/1000, Reward: 121.0, Step: 121 +2022-10-30 21:18:54 - r - INFO: - Episode: 529/1000, Reward: 29.0, Step: 29 +2022-10-30 21:18:54 - r - INFO: - Episode: 530/1000, Reward: 29.0, Step: 29 +2022-10-30 21:18:54 - r - INFO: - Episode: 531/1000, Reward: 43.0, Step: 43 +2022-10-30 21:18:55 - r - INFO: - Episode: 532/1000, Reward: 105.0, Step: 105 +2022-10-30 21:18:55 - r - INFO: - Episode: 533/1000, Reward: 130.0, Step: 130 +2022-10-30 21:18:55 - r - INFO: - Episode: 534/1000, Reward: 30.0, Step: 30 +2022-10-30 21:18:56 - r - INFO: - Episode: 535/1000, Reward: 31.0, Step: 31 +2022-10-30 21:18:56 - r - INFO: - Episode: 536/1000, Reward: 30.0, Step: 30 +2022-10-30 21:18:56 - r - INFO: - Episode: 537/1000, Reward: 37.0, Step: 37 +2022-10-30 21:18:57 - r - INFO: - Episode: 538/1000, Reward: 115.0, Step: 115 +2022-10-30 21:18:58 - r - INFO: - Episode: 539/1000, Reward: 110.0, Step: 110 +2022-10-30 21:18:58 - r - INFO: - Episode: 540/1000, Reward: 112.0, Step: 112 +2022-10-30 21:18:59 - r - INFO: - Episode: 541/1000, Reward: 33.0, Step: 33 +2022-10-30 21:18:59 - r - INFO: - Episode: 542/1000, Reward: 120.0, Step: 120 +2022-10-30 21:19:00 - r - INFO: - Episode: 543/1000, Reward: 109.0, Step: 109 +2022-10-30 21:19:01 - r - INFO: - Episode: 544/1000, Reward: 122.0, Step: 122 +2022-10-30 21:19:01 - r - INFO: - Episode: 545/1000, Reward: 115.0, Step: 115 +2022-10-30 21:19:02 - r - INFO: - Episode: 546/1000, Reward: 34.0, Step: 34 +2022-10-30 21:19:02 - r - INFO: - Episode: 547/1000, Reward: 28.0, Step: 28 +2022-10-30 21:19:03 - r - INFO: - Episode: 548/1000, Reward: 29.0, Step: 29 +2022-10-30 21:19:03 - r - INFO: - Episode: 549/1000, Reward: 113.0, Step: 113 +2022-10-30 21:19:04 - r - INFO: - Episode: 550/1000, Reward: 100.0, Step: 100 +2022-10-30 21:19:04 - r - INFO: - Episode: 551/1000, Reward: 26.0, Step: 26 +2022-10-30 21:19:04 - r - INFO: - Episode: 552/1000, Reward: 24.0, Step: 24 +2022-10-30 21:19:05 - r - INFO: - Episode: 553/1000, Reward: 26.0, Step: 26 +2022-10-30 21:19:05 - r - INFO: - Episode: 554/1000, Reward: 102.0, Step: 102 +2022-10-30 21:19:05 - r - INFO: - Episode: 555/1000, Reward: 18.0, Step: 18 +2022-10-30 21:19:06 - r - INFO: - Episode: 556/1000, Reward: 107.0, Step: 107 +2022-10-30 21:19:06 - r - INFO: - Episode: 557/1000, Reward: 27.0, Step: 27 +2022-10-30 21:19:06 - r - INFO: - Episode: 558/1000, Reward: 87.0, Step: 87 +2022-10-30 21:19:07 - r - INFO: - Episode: 559/1000, Reward: 29.0, Step: 29 +2022-10-30 21:19:07 - r - INFO: - Episode: 560/1000, Reward: 31.0, Step: 31 +2022-10-30 21:19:07 - r - INFO: - Episode: 561/1000, Reward: 112.0, Step: 112 +2022-10-30 21:19:08 - r - INFO: - Episode: 562/1000, Reward: 112.0, Step: 112 +2022-10-30 21:19:09 - r - INFO: - Episode: 563/1000, Reward: 108.0, Step: 108 +2022-10-30 21:19:09 - r - INFO: - Episode: 564/1000, Reward: 98.0, Step: 98 +2022-10-30 21:19:10 - r - INFO: - Episode: 565/1000, Reward: 104.0, Step: 104 +2022-10-30 21:19:10 - r - INFO: - Episode: 566/1000, Reward: 116.0, Step: 116 +2022-10-30 21:19:11 - r - INFO: - Episode: 567/1000, Reward: 123.0, Step: 123 +2022-10-30 21:19:12 - r - INFO: - Episode: 568/1000, Reward: 105.0, Step: 105 +2022-10-30 21:19:12 - r - INFO: - Episode: 569/1000, Reward: 133.0, Step: 133 +2022-10-30 21:19:13 - r - INFO: - Episode: 570/1000, Reward: 116.0, Step: 116 +2022-10-30 21:19:14 - r - INFO: - Episode: 571/1000, Reward: 128.0, Step: 128 +2022-10-30 21:19:15 - r - INFO: - Episode: 572/1000, Reward: 130.0, Step: 130 +2022-10-30 21:19:15 - r - INFO: - Episode: 573/1000, Reward: 113.0, Step: 113 +2022-10-30 21:19:16 - r - INFO: - Episode: 574/1000, Reward: 143.0, Step: 143 +2022-10-30 21:19:17 - r - INFO: - Episode: 575/1000, Reward: 145.0, Step: 145 +2022-10-30 21:19:18 - r - INFO: - Episode: 576/1000, Reward: 159.0, Step: 159 +2022-10-30 21:19:19 - r - INFO: - Episode: 577/1000, Reward: 150.0, Step: 150 +2022-10-30 21:19:19 - r - INFO: - Episode: 578/1000, Reward: 130.0, Step: 130 +2022-10-30 21:19:20 - r - INFO: - Episode: 579/1000, Reward: 145.0, Step: 145 +2022-10-30 21:19:21 - r - INFO: - Episode: 580/1000, Reward: 173.0, Step: 173 +2022-10-30 21:19:22 - r - INFO: - Episode: 581/1000, Reward: 154.0, Step: 154 +2022-10-30 21:19:23 - r - INFO: - Episode: 582/1000, Reward: 131.0, Step: 131 +2022-10-30 21:19:24 - r - INFO: - Episode: 583/1000, Reward: 163.0, Step: 163 +2022-10-30 21:19:25 - r - INFO: - Episode: 584/1000, Reward: 160.0, Step: 160 +2022-10-30 21:19:26 - r - INFO: - Episode: 585/1000, Reward: 181.0, Step: 181 +2022-10-30 21:19:27 - r - INFO: - Episode: 586/1000, Reward: 161.0, Step: 161 +2022-10-30 21:19:28 - r - INFO: - Episode: 587/1000, Reward: 169.0, Step: 169 +2022-10-30 21:19:29 - r - INFO: - Episode: 588/1000, Reward: 150.0, Step: 150 +2022-10-30 21:19:30 - r - INFO: - Episode: 589/1000, Reward: 176.0, Step: 176 +2022-10-30 21:19:31 - r - INFO: - Episode: 590/1000, Reward: 157.0, Step: 157 +2022-10-30 21:19:32 - r - INFO: - Episode: 591/1000, Reward: 167.0, Step: 167 +2022-10-30 21:19:33 - r - INFO: - Episode: 592/1000, Reward: 168.0, Step: 168 +2022-10-30 21:19:34 - r - INFO: - Episode: 593/1000, Reward: 135.0, Step: 135 +2022-10-30 21:19:35 - r - INFO: - Episode: 594/1000, Reward: 157.0, Step: 157 +2022-10-30 21:19:35 - r - INFO: - Episode: 595/1000, Reward: 138.0, Step: 138 +2022-10-30 21:19:36 - r - INFO: - Episode: 596/1000, Reward: 139.0, Step: 139 +2022-10-30 21:19:37 - r - INFO: - Episode: 597/1000, Reward: 146.0, Step: 146 +2022-10-30 21:19:38 - r - INFO: - Episode: 598/1000, Reward: 121.0, Step: 121 +2022-10-30 21:19:39 - r - INFO: - Episode: 599/1000, Reward: 140.0, Step: 140 +2022-10-30 21:19:40 - r - INFO: - Episode: 600/1000, Reward: 124.0, Step: 124 +2022-10-30 21:19:41 - r - INFO: - Episode: 601/1000, Reward: 124.0, Step: 124 +2022-10-30 21:19:42 - r - INFO: - Episode: 602/1000, Reward: 115.0, Step: 115 +2022-10-30 21:19:42 - r - INFO: - Episode: 603/1000, Reward: 129.0, Step: 129 +2022-10-30 21:19:43 - r - INFO: - Episode: 604/1000, Reward: 107.0, Step: 107 +2022-10-30 21:19:44 - r - INFO: - Episode: 605/1000, Reward: 118.0, Step: 118 +2022-10-30 21:19:44 - r - INFO: - Episode: 606/1000, Reward: 108.0, Step: 108 +2022-10-30 21:19:45 - r - INFO: - Episode: 607/1000, Reward: 102.0, Step: 102 +2022-10-30 21:19:46 - r - INFO: - Episode: 608/1000, Reward: 105.0, Step: 105 +2022-10-30 21:19:46 - r - INFO: - Episode: 609/1000, Reward: 103.0, Step: 103 +2022-10-30 21:19:47 - r - INFO: - Episode: 610/1000, Reward: 96.0, Step: 96 +2022-10-30 21:19:47 - r - INFO: - Episode: 611/1000, Reward: 116.0, Step: 116 +2022-10-30 21:19:48 - r - INFO: - Episode: 612/1000, Reward: 51.0, Step: 51 +2022-10-30 21:19:48 - r - INFO: - Episode: 613/1000, Reward: 100.0, Step: 100 +2022-10-30 21:19:49 - r - INFO: - Episode: 614/1000, Reward: 121.0, Step: 121 +2022-10-30 21:19:50 - r - INFO: - Episode: 615/1000, Reward: 109.0, Step: 109 +2022-10-30 21:19:50 - r - INFO: - Episode: 616/1000, Reward: 85.0, Step: 85 +2022-10-30 21:19:51 - r - INFO: - Episode: 617/1000, Reward: 111.0, Step: 111 +2022-10-30 21:19:52 - r - INFO: - Episode: 618/1000, Reward: 91.0, Step: 91 +2022-10-30 21:19:52 - r - INFO: - Episode: 619/1000, Reward: 127.0, Step: 127 +2022-10-30 21:19:53 - r - INFO: - Episode: 620/1000, Reward: 117.0, Step: 117 +2022-10-30 21:19:53 - r - INFO: - Episode: 621/1000, Reward: 104.0, Step: 104 +2022-10-30 21:19:54 - r - INFO: - Episode: 622/1000, Reward: 119.0, Step: 119 +2022-10-30 21:19:55 - r - INFO: - Episode: 623/1000, Reward: 111.0, Step: 111 +2022-10-30 21:19:56 - r - INFO: - Episode: 624/1000, Reward: 132.0, Step: 132 +2022-10-30 21:19:56 - r - INFO: - Episode: 625/1000, Reward: 130.0, Step: 130 +2022-10-30 21:19:57 - r - INFO: - Episode: 626/1000, Reward: 140.0, Step: 140 +2022-10-30 21:19:58 - r - INFO: - Episode: 627/1000, Reward: 95.0, Step: 95 +2022-10-30 21:19:58 - r - INFO: - Episode: 628/1000, Reward: 106.0, Step: 106 +2022-10-30 21:19:59 - r - INFO: - Episode: 629/1000, Reward: 120.0, Step: 120 +2022-10-30 21:20:00 - r - INFO: - Episode: 630/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:00 - r - INFO: - Episode: 631/1000, Reward: 114.0, Step: 114 +2022-10-30 21:20:01 - r - INFO: - Episode: 632/1000, Reward: 126.0, Step: 126 +2022-10-30 21:20:02 - r - INFO: - Episode: 633/1000, Reward: 100.0, Step: 100 +2022-10-30 21:20:03 - r - INFO: - Episode: 634/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:03 - r - INFO: - Episode: 635/1000, Reward: 104.0, Step: 104 +2022-10-30 21:20:04 - r - INFO: - Episode: 636/1000, Reward: 103.0, Step: 103 +2022-10-30 21:20:04 - r - INFO: - Episode: 637/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:05 - r - INFO: - Episode: 638/1000, Reward: 110.0, Step: 110 +2022-10-30 21:20:06 - r - INFO: - Episode: 639/1000, Reward: 131.0, Step: 131 +2022-10-30 21:20:06 - r - INFO: - Episode: 640/1000, Reward: 90.0, Step: 90 +2022-10-30 21:20:07 - r - INFO: - Episode: 641/1000, Reward: 97.0, Step: 97 +2022-10-30 21:20:08 - r - INFO: - Episode: 642/1000, Reward: 104.0, Step: 104 +2022-10-30 21:20:09 - r - INFO: - Episode: 643/1000, Reward: 91.0, Step: 91 +2022-10-30 21:20:09 - r - INFO: - Episode: 644/1000, Reward: 97.0, Step: 97 +2022-10-30 21:20:10 - r - INFO: - Episode: 645/1000, Reward: 109.0, Step: 109 +2022-10-30 21:20:10 - r - INFO: - Episode: 646/1000, Reward: 112.0, Step: 112 +2022-10-30 21:20:11 - r - INFO: - Episode: 647/1000, Reward: 97.0, Step: 97 +2022-10-30 21:20:11 - r - INFO: - Episode: 648/1000, Reward: 32.0, Step: 32 +2022-10-30 21:20:12 - r - INFO: - Episode: 649/1000, Reward: 94.0, Step: 94 +2022-10-30 21:20:13 - r - INFO: - Episode: 650/1000, Reward: 107.0, Step: 107 +2022-10-30 21:20:13 - r - INFO: - Episode: 651/1000, Reward: 61.0, Step: 61 +2022-10-30 21:20:14 - r - INFO: - Episode: 652/1000, Reward: 97.0, Step: 97 +2022-10-30 21:20:14 - r - INFO: - Episode: 653/1000, Reward: 99.0, Step: 99 +2022-10-30 21:20:15 - r - INFO: - Episode: 654/1000, Reward: 76.0, Step: 76 +2022-10-30 21:20:15 - r - INFO: - Episode: 655/1000, Reward: 38.0, Step: 38 +2022-10-30 21:20:15 - r - INFO: - Episode: 656/1000, Reward: 96.0, Step: 96 +2022-10-30 21:20:16 - r - INFO: - Episode: 657/1000, Reward: 96.0, Step: 96 +2022-10-30 21:20:16 - r - INFO: - Episode: 658/1000, Reward: 65.0, Step: 65 +2022-10-30 21:20:17 - r - INFO: - Episode: 659/1000, Reward: 45.0, Step: 45 +2022-10-30 21:20:17 - r - INFO: - Episode: 660/1000, Reward: 91.0, Step: 91 +2022-10-30 21:20:18 - r - INFO: - Episode: 661/1000, Reward: 78.0, Step: 78 +2022-10-30 21:20:18 - r - INFO: - Episode: 662/1000, Reward: 90.0, Step: 90 +2022-10-30 21:20:19 - r - INFO: - Episode: 663/1000, Reward: 92.0, Step: 92 +2022-10-30 21:20:19 - r - INFO: - Episode: 664/1000, Reward: 94.0, Step: 94 +2022-10-30 21:20:20 - r - INFO: - Episode: 665/1000, Reward: 101.0, Step: 101 +2022-10-30 21:20:20 - r - INFO: - Episode: 666/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:21 - r - INFO: - Episode: 667/1000, Reward: 109.0, Step: 109 +2022-10-30 21:20:22 - r - INFO: - Episode: 668/1000, Reward: 99.0, Step: 99 +2022-10-30 21:20:22 - r - INFO: - Episode: 669/1000, Reward: 115.0, Step: 115 +2022-10-30 21:20:23 - r - INFO: - Episode: 670/1000, Reward: 112.0, Step: 112 +2022-10-30 21:20:23 - r - INFO: - Episode: 671/1000, Reward: 113.0, Step: 113 +2022-10-30 21:20:24 - r - INFO: - Episode: 672/1000, Reward: 110.0, Step: 110 +2022-10-30 21:20:25 - r - INFO: - Episode: 673/1000, Reward: 108.0, Step: 108 +2022-10-30 21:20:26 - r - INFO: - Episode: 674/1000, Reward: 112.0, Step: 112 +2022-10-30 21:20:26 - r - INFO: - Episode: 675/1000, Reward: 125.0, Step: 125 +2022-10-30 21:20:27 - r - INFO: - Episode: 676/1000, Reward: 122.0, Step: 122 +2022-10-30 21:20:28 - r - INFO: - Episode: 677/1000, Reward: 114.0, Step: 114 +2022-10-30 21:20:28 - r - INFO: - Episode: 678/1000, Reward: 127.0, Step: 127 +2022-10-30 21:20:29 - r - INFO: - Episode: 679/1000, Reward: 125.0, Step: 125 +2022-10-30 21:20:30 - r - INFO: - Episode: 680/1000, Reward: 112.0, Step: 112 +2022-10-30 21:20:30 - r - INFO: - Episode: 681/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:31 - r - INFO: - Episode: 682/1000, Reward: 124.0, Step: 124 +2022-10-30 21:20:32 - r - INFO: - Episode: 683/1000, Reward: 113.0, Step: 113 +2022-10-30 21:20:33 - r - INFO: - Episode: 684/1000, Reward: 103.0, Step: 103 +2022-10-30 21:20:33 - r - INFO: - Episode: 685/1000, Reward: 119.0, Step: 119 +2022-10-30 21:20:34 - r - INFO: - Episode: 686/1000, Reward: 120.0, Step: 120 +2022-10-30 21:20:35 - r - INFO: - Episode: 687/1000, Reward: 95.0, Step: 95 +2022-10-30 21:20:35 - r - INFO: - Episode: 688/1000, Reward: 100.0, Step: 100 +2022-10-30 21:20:36 - r - INFO: - Episode: 689/1000, Reward: 29.0, Step: 29 +2022-10-30 21:20:36 - r - INFO: - Episode: 690/1000, Reward: 119.0, Step: 119 +2022-10-30 21:20:37 - r - INFO: - Episode: 691/1000, Reward: 107.0, Step: 107 +2022-10-30 21:20:38 - r - INFO: - Episode: 692/1000, Reward: 117.0, Step: 117 +2022-10-30 21:20:38 - r - INFO: - Episode: 693/1000, Reward: 78.0, Step: 78 +2022-10-30 21:20:38 - r - INFO: - Episode: 694/1000, Reward: 35.0, Step: 35 +2022-10-30 21:20:39 - r - INFO: - Episode: 695/1000, Reward: 101.0, Step: 101 +2022-10-30 21:20:40 - r - INFO: - Episode: 696/1000, Reward: 98.0, Step: 98 +2022-10-30 21:20:40 - r - INFO: - Episode: 697/1000, Reward: 94.0, Step: 94 +2022-10-30 21:20:41 - r - INFO: - Episode: 698/1000, Reward: 102.0, Step: 102 +2022-10-30 21:20:41 - r - INFO: - Episode: 699/1000, Reward: 90.0, Step: 90 +2022-10-30 21:20:42 - r - INFO: - Episode: 700/1000, Reward: 86.0, Step: 86 +2022-10-30 21:20:42 - r - INFO: - Episode: 701/1000, Reward: 81.0, Step: 81 +2022-10-30 21:20:43 - r - INFO: - Episode: 702/1000, Reward: 105.0, Step: 105 +2022-10-30 21:20:43 - r - INFO: - Episode: 703/1000, Reward: 72.0, Step: 72 +2022-10-30 21:20:44 - r - INFO: - Episode: 704/1000, Reward: 100.0, Step: 100 +2022-10-30 21:20:44 - r - INFO: - Episode: 705/1000, Reward: 96.0, Step: 96 +2022-10-30 21:20:45 - r - INFO: - Episode: 706/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:45 - r - INFO: - Episode: 707/1000, Reward: 27.0, Step: 27 +2022-10-30 21:20:46 - r - INFO: - Episode: 708/1000, Reward: 107.0, Step: 107 +2022-10-30 21:20:47 - r - INFO: - Episode: 709/1000, Reward: 87.0, Step: 87 +2022-10-30 21:20:47 - r - INFO: - Episode: 710/1000, Reward: 114.0, Step: 114 +2022-10-30 21:20:48 - r - INFO: - Episode: 711/1000, Reward: 111.0, Step: 111 +2022-10-30 21:20:48 - r - INFO: - Episode: 712/1000, Reward: 88.0, Step: 88 +2022-10-30 21:20:49 - r - INFO: - Episode: 713/1000, Reward: 112.0, Step: 112 +2022-10-30 21:20:50 - r - INFO: - Episode: 714/1000, Reward: 108.0, Step: 108 +2022-10-30 21:20:50 - r - INFO: - Episode: 715/1000, Reward: 108.0, Step: 108 +2022-10-30 21:20:51 - r - INFO: - Episode: 716/1000, Reward: 103.0, Step: 103 +2022-10-30 21:20:52 - r - INFO: - Episode: 717/1000, Reward: 120.0, Step: 120 +2022-10-30 21:20:52 - r - INFO: - Episode: 718/1000, Reward: 116.0, Step: 116 +2022-10-30 21:20:53 - r - INFO: - Episode: 719/1000, Reward: 112.0, Step: 112 +2022-10-30 21:20:54 - r - INFO: - Episode: 720/1000, Reward: 99.0, Step: 99 +2022-10-30 21:20:54 - r - INFO: - Episode: 721/1000, Reward: 118.0, Step: 118 +2022-10-30 21:20:55 - r - INFO: - Episode: 722/1000, Reward: 114.0, Step: 114 +2022-10-30 21:20:56 - r - INFO: - Episode: 723/1000, Reward: 104.0, Step: 104 +2022-10-30 21:20:56 - r - INFO: - Episode: 724/1000, Reward: 99.0, Step: 99 +2022-10-30 21:20:57 - r - INFO: - Episode: 725/1000, Reward: 102.0, Step: 102 +2022-10-30 21:20:57 - r - INFO: - Episode: 726/1000, Reward: 106.0, Step: 106 +2022-10-30 21:20:58 - r - INFO: - Episode: 727/1000, Reward: 31.0, Step: 31 +2022-10-30 21:20:58 - r - INFO: - Episode: 728/1000, Reward: 91.0, Step: 91 +2022-10-30 21:20:59 - r - INFO: - Episode: 729/1000, Reward: 32.0, Step: 32 +2022-10-30 21:20:59 - r - INFO: - Episode: 730/1000, Reward: 96.0, Step: 96 +2022-10-30 21:20:59 - r - INFO: - Episode: 731/1000, Reward: 20.0, Step: 20 +2022-10-30 21:21:00 - r - INFO: - Episode: 732/1000, Reward: 33.0, Step: 33 +2022-10-30 21:21:00 - r - INFO: - Episode: 733/1000, Reward: 23.0, Step: 23 +2022-10-30 21:21:00 - r - INFO: - Episode: 734/1000, Reward: 80.0, Step: 80 +2022-10-30 21:21:01 - r - INFO: - Episode: 735/1000, Reward: 35.0, Step: 35 +2022-10-30 21:21:01 - r - INFO: - Episode: 736/1000, Reward: 88.0, Step: 88 +2022-10-30 21:21:01 - r - INFO: - Episode: 737/1000, Reward: 28.0, Step: 28 +2022-10-30 21:21:01 - r - INFO: - Episode: 738/1000, Reward: 26.0, Step: 26 +2022-10-30 21:21:02 - r - INFO: - Episode: 739/1000, Reward: 70.0, Step: 70 +2022-10-30 21:21:02 - r - INFO: - Episode: 740/1000, Reward: 86.0, Step: 86 +2022-10-30 21:21:02 - r - INFO: - Episode: 741/1000, Reward: 28.0, Step: 28 +2022-10-30 21:21:02 - r - INFO: - Episode: 742/1000, Reward: 39.0, Step: 39 +2022-10-30 21:21:03 - r - INFO: - Episode: 743/1000, Reward: 65.0, Step: 65 +2022-10-30 21:21:03 - r - INFO: - Episode: 744/1000, Reward: 52.0, Step: 52 +2022-10-30 21:21:03 - r - INFO: - Episode: 745/1000, Reward: 43.0, Step: 43 +2022-10-30 21:21:04 - r - INFO: - Episode: 746/1000, Reward: 97.0, Step: 97 +2022-10-30 21:21:04 - r - INFO: - Episode: 747/1000, Reward: 27.0, Step: 27 +2022-10-30 21:21:05 - r - INFO: - Episode: 748/1000, Reward: 89.0, Step: 89 +2022-10-30 21:21:05 - r - INFO: - Episode: 749/1000, Reward: 34.0, Step: 34 +2022-10-30 21:21:05 - r - INFO: - Episode: 750/1000, Reward: 35.0, Step: 35 +2022-10-30 21:21:06 - r - INFO: - Episode: 751/1000, Reward: 28.0, Step: 28 +2022-10-30 21:21:06 - r - INFO: - Episode: 752/1000, Reward: 96.0, Step: 96 +2022-10-30 21:21:07 - r - INFO: - Episode: 753/1000, Reward: 97.0, Step: 97 +2022-10-30 21:21:07 - r - INFO: - Episode: 754/1000, Reward: 108.0, Step: 108 +2022-10-30 21:21:08 - r - INFO: - Episode: 755/1000, Reward: 45.0, Step: 45 +2022-10-30 21:21:09 - r - INFO: - Episode: 756/1000, Reward: 103.0, Step: 103 +2022-10-30 21:21:10 - r - INFO: - Episode: 757/1000, Reward: 97.0, Step: 97 +2022-10-30 21:21:10 - r - INFO: - Episode: 758/1000, Reward: 114.0, Step: 114 +2022-10-30 21:21:11 - r - INFO: - Episode: 759/1000, Reward: 103.0, Step: 103 +2022-10-30 21:21:12 - r - INFO: - Episode: 760/1000, Reward: 116.0, Step: 116 +2022-10-30 21:21:12 - r - INFO: - Episode: 761/1000, Reward: 127.0, Step: 127 +2022-10-30 21:21:13 - r - INFO: - Episode: 762/1000, Reward: 122.0, Step: 122 +2022-10-30 21:21:14 - r - INFO: - Episode: 763/1000, Reward: 112.0, Step: 112 +2022-10-30 21:21:14 - r - INFO: - Episode: 764/1000, Reward: 112.0, Step: 112 +2022-10-30 21:21:15 - r - INFO: - Episode: 765/1000, Reward: 120.0, Step: 120 +2022-10-30 21:21:16 - r - INFO: - Episode: 766/1000, Reward: 129.0, Step: 129 +2022-10-30 21:21:17 - r - INFO: - Episode: 767/1000, Reward: 127.0, Step: 127 +2022-10-30 21:21:18 - r - INFO: - Episode: 768/1000, Reward: 125.0, Step: 125 +2022-10-30 21:21:19 - r - INFO: - Episode: 769/1000, Reward: 124.0, Step: 124 +2022-10-30 21:21:20 - r - INFO: - Episode: 770/1000, Reward: 126.0, Step: 126 +2022-10-30 21:21:20 - r - INFO: - Episode: 771/1000, Reward: 129.0, Step: 129 +2022-10-30 21:21:21 - r - INFO: - Episode: 772/1000, Reward: 129.0, Step: 129 +2022-10-30 21:21:22 - r - INFO: - Episode: 773/1000, Reward: 43.0, Step: 43 +2022-10-30 21:21:22 - r - INFO: - Episode: 774/1000, Reward: 121.0, Step: 121 +2022-10-30 21:21:23 - r - INFO: - Episode: 775/1000, Reward: 40.0, Step: 40 +2022-10-30 21:21:24 - r - INFO: - Episode: 776/1000, Reward: 116.0, Step: 116 +2022-10-30 21:21:24 - r - INFO: - Episode: 777/1000, Reward: 117.0, Step: 117 +2022-10-30 21:21:25 - r - INFO: - Episode: 778/1000, Reward: 113.0, Step: 113 +2022-10-30 21:21:26 - r - INFO: - Episode: 779/1000, Reward: 117.0, Step: 117 +2022-10-30 21:21:26 - r - INFO: - Episode: 780/1000, Reward: 108.0, Step: 108 +2022-10-30 21:21:27 - r - INFO: - Episode: 781/1000, Reward: 108.0, Step: 108 +2022-10-30 21:21:28 - r - INFO: - Episode: 782/1000, Reward: 119.0, Step: 119 +2022-10-30 21:21:28 - r - INFO: - Episode: 783/1000, Reward: 109.0, Step: 109 +2022-10-30 21:21:29 - r - INFO: - Episode: 784/1000, Reward: 116.0, Step: 116 +2022-10-30 21:21:29 - r - INFO: - Episode: 785/1000, Reward: 114.0, Step: 114 +2022-10-30 21:21:30 - r - INFO: - Episode: 786/1000, Reward: 45.0, Step: 45 +2022-10-30 21:21:31 - r - INFO: - Episode: 787/1000, Reward: 116.0, Step: 116 +2022-10-30 21:21:31 - r - INFO: - Episode: 788/1000, Reward: 116.0, Step: 116 +2022-10-30 21:21:32 - r - INFO: - Episode: 789/1000, Reward: 110.0, Step: 110 +2022-10-30 21:21:32 - r - INFO: - Episode: 790/1000, Reward: 105.0, Step: 105 +2022-10-30 21:21:33 - r - INFO: - Episode: 791/1000, Reward: 110.0, Step: 110 +2022-10-30 21:21:34 - r - INFO: - Episode: 792/1000, Reward: 112.0, Step: 112 +2022-10-30 21:21:34 - r - INFO: - Episode: 793/1000, Reward: 104.0, Step: 104 +2022-10-30 21:21:35 - r - INFO: - Episode: 794/1000, Reward: 120.0, Step: 120 +2022-10-30 21:21:36 - r - INFO: - Episode: 795/1000, Reward: 110.0, Step: 110 +2022-10-30 21:21:36 - r - INFO: - Episode: 796/1000, Reward: 113.0, Step: 113 +2022-10-30 21:21:37 - r - INFO: - Episode: 797/1000, Reward: 33.0, Step: 33 +2022-10-30 21:21:37 - r - INFO: - Episode: 798/1000, Reward: 111.0, Step: 111 +2022-10-30 21:21:38 - r - INFO: - Episode: 799/1000, Reward: 31.0, Step: 31 +2022-10-30 21:21:38 - r - INFO: - Episode: 800/1000, Reward: 139.0, Step: 139 +2022-10-30 21:21:39 - r - INFO: - Episode: 801/1000, Reward: 110.0, Step: 110 +2022-10-30 21:21:40 - r - INFO: - Episode: 802/1000, Reward: 124.0, Step: 124 +2022-10-30 21:21:41 - r - INFO: - Episode: 803/1000, Reward: 120.0, Step: 120 +2022-10-30 21:21:41 - r - INFO: - Episode: 804/1000, Reward: 112.0, Step: 112 +2022-10-30 21:21:42 - r - INFO: - Episode: 805/1000, Reward: 116.0, Step: 116 +2022-10-30 21:21:43 - r - INFO: - Episode: 806/1000, Reward: 105.0, Step: 105 +2022-10-30 21:21:43 - r - INFO: - Episode: 807/1000, Reward: 125.0, Step: 125 +2022-10-30 21:21:44 - r - INFO: - Episode: 808/1000, Reward: 103.0, Step: 103 +2022-10-30 21:21:45 - r - INFO: - Episode: 809/1000, Reward: 122.0, Step: 122 +2022-10-30 21:21:45 - r - INFO: - Episode: 810/1000, Reward: 109.0, Step: 109 +2022-10-30 21:21:46 - r - INFO: - Episode: 811/1000, Reward: 118.0, Step: 118 +2022-10-30 21:21:47 - r - INFO: - Episode: 812/1000, Reward: 124.0, Step: 124 +2022-10-30 21:21:48 - r - INFO: - Episode: 813/1000, Reward: 115.0, Step: 115 +2022-10-30 21:21:48 - r - INFO: - Episode: 814/1000, Reward: 26.0, Step: 26 +2022-10-30 21:21:49 - r - INFO: - Episode: 815/1000, Reward: 118.0, Step: 118 +2022-10-30 21:21:49 - r - INFO: - Episode: 816/1000, Reward: 118.0, Step: 118 +2022-10-30 21:21:50 - r - INFO: - Episode: 817/1000, Reward: 31.0, Step: 31 +2022-10-30 21:21:50 - r - INFO: - Episode: 818/1000, Reward: 99.0, Step: 99 +2022-10-30 21:21:51 - r - INFO: - Episode: 819/1000, Reward: 122.0, Step: 122 +2022-10-30 21:21:52 - r - INFO: - Episode: 820/1000, Reward: 102.0, Step: 102 +2022-10-30 21:21:52 - r - INFO: - Episode: 821/1000, Reward: 111.0, Step: 111 +2022-10-30 21:21:53 - r - INFO: - Episode: 822/1000, Reward: 110.0, Step: 110 +2022-10-30 21:21:54 - r - INFO: - Episode: 823/1000, Reward: 113.0, Step: 113 +2022-10-30 21:21:54 - r - INFO: - Episode: 824/1000, Reward: 117.0, Step: 117 +2022-10-30 21:21:55 - r - INFO: - Episode: 825/1000, Reward: 113.0, Step: 113 +2022-10-30 21:21:56 - r - INFO: - Episode: 826/1000, Reward: 109.0, Step: 109 +2022-10-30 21:21:57 - r - INFO: - Episode: 827/1000, Reward: 122.0, Step: 122 +2022-10-30 21:21:57 - r - INFO: - Episode: 828/1000, Reward: 117.0, Step: 117 +2022-10-30 21:21:58 - r - INFO: - Episode: 829/1000, Reward: 127.0, Step: 127 +2022-10-30 21:21:59 - r - INFO: - Episode: 830/1000, Reward: 113.0, Step: 113 +2022-10-30 21:21:59 - r - INFO: - Episode: 831/1000, Reward: 118.0, Step: 118 +2022-10-30 21:22:00 - r - INFO: - Episode: 832/1000, Reward: 107.0, Step: 107 +2022-10-30 21:22:01 - r - INFO: - Episode: 833/1000, Reward: 108.0, Step: 108 +2022-10-30 21:22:01 - r - INFO: - Episode: 834/1000, Reward: 103.0, Step: 103 +2022-10-30 21:22:02 - r - INFO: - Episode: 835/1000, Reward: 126.0, Step: 126 +2022-10-30 21:22:03 - r - INFO: - Episode: 836/1000, Reward: 131.0, Step: 131 +2022-10-30 21:22:03 - r - INFO: - Episode: 837/1000, Reward: 106.0, Step: 106 +2022-10-30 21:22:04 - r - INFO: - Episode: 838/1000, Reward: 116.0, Step: 116 +2022-10-30 21:22:05 - r - INFO: - Episode: 839/1000, Reward: 24.0, Step: 24 +2022-10-30 21:22:05 - r - INFO: - Episode: 840/1000, Reward: 107.0, Step: 107 +2022-10-30 21:22:06 - r - INFO: - Episode: 841/1000, Reward: 124.0, Step: 124 +2022-10-30 21:22:07 - r - INFO: - Episode: 842/1000, Reward: 125.0, Step: 125 +2022-10-30 21:22:07 - r - INFO: - Episode: 843/1000, Reward: 110.0, Step: 110 +2022-10-30 21:22:08 - r - INFO: - Episode: 844/1000, Reward: 112.0, Step: 112 +2022-10-30 21:22:09 - r - INFO: - Episode: 845/1000, Reward: 105.0, Step: 105 +2022-10-30 21:22:09 - r - INFO: - Episode: 846/1000, Reward: 104.0, Step: 104 +2022-10-30 21:22:10 - r - INFO: - Episode: 847/1000, Reward: 134.0, Step: 134 +2022-10-30 21:22:11 - r - INFO: - Episode: 848/1000, Reward: 107.0, Step: 107 +2022-10-30 21:22:11 - r - INFO: - Episode: 849/1000, Reward: 128.0, Step: 128 +2022-10-30 21:22:12 - r - INFO: - Episode: 850/1000, Reward: 113.0, Step: 113 +2022-10-30 21:22:13 - r - INFO: - Episode: 851/1000, Reward: 138.0, Step: 138 +2022-10-30 21:22:14 - r - INFO: - Episode: 852/1000, Reward: 118.0, Step: 118 +2022-10-30 21:22:14 - r - INFO: - Episode: 853/1000, Reward: 142.0, Step: 142 +2022-10-30 21:22:15 - r - INFO: - Episode: 854/1000, Reward: 118.0, Step: 118 +2022-10-30 21:22:16 - r - INFO: - Episode: 855/1000, Reward: 122.0, Step: 122 +2022-10-30 21:22:16 - r - INFO: - Episode: 856/1000, Reward: 130.0, Step: 130 +2022-10-30 21:22:17 - r - INFO: - Episode: 857/1000, Reward: 126.0, Step: 126 +2022-10-30 21:22:18 - r - INFO: - Episode: 858/1000, Reward: 111.0, Step: 111 +2022-10-30 21:22:19 - r - INFO: - Episode: 859/1000, Reward: 114.0, Step: 114 +2022-10-30 21:22:19 - r - INFO: - Episode: 860/1000, Reward: 128.0, Step: 128 +2022-10-30 21:22:20 - r - INFO: - Episode: 861/1000, Reward: 126.0, Step: 126 +2022-10-30 21:22:21 - r - INFO: - Episode: 862/1000, Reward: 143.0, Step: 143 +2022-10-30 21:22:22 - r - INFO: - Episode: 863/1000, Reward: 132.0, Step: 132 +2022-10-30 21:22:22 - r - INFO: - Episode: 864/1000, Reward: 123.0, Step: 123 +2022-10-30 21:22:23 - r - INFO: - Episode: 865/1000, Reward: 111.0, Step: 111 +2022-10-30 21:22:24 - r - INFO: - Episode: 866/1000, Reward: 129.0, Step: 129 +2022-10-30 21:22:25 - r - INFO: - Episode: 867/1000, Reward: 121.0, Step: 121 +2022-10-30 21:22:25 - r - INFO: - Episode: 868/1000, Reward: 114.0, Step: 114 +2022-10-30 21:22:26 - r - INFO: - Episode: 869/1000, Reward: 110.0, Step: 110 +2022-10-30 21:22:27 - r - INFO: - Episode: 870/1000, Reward: 118.0, Step: 118 +2022-10-30 21:22:27 - r - INFO: - Episode: 871/1000, Reward: 120.0, Step: 120 +2022-10-30 21:22:28 - r - INFO: - Episode: 872/1000, Reward: 109.0, Step: 109 +2022-10-30 21:22:29 - r - INFO: - Episode: 873/1000, Reward: 106.0, Step: 106 +2022-10-30 21:22:29 - r - INFO: - Episode: 874/1000, Reward: 118.0, Step: 118 +2022-10-30 21:22:30 - r - INFO: - Episode: 875/1000, Reward: 104.0, Step: 104 +2022-10-30 21:22:30 - r - INFO: - Episode: 876/1000, Reward: 98.0, Step: 98 +2022-10-30 21:22:31 - r - INFO: - Episode: 877/1000, Reward: 115.0, Step: 115 +2022-10-30 21:22:31 - r - INFO: - Episode: 878/1000, Reward: 34.0, Step: 34 +2022-10-30 21:22:32 - r - INFO: - Episode: 879/1000, Reward: 96.0, Step: 96 +2022-10-30 21:22:33 - r - INFO: - Episode: 880/1000, Reward: 108.0, Step: 108 +2022-10-30 21:22:33 - r - INFO: - Episode: 881/1000, Reward: 105.0, Step: 105 +2022-10-30 21:22:34 - r - INFO: - Episode: 882/1000, Reward: 33.0, Step: 33 +2022-10-30 21:22:34 - r - INFO: - Episode: 883/1000, Reward: 105.0, Step: 105 +2022-10-30 21:22:35 - r - INFO: - Episode: 884/1000, Reward: 111.0, Step: 111 +2022-10-30 21:22:35 - r - INFO: - Episode: 885/1000, Reward: 112.0, Step: 112 +2022-10-30 21:22:36 - r - INFO: - Episode: 886/1000, Reward: 101.0, Step: 101 +2022-10-30 21:22:36 - r - INFO: - Episode: 887/1000, Reward: 25.0, Step: 25 +2022-10-30 21:22:37 - r - INFO: - Episode: 888/1000, Reward: 35.0, Step: 35 +2022-10-30 21:22:37 - r - INFO: - Episode: 889/1000, Reward: 99.0, Step: 99 +2022-10-30 21:22:38 - r - INFO: - Episode: 890/1000, Reward: 105.0, Step: 105 +2022-10-30 21:22:38 - r - INFO: - Episode: 891/1000, Reward: 36.0, Step: 36 +2022-10-30 21:22:38 - r - INFO: - Episode: 892/1000, Reward: 92.0, Step: 92 +2022-10-30 21:22:39 - r - INFO: - Episode: 893/1000, Reward: 104.0, Step: 104 +2022-10-30 21:22:39 - r - INFO: - Episode: 894/1000, Reward: 111.0, Step: 111 +2022-10-30 21:22:40 - r - INFO: - Episode: 895/1000, Reward: 106.0, Step: 106 +2022-10-30 21:22:41 - r - INFO: - Episode: 896/1000, Reward: 109.0, Step: 109 +2022-10-30 21:22:41 - r - INFO: - Episode: 897/1000, Reward: 108.0, Step: 108 +2022-10-30 21:22:42 - r - INFO: - Episode: 898/1000, Reward: 101.0, Step: 101 +2022-10-30 21:22:42 - r - INFO: - Episode: 899/1000, Reward: 100.0, Step: 100 +2022-10-30 21:22:43 - r - INFO: - Episode: 900/1000, Reward: 33.0, Step: 33 +2022-10-30 21:22:44 - r - INFO: - Episode: 901/1000, Reward: 119.0, Step: 119 +2022-10-30 21:22:44 - r - INFO: - Episode: 902/1000, Reward: 112.0, Step: 112 +2022-10-30 21:22:45 - r - INFO: - Episode: 903/1000, Reward: 112.0, Step: 112 +2022-10-30 21:22:45 - r - INFO: - Episode: 904/1000, Reward: 126.0, Step: 126 +2022-10-30 21:22:46 - r - INFO: - Episode: 905/1000, Reward: 123.0, Step: 123 +2022-10-30 21:22:47 - r - INFO: - Episode: 906/1000, Reward: 125.0, Step: 125 +2022-10-30 21:22:47 - r - INFO: - Episode: 907/1000, Reward: 107.0, Step: 107 +2022-10-30 21:22:48 - r - INFO: - Episode: 908/1000, Reward: 128.0, Step: 128 +2022-10-30 21:22:49 - r - INFO: - Episode: 909/1000, Reward: 119.0, Step: 119 +2022-10-30 21:22:50 - r - INFO: - Episode: 910/1000, Reward: 142.0, Step: 142 +2022-10-30 21:22:50 - r - INFO: - Episode: 911/1000, Reward: 117.0, Step: 117 +2022-10-30 21:22:51 - r - INFO: - Episode: 912/1000, Reward: 125.0, Step: 125 +2022-10-30 21:22:52 - r - INFO: - Episode: 913/1000, Reward: 141.0, Step: 141 +2022-10-30 21:22:53 - r - INFO: - Episode: 914/1000, Reward: 134.0, Step: 134 +2022-10-30 21:22:53 - r - INFO: - Episode: 915/1000, Reward: 131.0, Step: 131 +2022-10-30 21:22:54 - r - INFO: - Episode: 916/1000, Reward: 131.0, Step: 131 +2022-10-30 21:22:55 - r - INFO: - Episode: 917/1000, Reward: 140.0, Step: 140 +2022-10-30 21:22:56 - r - INFO: - Episode: 918/1000, Reward: 115.0, Step: 115 +2022-10-30 21:22:56 - r - INFO: - Episode: 919/1000, Reward: 142.0, Step: 142 +2022-10-30 21:22:57 - r - INFO: - Episode: 920/1000, Reward: 142.0, Step: 142 +2022-10-30 21:22:58 - r - INFO: - Episode: 921/1000, Reward: 128.0, Step: 128 +2022-10-30 21:22:59 - r - INFO: - Episode: 922/1000, Reward: 139.0, Step: 139 +2022-10-30 21:23:00 - r - INFO: - Episode: 923/1000, Reward: 133.0, Step: 133 +2022-10-30 21:23:01 - r - INFO: - Episode: 924/1000, Reward: 129.0, Step: 129 +2022-10-30 21:23:01 - r - INFO: - Episode: 925/1000, Reward: 124.0, Step: 124 +2022-10-30 21:23:02 - r - INFO: - Episode: 926/1000, Reward: 131.0, Step: 131 +2022-10-30 21:23:03 - r - INFO: - Episode: 927/1000, Reward: 125.0, Step: 125 +2022-10-30 21:23:04 - r - INFO: - Episode: 928/1000, Reward: 146.0, Step: 146 +2022-10-30 21:23:04 - r - INFO: - Episode: 929/1000, Reward: 118.0, Step: 118 +2022-10-30 21:23:05 - r - INFO: - Episode: 930/1000, Reward: 126.0, Step: 126 +2022-10-30 21:23:06 - r - INFO: - Episode: 931/1000, Reward: 134.0, Step: 134 +2022-10-30 21:23:07 - r - INFO: - Episode: 932/1000, Reward: 155.0, Step: 155 +2022-10-30 21:23:07 - r - INFO: - Episode: 933/1000, Reward: 134.0, Step: 134 +2022-10-30 21:23:08 - r - INFO: - Episode: 934/1000, Reward: 136.0, Step: 136 +2022-10-30 21:23:09 - r - INFO: - Episode: 935/1000, Reward: 146.0, Step: 146 +2022-10-30 21:23:10 - r - INFO: - Episode: 936/1000, Reward: 150.0, Step: 150 +2022-10-30 21:23:11 - r - INFO: - Episode: 937/1000, Reward: 167.0, Step: 167 +2022-10-30 21:23:12 - r - INFO: - Episode: 938/1000, Reward: 135.0, Step: 135 +2022-10-30 21:23:13 - r - INFO: - Episode: 939/1000, Reward: 197.0, Step: 197 +2022-10-30 21:23:14 - r - INFO: - Episode: 940/1000, Reward: 190.0, Step: 190 +2022-10-30 21:23:15 - r - INFO: - Episode: 941/1000, Reward: 170.0, Step: 170 +2022-10-30 21:23:16 - r - INFO: - Episode: 942/1000, Reward: 179.0, Step: 179 +2022-10-30 21:23:17 - r - INFO: - Episode: 943/1000, Reward: 192.0, Step: 192 +2022-10-30 21:23:18 - r - INFO: - Episode: 944/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:19 - r - INFO: - Current episode 944 has the best eval reward: 199.5 +2022-10-30 21:23:20 - r - INFO: - Episode: 945/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:21 - r - INFO: - Episode: 946/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:22 - r - INFO: - Episode: 947/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:23 - r - INFO: - Current episode 947 has the best eval reward: 200.0 +2022-10-30 21:23:23 - r - INFO: - Episode: 948/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:25 - r - INFO: - Episode: 949/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:25 - r - INFO: - Current episode 949 has the best eval reward: 200.0 +2022-10-30 21:23:26 - r - INFO: - Episode: 950/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:26 - r - INFO: - Current episode 950 has the best eval reward: 200.0 +2022-10-30 21:23:27 - r - INFO: - Episode: 951/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:28 - r - INFO: - Current episode 951 has the best eval reward: 200.0 +2022-10-30 21:23:28 - r - INFO: - Episode: 952/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:29 - r - INFO: - Current episode 952 has the best eval reward: 200.0 +2022-10-30 21:23:29 - r - INFO: - Episode: 953/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:30 - r - INFO: - Current episode 953 has the best eval reward: 200.0 +2022-10-30 21:23:31 - r - INFO: - Episode: 954/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:31 - r - INFO: - Current episode 954 has the best eval reward: 200.0 +2022-10-30 21:23:32 - r - INFO: - Episode: 955/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:33 - r - INFO: - Current episode 955 has the best eval reward: 200.0 +2022-10-30 21:23:33 - r - INFO: - Episode: 956/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:34 - r - INFO: - Current episode 956 has the best eval reward: 200.0 +2022-10-30 21:23:34 - r - INFO: - Episode: 957/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:35 - r - INFO: - Current episode 957 has the best eval reward: 200.0 +2022-10-30 21:23:36 - r - INFO: - Episode: 958/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:36 - r - INFO: - Current episode 958 has the best eval reward: 200.0 +2022-10-30 21:23:37 - r - INFO: - Episode: 959/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:37 - r - INFO: - Current episode 959 has the best eval reward: 200.0 +2022-10-30 21:23:38 - r - INFO: - Episode: 960/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:39 - r - INFO: - Episode: 961/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:40 - r - INFO: - Current episode 961 has the best eval reward: 200.0 +2022-10-30 21:23:40 - r - INFO: - Episode: 962/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:41 - r - INFO: - Current episode 962 has the best eval reward: 200.0 +2022-10-30 21:23:42 - r - INFO: - Episode: 963/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:42 - r - INFO: - Current episode 963 has the best eval reward: 200.0 +2022-10-30 21:23:43 - r - INFO: - Episode: 964/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:43 - r - INFO: - Current episode 964 has the best eval reward: 200.0 +2022-10-30 21:23:44 - r - INFO: - Episode: 965/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:45 - r - INFO: - Episode: 966/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:46 - r - INFO: - Current episode 966 has the best eval reward: 200.0 +2022-10-30 21:23:46 - r - INFO: - Episode: 967/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:47 - r - INFO: - Current episode 967 has the best eval reward: 200.0 +2022-10-30 21:23:48 - r - INFO: - Episode: 968/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:48 - r - INFO: - Current episode 968 has the best eval reward: 200.0 +2022-10-30 21:23:49 - r - INFO: - Episode: 969/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:50 - r - INFO: - Current episode 969 has the best eval reward: 200.0 +2022-10-30 21:23:50 - r - INFO: - Episode: 970/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:51 - r - INFO: - Episode: 971/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:52 - r - INFO: - Current episode 971 has the best eval reward: 200.0 +2022-10-30 21:23:52 - r - INFO: - Episode: 972/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:53 - r - INFO: - Current episode 972 has the best eval reward: 200.0 +2022-10-30 21:23:54 - r - INFO: - Episode: 973/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:54 - r - INFO: - Current episode 973 has the best eval reward: 200.0 +2022-10-30 21:23:55 - r - INFO: - Episode: 974/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:55 - r - INFO: - Current episode 974 has the best eval reward: 200.0 +2022-10-30 21:23:56 - r - INFO: - Episode: 975/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:57 - r - INFO: - Current episode 975 has the best eval reward: 200.0 +2022-10-30 21:23:57 - r - INFO: - Episode: 976/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:58 - r - INFO: - Current episode 976 has the best eval reward: 200.0 +2022-10-30 21:23:58 - r - INFO: - Episode: 977/1000, Reward: 200.0, Step: 200 +2022-10-30 21:23:59 - r - INFO: - Current episode 977 has the best eval reward: 200.0 +2022-10-30 21:24:00 - r - INFO: - Episode: 978/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:01 - r - INFO: - Episode: 979/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:01 - r - INFO: - Current episode 979 has the best eval reward: 200.0 +2022-10-30 21:24:02 - r - INFO: - Episode: 980/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:03 - r - INFO: - Current episode 980 has the best eval reward: 200.0 +2022-10-30 21:24:03 - r - INFO: - Episode: 981/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:04 - r - INFO: - Episode: 982/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:05 - r - INFO: - Episode: 983/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:06 - r - INFO: - Current episode 983 has the best eval reward: 200.0 +2022-10-30 21:24:07 - r - INFO: - Episode: 984/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:08 - r - INFO: - Episode: 985/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:09 - r - INFO: - Episode: 986/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:10 - r - INFO: - Episode: 987/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:11 - r - INFO: - Current episode 987 has the best eval reward: 200.0 +2022-10-30 21:24:12 - r - INFO: - Episode: 988/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:12 - r - INFO: - Current episode 988 has the best eval reward: 200.0 +2022-10-30 21:24:13 - r - INFO: - Episode: 989/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:14 - r - INFO: - Episode: 990/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:15 - r - INFO: - Episode: 991/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:16 - r - INFO: - Current episode 991 has the best eval reward: 200.0 +2022-10-30 21:24:16 - r - INFO: - Episode: 992/1000, Reward: 198.0, Step: 198 +2022-10-30 21:24:17 - r - INFO: - Current episode 992 has the best eval reward: 200.0 +2022-10-30 21:24:18 - r - INFO: - Episode: 993/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:18 - r - INFO: - Current episode 993 has the best eval reward: 200.0 +2022-10-30 21:24:19 - r - INFO: - Episode: 994/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:19 - r - INFO: - Current episode 994 has the best eval reward: 200.0 +2022-10-30 21:24:20 - r - INFO: - Episode: 995/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:21 - r - INFO: - Episode: 996/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:22 - r - INFO: - Episode: 997/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:23 - r - INFO: - Episode: 998/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:24 - r - INFO: - Current episode 998 has the best eval reward: 200.0 +2022-10-30 21:24:25 - r - INFO: - Episode: 999/1000, Reward: 200.0, Step: 200 +2022-10-30 21:24:26 - r - INFO: - Episode: 1000/1000, Reward: 200.0, Step: 200 diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/models/actor_checkpoint.pt b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/models/actor_checkpoint.pt new file mode 100644 index 0000000..89d0854 Binary files /dev/null and b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/models/actor_checkpoint.pt differ diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/models/critic_checkpoint.pt b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/models/critic_checkpoint.pt new file mode 100644 index 0000000..720f388 Binary files /dev/null and b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/models/critic_checkpoint.pt differ diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/results/learning_curve.png b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/results/learning_curve.png new file mode 100644 index 0000000..8bbfcde Binary files /dev/null and b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/results/learning_curve.png differ diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/results/res.csv b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/results/res.csv new file mode 100644 index 0000000..6f853b9 --- /dev/null +++ b/projects/codes/A2C/Train_CartPole-v1_A2C_20221030-211435/results/res.csv @@ -0,0 +1,1001 @@ +episodes,rewards,steps +0,25.0,25 +1,13.0,13 +2,58.0,58 +3,10.0,10 +4,39.0,39 +5,39.0,39 +6,25.0,25 +7,22.0,22 +8,21.0,21 +9,27.0,27 +10,35.0,35 +11,26.0,26 +12,38.0,38 +13,29.0,29 +14,50.0,50 +15,20.0,20 +16,52.0,52 +17,12.0,12 +18,20.0,20 +19,38.0,38 +20,22.0,22 +21,36.0,36 +22,20.0,20 +23,35.0,35 +24,90.0,90 +25,29.0,29 +26,16.0,16 +27,25.0,25 +28,46.0,46 +29,33.0,33 +30,11.0,11 +31,27.0,27 +32,32.0,32 +33,21.0,21 +34,11.0,11 +35,21.0,21 +36,51.0,51 +37,29.0,29 +38,50.0,50 +39,19.0,19 +40,41.0,41 +41,28.0,28 +42,71.0,71 +43,45.0,45 +44,42.0,42 +45,39.0,39 +46,21.0,21 +47,14.0,14 +48,23.0,23 +49,21.0,21 +50,34.0,34 +51,14.0,14 +52,41.0,41 +53,99.0,99 +54,21.0,21 +55,52.0,52 +56,34.0,34 +57,73.0,73 +58,21.0,21 +59,27.0,27 +60,51.0,51 +61,46.0,46 +62,21.0,21 +63,20.0,20 +64,44.0,44 +65,16.0,16 +66,39.0,39 +67,30.0,30 +68,37.0,37 +69,20.0,20 +70,21.0,21 +71,13.0,13 +72,65.0,65 +73,45.0,45 +74,45.0,45 +75,46.0,46 +76,13.0,13 +77,33.0,33 +78,30.0,30 +79,52.0,52 +80,27.0,27 +81,30.0,30 +82,47.0,47 +83,56.0,56 +84,19.0,19 +85,33.0,33 +86,25.0,25 +87,41.0,41 +88,20.0,20 +89,58.0,58 +90,35.0,35 +91,23.0,23 +92,12.0,12 +93,20.0,20 +94,10.0,10 +95,49.0,49 +96,29.0,29 +97,35.0,35 +98,36.0,36 +99,36.0,36 +100,16.0,16 +101,36.0,36 +102,30.0,30 +103,76.0,76 +104,52.0,52 +105,39.0,39 +106,52.0,52 +107,69.0,69 +108,27.0,27 +109,14.0,14 +110,28.0,28 +111,12.0,12 +112,26.0,26 +113,50.0,50 +114,25.0,25 +115,53.0,53 +116,19.0,19 +117,33.0,33 +118,34.0,34 +119,41.0,41 +120,25.0,25 +121,18.0,18 +122,114.0,114 +123,25.0,25 +124,46.0,46 +125,22.0,22 +126,71.0,71 +127,30.0,30 +128,130.0,130 +129,65.0,65 +130,55.0,55 +131,37.0,37 +132,46.0,46 +133,65.0,65 +134,31.0,31 +135,33.0,33 +136,39.0,39 +137,73.0,73 +138,78.0,78 +139,36.0,36 +140,56.0,56 +141,12.0,12 +142,36.0,36 +143,13.0,13 +144,85.0,85 +145,34.0,34 +146,16.0,16 +147,68.0,68 +148,94.0,94 +149,17.0,17 +150,64.0,64 +151,33.0,33 +152,63.0,63 +153,39.0,39 +154,72.0,72 +155,39.0,39 +156,37.0,37 +157,18.0,18 +158,55.0,55 +159,21.0,21 +160,54.0,54 +161,46.0,46 +162,21.0,21 +163,26.0,26 +164,70.0,70 +165,20.0,20 +166,41.0,41 +167,77.0,77 +168,13.0,13 +169,66.0,66 +170,72.0,72 +171,28.0,28 +172,68.0,68 +173,124.0,124 +174,41.0,41 +175,54.0,54 +176,33.0,33 +177,92.0,92 +178,23.0,23 +179,76.0,76 +180,47.0,47 +181,89.0,89 +182,84.0,84 +183,75.0,75 +184,64.0,64 +185,35.0,35 +186,44.0,44 +187,46.0,46 +188,67.0,67 +189,82.0,82 +190,55.0,55 +191,26.0,26 +192,116.0,116 +193,116.0,116 +194,119.0,119 +195,50.0,50 +196,43.0,43 +197,47.0,47 +198,71.0,71 +199,53.0,53 +200,137.0,137 +201,82.0,82 +202,120.0,120 +203,69.0,69 +204,55.0,55 +205,62.0,62 +206,64.0,64 +207,49.0,49 +208,32.0,32 +209,42.0,42 +210,50.0,50 +211,93.0,93 +212,60.0,60 +213,54.0,54 +214,68.0,68 +215,84.0,84 +216,55.0,55 +217,70.0,70 +218,115.0,115 +219,149.0,149 +220,68.0,68 +221,50.0,50 +222,56.0,56 +223,61.0,61 +224,117.0,117 +225,66.0,66 +226,127.0,127 +227,66.0,66 +228,48.0,48 +229,36.0,36 +230,79.0,79 +231,49.0,49 +232,55.0,55 +233,41.0,41 +234,20.0,20 +235,40.0,40 +236,120.0,120 +237,27.0,27 +238,51.0,51 +239,35.0,35 +240,43.0,43 +241,54.0,54 +242,52.0,52 +243,47.0,47 +244,63.0,63 +245,29.0,29 +246,36.0,36 +247,58.0,58 +248,63.0,63 +249,49.0,49 +250,70.0,70 +251,114.0,114 +252,62.0,62 +253,73.0,73 +254,62.0,62 +255,61.0,61 +256,115.0,115 +257,50.0,50 +258,128.0,128 +259,200.0,200 +260,75.0,75 +261,64.0,64 +262,33.0,33 +263,90.0,90 +264,117.0,117 +265,60.0,60 +266,177.0,177 +267,39.0,39 +268,40.0,40 +269,109.0,109 +270,100.0,100 +271,99.0,99 +272,136.0,136 +273,62.0,62 +274,100.0,100 +275,73.0,73 +276,166.0,166 +277,74.0,74 +278,126.0,126 +279,111.0,111 +280,198.0,198 +281,106.0,106 +282,80.0,80 +283,74.0,74 +284,114.0,114 +285,69.0,69 +286,98.0,98 +287,63.0,63 +288,61.0,61 +289,49.0,49 +290,89.0,89 +291,114.0,114 +292,103.0,103 +293,103.0,103 +294,93.0,93 +295,137.0,137 +296,97.0,97 +297,124.0,124 +298,147.0,147 +299,125.0,125 +300,105.0,105 +301,113.0,113 +302,120.0,120 +303,159.0,159 +304,190.0,190 +305,119.0,119 +306,200.0,200 +307,148.0,148 +308,200.0,200 +309,79.0,79 +310,115.0,115 +311,147.0,147 +312,112.0,112 +313,125.0,125 +314,184.0,184 +315,193.0,193 +316,117.0,117 +317,153.0,153 +318,125.0,125 +319,184.0,184 +320,173.0,173 +321,117.0,117 +322,47.0,47 +323,107.0,107 +324,104.0,104 +325,114.0,114 +326,90.0,90 +327,112.0,112 +328,70.0,70 +329,74.0,74 +330,159.0,159 +331,39.0,39 +332,129.0,129 +333,50.0,50 +334,74.0,74 +335,31.0,31 +336,57.0,57 +337,71.0,71 +338,43.0,43 +339,41.0,41 +340,64.0,64 +341,38.0,38 +342,45.0,45 +343,120.0,120 +344,40.0,40 +345,46.0,46 +346,57.0,57 +347,29.0,29 +348,29.0,29 +349,50.0,50 +350,38.0,38 +351,51.0,51 +352,49.0,49 +353,30.0,30 +354,40.0,40 +355,45.0,45 +356,68.0,68 +357,27.0,27 +358,18.0,18 +359,26.0,26 +360,15.0,15 +361,65.0,65 +362,38.0,38 +363,41.0,41 +364,61.0,61 +365,113.0,113 +366,39.0,39 +367,60.0,60 +368,134.0,134 +369,122.0,122 +370,34.0,34 +371,129.0,129 +372,40.0,40 +373,128.0,128 +374,200.0,200 +375,108.0,108 +376,108.0,108 +377,151.0,151 +378,79.0,79 +379,105.0,105 +380,87.0,87 +381,94.0,94 +382,112.0,112 +383,200.0,200 +384,184.0,184 +385,124.0,124 +386,200.0,200 +387,200.0,200 +388,109.0,109 +389,88.0,88 +390,104.0,104 +391,200.0,200 +392,84.0,84 +393,187.0,187 +394,182.0,182 +395,148.0,148 +396,86.0,86 +397,200.0,200 +398,199.0,199 +399,200.0,200 +400,92.0,92 +401,112.0,112 +402,86.0,86 +403,114.0,114 +404,90.0,90 +405,101.0,101 +406,111.0,111 +407,107.0,107 +408,120.0,120 +409,114.0,114 +410,97.0,97 +411,95.0,95 +412,126.0,126 +413,111.0,111 +414,120.0,120 +415,178.0,178 +416,97.0,97 +417,144.0,144 +418,200.0,200 +419,190.0,190 +420,29.0,29 +421,200.0,200 +422,116.0,116 +423,200.0,200 +424,107.0,107 +425,128.0,128 +426,164.0,164 +427,30.0,30 +428,122.0,122 +429,110.0,110 +430,105.0,105 +431,137.0,137 +432,110.0,110 +433,111.0,111 +434,33.0,33 +435,100.0,100 +436,131.0,131 +437,99.0,99 +438,118.0,118 +439,98.0,98 +440,119.0,119 +441,41.0,41 +442,107.0,107 +443,41.0,41 +444,113.0,113 +445,113.0,113 +446,117.0,117 +447,140.0,140 +448,133.0,133 +449,108.0,108 +450,117.0,117 +451,40.0,40 +452,108.0,108 +453,140.0,140 +454,133.0,133 +455,115.0,115 +456,30.0,30 +457,119.0,119 +458,160.0,160 +459,125.0,125 +460,161.0,161 +461,139.0,139 +462,190.0,190 +463,149.0,149 +464,173.0,173 +465,165.0,165 +466,82.0,82 +467,197.0,197 +468,200.0,200 +469,200.0,200 +470,200.0,200 +471,182.0,182 +472,118.0,118 +473,200.0,200 +474,200.0,200 +475,93.0,93 +476,200.0,200 +477,200.0,200 +478,167.0,167 +479,200.0,200 +480,200.0,200 +481,200.0,200 +482,190.0,190 +483,86.0,86 +484,166.0,166 +485,200.0,200 +486,200.0,200 +487,172.0,172 +488,200.0,200 +489,102.0,102 +490,194.0,194 +491,200.0,200 +492,179.0,179 +493,187.0,187 +494,200.0,200 +495,89.0,89 +496,169.0,169 +497,28.0,28 +498,160.0,160 +499,140.0,140 +500,37.0,37 +501,32.0,32 +502,129.0,129 +503,22.0,22 +504,124.0,124 +505,24.0,24 +506,115.0,115 +507,24.0,24 +508,38.0,38 +509,24.0,24 +510,23.0,23 +511,125.0,125 +512,22.0,22 +513,24.0,24 +514,20.0,20 +515,25.0,25 +516,31.0,31 +517,23.0,23 +518,30.0,30 +519,101.0,101 +520,25.0,25 +521,22.0,22 +522,20.0,20 +523,16.0,16 +524,104.0,104 +525,17.0,17 +526,108.0,108 +527,121.0,121 +528,29.0,29 +529,29.0,29 +530,43.0,43 +531,105.0,105 +532,130.0,130 +533,30.0,30 +534,31.0,31 +535,30.0,30 +536,37.0,37 +537,115.0,115 +538,110.0,110 +539,112.0,112 +540,33.0,33 +541,120.0,120 +542,109.0,109 +543,122.0,122 +544,115.0,115 +545,34.0,34 +546,28.0,28 +547,29.0,29 +548,113.0,113 +549,100.0,100 +550,26.0,26 +551,24.0,24 +552,26.0,26 +553,102.0,102 +554,18.0,18 +555,107.0,107 +556,27.0,27 +557,87.0,87 +558,29.0,29 +559,31.0,31 +560,112.0,112 +561,112.0,112 +562,108.0,108 +563,98.0,98 +564,104.0,104 +565,116.0,116 +566,123.0,123 +567,105.0,105 +568,133.0,133 +569,116.0,116 +570,128.0,128 +571,130.0,130 +572,113.0,113 +573,143.0,143 +574,145.0,145 +575,159.0,159 +576,150.0,150 +577,130.0,130 +578,145.0,145 +579,173.0,173 +580,154.0,154 +581,131.0,131 +582,163.0,163 +583,160.0,160 +584,181.0,181 +585,161.0,161 +586,169.0,169 +587,150.0,150 +588,176.0,176 +589,157.0,157 +590,167.0,167 +591,168.0,168 +592,135.0,135 +593,157.0,157 +594,138.0,138 +595,139.0,139 +596,146.0,146 +597,121.0,121 +598,140.0,140 +599,124.0,124 +600,124.0,124 +601,115.0,115 +602,129.0,129 +603,107.0,107 +604,118.0,118 +605,108.0,108 +606,102.0,102 +607,105.0,105 +608,103.0,103 +609,96.0,96 +610,116.0,116 +611,51.0,51 +612,100.0,100 +613,121.0,121 +614,109.0,109 +615,85.0,85 +616,111.0,111 +617,91.0,91 +618,127.0,127 +619,117.0,117 +620,104.0,104 +621,119.0,119 +622,111.0,111 +623,132.0,132 +624,130.0,130 +625,140.0,140 +626,95.0,95 +627,106.0,106 +628,120.0,120 +629,111.0,111 +630,114.0,114 +631,126.0,126 +632,100.0,100 +633,111.0,111 +634,104.0,104 +635,103.0,103 +636,111.0,111 +637,110.0,110 +638,131.0,131 +639,90.0,90 +640,97.0,97 +641,104.0,104 +642,91.0,91 +643,97.0,97 +644,109.0,109 +645,112.0,112 +646,97.0,97 +647,32.0,32 +648,94.0,94 +649,107.0,107 +650,61.0,61 +651,97.0,97 +652,99.0,99 +653,76.0,76 +654,38.0,38 +655,96.0,96 +656,96.0,96 +657,65.0,65 +658,45.0,45 +659,91.0,91 +660,78.0,78 +661,90.0,90 +662,92.0,92 +663,94.0,94 +664,101.0,101 +665,111.0,111 +666,109.0,109 +667,99.0,99 +668,115.0,115 +669,112.0,112 +670,113.0,113 +671,110.0,110 +672,108.0,108 +673,112.0,112 +674,125.0,125 +675,122.0,122 +676,114.0,114 +677,127.0,127 +678,125.0,125 +679,112.0,112 +680,111.0,111 +681,124.0,124 +682,113.0,113 +683,103.0,103 +684,119.0,119 +685,120.0,120 +686,95.0,95 +687,100.0,100 +688,29.0,29 +689,119.0,119 +690,107.0,107 +691,117.0,117 +692,78.0,78 +693,35.0,35 +694,101.0,101 +695,98.0,98 +696,94.0,94 +697,102.0,102 +698,90.0,90 +699,86.0,86 +700,81.0,81 +701,105.0,105 +702,72.0,72 +703,100.0,100 +704,96.0,96 +705,111.0,111 +706,27.0,27 +707,107.0,107 +708,87.0,87 +709,114.0,114 +710,111.0,111 +711,88.0,88 +712,112.0,112 +713,108.0,108 +714,108.0,108 +715,103.0,103 +716,120.0,120 +717,116.0,116 +718,112.0,112 +719,99.0,99 +720,118.0,118 +721,114.0,114 +722,104.0,104 +723,99.0,99 +724,102.0,102 +725,106.0,106 +726,31.0,31 +727,91.0,91 +728,32.0,32 +729,96.0,96 +730,20.0,20 +731,33.0,33 +732,23.0,23 +733,80.0,80 +734,35.0,35 +735,88.0,88 +736,28.0,28 +737,26.0,26 +738,70.0,70 +739,86.0,86 +740,28.0,28 +741,39.0,39 +742,65.0,65 +743,52.0,52 +744,43.0,43 +745,97.0,97 +746,27.0,27 +747,89.0,89 +748,34.0,34 +749,35.0,35 +750,28.0,28 +751,96.0,96 +752,97.0,97 +753,108.0,108 +754,45.0,45 +755,103.0,103 +756,97.0,97 +757,114.0,114 +758,103.0,103 +759,116.0,116 +760,127.0,127 +761,122.0,122 +762,112.0,112 +763,112.0,112 +764,120.0,120 +765,129.0,129 +766,127.0,127 +767,125.0,125 +768,124.0,124 +769,126.0,126 +770,129.0,129 +771,129.0,129 +772,43.0,43 +773,121.0,121 +774,40.0,40 +775,116.0,116 +776,117.0,117 +777,113.0,113 +778,117.0,117 +779,108.0,108 +780,108.0,108 +781,119.0,119 +782,109.0,109 +783,116.0,116 +784,114.0,114 +785,45.0,45 +786,116.0,116 +787,116.0,116 +788,110.0,110 +789,105.0,105 +790,110.0,110 +791,112.0,112 +792,104.0,104 +793,120.0,120 +794,110.0,110 +795,113.0,113 +796,33.0,33 +797,111.0,111 +798,31.0,31 +799,139.0,139 +800,110.0,110 +801,124.0,124 +802,120.0,120 +803,112.0,112 +804,116.0,116 +805,105.0,105 +806,125.0,125 +807,103.0,103 +808,122.0,122 +809,109.0,109 +810,118.0,118 +811,124.0,124 +812,115.0,115 +813,26.0,26 +814,118.0,118 +815,118.0,118 +816,31.0,31 +817,99.0,99 +818,122.0,122 +819,102.0,102 +820,111.0,111 +821,110.0,110 +822,113.0,113 +823,117.0,117 +824,113.0,113 +825,109.0,109 +826,122.0,122 +827,117.0,117 +828,127.0,127 +829,113.0,113 +830,118.0,118 +831,107.0,107 +832,108.0,108 +833,103.0,103 +834,126.0,126 +835,131.0,131 +836,106.0,106 +837,116.0,116 +838,24.0,24 +839,107.0,107 +840,124.0,124 +841,125.0,125 +842,110.0,110 +843,112.0,112 +844,105.0,105 +845,104.0,104 +846,134.0,134 +847,107.0,107 +848,128.0,128 +849,113.0,113 +850,138.0,138 +851,118.0,118 +852,142.0,142 +853,118.0,118 +854,122.0,122 +855,130.0,130 +856,126.0,126 +857,111.0,111 +858,114.0,114 +859,128.0,128 +860,126.0,126 +861,143.0,143 +862,132.0,132 +863,123.0,123 +864,111.0,111 +865,129.0,129 +866,121.0,121 +867,114.0,114 +868,110.0,110 +869,118.0,118 +870,120.0,120 +871,109.0,109 +872,106.0,106 +873,118.0,118 +874,104.0,104 +875,98.0,98 +876,115.0,115 +877,34.0,34 +878,96.0,96 +879,108.0,108 +880,105.0,105 +881,33.0,33 +882,105.0,105 +883,111.0,111 +884,112.0,112 +885,101.0,101 +886,25.0,25 +887,35.0,35 +888,99.0,99 +889,105.0,105 +890,36.0,36 +891,92.0,92 +892,104.0,104 +893,111.0,111 +894,106.0,106 +895,109.0,109 +896,108.0,108 +897,101.0,101 +898,100.0,100 +899,33.0,33 +900,119.0,119 +901,112.0,112 +902,112.0,112 +903,126.0,126 +904,123.0,123 +905,125.0,125 +906,107.0,107 +907,128.0,128 +908,119.0,119 +909,142.0,142 +910,117.0,117 +911,125.0,125 +912,141.0,141 +913,134.0,134 +914,131.0,131 +915,131.0,131 +916,140.0,140 +917,115.0,115 +918,142.0,142 +919,142.0,142 +920,128.0,128 +921,139.0,139 +922,133.0,133 +923,129.0,129 +924,124.0,124 +925,131.0,131 +926,125.0,125 +927,146.0,146 +928,118.0,118 +929,126.0,126 +930,134.0,134 +931,155.0,155 +932,134.0,134 +933,136.0,136 +934,146.0,146 +935,150.0,150 +936,167.0,167 +937,135.0,135 +938,197.0,197 +939,190.0,190 +940,170.0,170 +941,179.0,179 +942,192.0,192 +943,200.0,200 +944,200.0,200 +945,200.0,200 +946,200.0,200 +947,200.0,200 +948,200.0,200 +949,200.0,200 +950,200.0,200 +951,200.0,200 +952,200.0,200 +953,200.0,200 +954,200.0,200 +955,200.0,200 +956,200.0,200 +957,200.0,200 +958,200.0,200 +959,200.0,200 +960,200.0,200 +961,200.0,200 +962,200.0,200 +963,200.0,200 +964,200.0,200 +965,200.0,200 +966,200.0,200 +967,200.0,200 +968,200.0,200 +969,200.0,200 +970,200.0,200 +971,200.0,200 +972,200.0,200 +973,200.0,200 +974,200.0,200 +975,200.0,200 +976,200.0,200 +977,200.0,200 +978,200.0,200 +979,200.0,200 +980,200.0,200 +981,200.0,200 +982,200.0,200 +983,200.0,200 +984,200.0,200 +985,200.0,200 +986,200.0,200 +987,200.0,200 +988,200.0,200 +989,200.0,200 +990,200.0,200 +991,198.0,198 +992,200.0,200 +993,200.0,200 +994,200.0,200 +995,200.0,200 +996,200.0,200 +997,200.0,200 +998,200.0,200 +999,200.0,200 diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/config.yaml b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/config.yaml new file mode 100644 index 0000000..49d9701 --- /dev/null +++ b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/config.yaml @@ -0,0 +1,24 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: CartPole-v1 + eval_eps: 10 + eval_per_episode: 5 + load_checkpoint: false + load_path: tasks + max_steps: 200 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 1000 +algo_cfg: + actor_hidden_dim: 256 + actor_lr: 0.0003 + batch_size: 64 + buffer_size: 100000 + critic_hidden_dim: 256 + critic_lr: 0.001 + gamma: 0.99 + hidden_dim: 256 diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/logs/log.txt b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/logs/log.txt new file mode 100644 index 0000000..18436c8 --- /dev/null +++ b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/logs/log.txt @@ -0,0 +1,1086 @@ +2022-10-31 23:21:38 - r - INFO: - n_states: 4, n_actions: 2 +2022-10-31 23:21:38 - r - INFO: - Actor model name: ActorSoftmaxTanh +2022-10-31 23:21:38 - r - INFO: - Critic model name: Critic +2022-10-31 23:21:38 - r - INFO: - ACMemory memory name: PGReplay +2022-10-31 23:21:38 - r - INFO: - agent name: A2C +2022-10-31 23:21:38 - r - INFO: - Start training! +2022-10-31 23:21:38 - r - INFO: - Env: CartPole-v1, Algorithm: A2C, Device: cuda +2022-10-31 23:21:40 - r - INFO: - Episode: 1/1000, Reward: 25.0, Step: 25 +2022-10-31 23:21:40 - r - INFO: - Episode: 2/1000, Reward: 11.0, Step: 11 +2022-10-31 23:21:41 - r - INFO: - Episode: 3/1000, Reward: 32.0, Step: 32 +2022-10-31 23:21:41 - r - INFO: - Episode: 4/1000, Reward: 11.0, Step: 11 +2022-10-31 23:21:41 - r - INFO: - Episode: 5/1000, Reward: 14.0, Step: 14 +2022-10-31 23:21:41 - r - INFO: - Current episode 5 has the best eval reward: 19.90 +2022-10-31 23:21:41 - r - INFO: - Episode: 6/1000, Reward: 11.0, Step: 11 +2022-10-31 23:21:41 - r - INFO: - Episode: 7/1000, Reward: 23.0, Step: 23 +2022-10-31 23:21:41 - r - INFO: - Episode: 8/1000, Reward: 27.0, Step: 27 +2022-10-31 23:21:41 - r - INFO: - Episode: 9/1000, Reward: 10.0, Step: 10 +2022-10-31 23:21:41 - r - INFO: - Episode: 10/1000, Reward: 21.0, Step: 21 +2022-10-31 23:21:41 - r - INFO: - Episode: 11/1000, Reward: 15.0, Step: 15 +2022-10-31 23:21:41 - r - INFO: - Episode: 12/1000, Reward: 26.0, Step: 26 +2022-10-31 23:21:41 - r - INFO: - Episode: 13/1000, Reward: 22.0, Step: 22 +2022-10-31 23:21:41 - r - INFO: - Episode: 14/1000, Reward: 14.0, Step: 14 +2022-10-31 23:21:41 - r - INFO: - Episode: 15/1000, Reward: 14.0, Step: 14 +2022-10-31 23:21:41 - r - INFO: - Episode: 16/1000, Reward: 21.0, Step: 21 +2022-10-31 23:21:41 - r - INFO: - Episode: 17/1000, Reward: 10.0, Step: 10 +2022-10-31 23:21:42 - r - INFO: - Episode: 18/1000, Reward: 19.0, Step: 19 +2022-10-31 23:21:42 - r - INFO: - Episode: 19/1000, Reward: 18.0, Step: 18 +2022-10-31 23:21:42 - r - INFO: - Episode: 20/1000, Reward: 26.0, Step: 26 +2022-10-31 23:21:42 - r - INFO: - Current episode 20 has the best eval reward: 21.50 +2022-10-31 23:21:42 - r - INFO: - Episode: 21/1000, Reward: 29.0, Step: 29 +2022-10-31 23:21:42 - r - INFO: - Episode: 22/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:42 - r - INFO: - Episode: 23/1000, Reward: 35.0, Step: 35 +2022-10-31 23:21:42 - r - INFO: - Episode: 24/1000, Reward: 33.0, Step: 33 +2022-10-31 23:21:42 - r - INFO: - Episode: 25/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:43 - r - INFO: - Current episode 25 has the best eval reward: 31.90 +2022-10-31 23:21:43 - r - INFO: - Episode: 26/1000, Reward: 50.0, Step: 50 +2022-10-31 23:21:43 - r - INFO: - Episode: 27/1000, Reward: 21.0, Step: 21 +2022-10-31 23:21:43 - r - INFO: - Episode: 28/1000, Reward: 30.0, Step: 30 +2022-10-31 23:21:43 - r - INFO: - Episode: 29/1000, Reward: 26.0, Step: 26 +2022-10-31 23:21:43 - r - INFO: - Episode: 30/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:43 - r - INFO: - Current episode 30 has the best eval reward: 56.70 +2022-10-31 23:21:43 - r - INFO: - Episode: 31/1000, Reward: 31.0, Step: 31 +2022-10-31 23:21:43 - r - INFO: - Episode: 32/1000, Reward: 54.0, Step: 54 +2022-10-31 23:21:43 - r - INFO: - Episode: 33/1000, Reward: 59.0, Step: 59 +2022-10-31 23:21:44 - r - INFO: - Episode: 34/1000, Reward: 50.0, Step: 50 +2022-10-31 23:21:44 - r - INFO: - Episode: 35/1000, Reward: 26.0, Step: 26 +2022-10-31 23:21:44 - r - INFO: - Episode: 36/1000, Reward: 34.0, Step: 34 +2022-10-31 23:21:44 - r - INFO: - Episode: 37/1000, Reward: 25.0, Step: 25 +2022-10-31 23:21:44 - r - INFO: - Episode: 38/1000, Reward: 166.0, Step: 166 +2022-10-31 23:21:44 - r - INFO: - Episode: 39/1000, Reward: 35.0, Step: 35 +2022-10-31 23:21:44 - r - INFO: - Episode: 40/1000, Reward: 25.0, Step: 25 +2022-10-31 23:21:45 - r - INFO: - Episode: 41/1000, Reward: 110.0, Step: 110 +2022-10-31 23:21:45 - r - INFO: - Episode: 42/1000, Reward: 22.0, Step: 22 +2022-10-31 23:21:45 - r - INFO: - Episode: 43/1000, Reward: 57.0, Step: 57 +2022-10-31 23:21:45 - r - INFO: - Episode: 44/1000, Reward: 45.0, Step: 45 +2022-10-31 23:21:45 - r - INFO: - Episode: 45/1000, Reward: 35.0, Step: 35 +2022-10-31 23:21:45 - r - INFO: - Episode: 46/1000, Reward: 45.0, Step: 45 +2022-10-31 23:21:45 - r - INFO: - Episode: 47/1000, Reward: 51.0, Step: 51 +2022-10-31 23:21:46 - r - INFO: - Episode: 48/1000, Reward: 32.0, Step: 32 +2022-10-31 23:21:46 - r - INFO: - Episode: 49/1000, Reward: 67.0, Step: 67 +2022-10-31 23:21:46 - r - INFO: - Episode: 50/1000, Reward: 46.0, Step: 46 +2022-10-31 23:21:46 - r - INFO: - Episode: 51/1000, Reward: 61.0, Step: 61 +2022-10-31 23:21:46 - r - INFO: - Episode: 52/1000, Reward: 49.0, Step: 49 +2022-10-31 23:21:46 - r - INFO: - Episode: 53/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:46 - r - INFO: - Episode: 54/1000, Reward: 37.0, Step: 37 +2022-10-31 23:21:46 - r - INFO: - Episode: 55/1000, Reward: 32.0, Step: 32 +2022-10-31 23:21:47 - r - INFO: - Current episode 55 has the best eval reward: 85.50 +2022-10-31 23:21:47 - r - INFO: - Episode: 56/1000, Reward: 31.0, Step: 31 +2022-10-31 23:21:47 - r - INFO: - Episode: 57/1000, Reward: 33.0, Step: 33 +2022-10-31 23:21:47 - r - INFO: - Episode: 58/1000, Reward: 93.0, Step: 93 +2022-10-31 23:21:47 - r - INFO: - Episode: 59/1000, Reward: 60.0, Step: 60 +2022-10-31 23:21:48 - r - INFO: - Episode: 60/1000, Reward: 128.0, Step: 128 +2022-10-31 23:21:48 - r - INFO: - Episode: 61/1000, Reward: 200.0, Step: 200 +2022-10-31 23:21:48 - r - INFO: - Episode: 62/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:48 - r - INFO: - Episode: 63/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:49 - r - INFO: - Episode: 64/1000, Reward: 63.0, Step: 63 +2022-10-31 23:21:49 - r - INFO: - Episode: 65/1000, Reward: 68.0, Step: 68 +2022-10-31 23:21:49 - r - INFO: - Episode: 66/1000, Reward: 45.0, Step: 45 +2022-10-31 23:21:49 - r - INFO: - Episode: 67/1000, Reward: 101.0, Step: 101 +2022-10-31 23:21:49 - r - INFO: - Episode: 68/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:49 - r - INFO: - Episode: 69/1000, Reward: 49.0, Step: 49 +2022-10-31 23:21:50 - r - INFO: - Episode: 70/1000, Reward: 54.0, Step: 54 +2022-10-31 23:21:50 - r - INFO: - Episode: 71/1000, Reward: 42.0, Step: 42 +2022-10-31 23:21:50 - r - INFO: - Episode: 72/1000, Reward: 77.0, Step: 77 +2022-10-31 23:21:50 - r - INFO: - Episode: 73/1000, Reward: 67.0, Step: 67 +2022-10-31 23:21:50 - r - INFO: - Episode: 74/1000, Reward: 41.0, Step: 41 +2022-10-31 23:21:51 - r - INFO: - Episode: 75/1000, Reward: 89.0, Step: 89 +2022-10-31 23:21:51 - r - INFO: - Episode: 76/1000, Reward: 51.0, Step: 51 +2022-10-31 23:21:51 - r - INFO: - Episode: 77/1000, Reward: 54.0, Step: 54 +2022-10-31 23:21:51 - r - INFO: - Episode: 78/1000, Reward: 37.0, Step: 37 +2022-10-31 23:21:51 - r - INFO: - Episode: 79/1000, Reward: 49.0, Step: 49 +2022-10-31 23:21:51 - r - INFO: - Episode: 80/1000, Reward: 46.0, Step: 46 +2022-10-31 23:21:52 - r - INFO: - Episode: 81/1000, Reward: 31.0, Step: 31 +2022-10-31 23:21:52 - r - INFO: - Episode: 82/1000, Reward: 43.0, Step: 43 +2022-10-31 23:21:52 - r - INFO: - Episode: 83/1000, Reward: 60.0, Step: 60 +2022-10-31 23:21:52 - r - INFO: - Episode: 84/1000, Reward: 41.0, Step: 41 +2022-10-31 23:21:52 - r - INFO: - Episode: 85/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:52 - r - INFO: - Episode: 86/1000, Reward: 28.0, Step: 28 +2022-10-31 23:21:52 - r - INFO: - Episode: 87/1000, Reward: 50.0, Step: 50 +2022-10-31 23:21:53 - r - INFO: - Episode: 88/1000, Reward: 159.0, Step: 159 +2022-10-31 23:21:53 - r - INFO: - Episode: 89/1000, Reward: 30.0, Step: 30 +2022-10-31 23:21:53 - r - INFO: - Episode: 90/1000, Reward: 34.0, Step: 34 +2022-10-31 23:21:53 - r - INFO: - Episode: 91/1000, Reward: 70.0, Step: 70 +2022-10-31 23:21:53 - r - INFO: - Episode: 92/1000, Reward: 22.0, Step: 22 +2022-10-31 23:21:53 - r - INFO: - Episode: 93/1000, Reward: 39.0, Step: 39 +2022-10-31 23:21:53 - r - INFO: - Episode: 94/1000, Reward: 50.0, Step: 50 +2022-10-31 23:21:53 - r - INFO: - Episode: 95/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:54 - r - INFO: - Episode: 96/1000, Reward: 37.0, Step: 37 +2022-10-31 23:21:54 - r - INFO: - Episode: 97/1000, Reward: 121.0, Step: 121 +2022-10-31 23:21:54 - r - INFO: - Episode: 98/1000, Reward: 26.0, Step: 26 +2022-10-31 23:21:54 - r - INFO: - Episode: 99/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:54 - r - INFO: - Episode: 100/1000, Reward: 30.0, Step: 30 +2022-10-31 23:21:55 - r - INFO: - Episode: 101/1000, Reward: 35.0, Step: 35 +2022-10-31 23:21:55 - r - INFO: - Episode: 102/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:55 - r - INFO: - Episode: 103/1000, Reward: 28.0, Step: 28 +2022-10-31 23:21:55 - r - INFO: - Episode: 104/1000, Reward: 29.0, Step: 29 +2022-10-31 23:21:55 - r - INFO: - Episode: 105/1000, Reward: 42.0, Step: 42 +2022-10-31 23:21:55 - r - INFO: - Episode: 106/1000, Reward: 54.0, Step: 54 +2022-10-31 23:21:55 - r - INFO: - Episode: 107/1000, Reward: 25.0, Step: 25 +2022-10-31 23:21:55 - r - INFO: - Episode: 108/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:55 - r - INFO: - Episode: 109/1000, Reward: 32.0, Step: 32 +2022-10-31 23:21:55 - r - INFO: - Episode: 110/1000, Reward: 50.0, Step: 50 +2022-10-31 23:21:56 - r - INFO: - Episode: 111/1000, Reward: 30.0, Step: 30 +2022-10-31 23:21:56 - r - INFO: - Episode: 112/1000, Reward: 58.0, Step: 58 +2022-10-31 23:21:56 - r - INFO: - Episode: 113/1000, Reward: 32.0, Step: 32 +2022-10-31 23:21:56 - r - INFO: - Episode: 114/1000, Reward: 43.0, Step: 43 +2022-10-31 23:21:56 - r - INFO: - Episode: 115/1000, Reward: 57.0, Step: 57 +2022-10-31 23:21:56 - r - INFO: - Episode: 116/1000, Reward: 20.0, Step: 20 +2022-10-31 23:21:57 - r - INFO: - Episode: 117/1000, Reward: 48.0, Step: 48 +2022-10-31 23:21:57 - r - INFO: - Episode: 118/1000, Reward: 45.0, Step: 45 +2022-10-31 23:21:57 - r - INFO: - Episode: 119/1000, Reward: 47.0, Step: 47 +2022-10-31 23:21:57 - r - INFO: - Episode: 120/1000, Reward: 69.0, Step: 69 +2022-10-31 23:21:57 - r - INFO: - Episode: 121/1000, Reward: 34.0, Step: 34 +2022-10-31 23:21:57 - r - INFO: - Episode: 122/1000, Reward: 22.0, Step: 22 +2022-10-31 23:21:57 - r - INFO: - Episode: 123/1000, Reward: 22.0, Step: 22 +2022-10-31 23:21:57 - r - INFO: - Episode: 124/1000, Reward: 38.0, Step: 38 +2022-10-31 23:21:57 - r - INFO: - Episode: 125/1000, Reward: 36.0, Step: 36 +2022-10-31 23:21:58 - r - INFO: - Episode: 126/1000, Reward: 41.0, Step: 41 +2022-10-31 23:21:58 - r - INFO: - Episode: 127/1000, Reward: 28.0, Step: 28 +2022-10-31 23:21:58 - r - INFO: - Episode: 128/1000, Reward: 35.0, Step: 35 +2022-10-31 23:21:58 - r - INFO: - Episode: 129/1000, Reward: 48.0, Step: 48 +2022-10-31 23:21:58 - r - INFO: - Episode: 130/1000, Reward: 51.0, Step: 51 +2022-10-31 23:21:58 - r - INFO: - Episode: 131/1000, Reward: 51.0, Step: 51 +2022-10-31 23:21:58 - r - INFO: - Episode: 132/1000, Reward: 36.0, Step: 36 +2022-10-31 23:21:59 - r - INFO: - Episode: 133/1000, Reward: 45.0, Step: 45 +2022-10-31 23:21:59 - r - INFO: - Episode: 134/1000, Reward: 27.0, Step: 27 +2022-10-31 23:21:59 - r - INFO: - Episode: 135/1000, Reward: 40.0, Step: 40 +2022-10-31 23:21:59 - r - INFO: - Episode: 136/1000, Reward: 43.0, Step: 43 +2022-10-31 23:21:59 - r - INFO: - Episode: 137/1000, Reward: 64.0, Step: 64 +2022-10-31 23:21:59 - r - INFO: - Episode: 138/1000, Reward: 43.0, Step: 43 +2022-10-31 23:21:59 - r - INFO: - Episode: 139/1000, Reward: 37.0, Step: 37 +2022-10-31 23:21:59 - r - INFO: - Episode: 140/1000, Reward: 38.0, Step: 38 +2022-10-31 23:22:00 - r - INFO: - Episode: 141/1000, Reward: 69.0, Step: 69 +2022-10-31 23:22:00 - r - INFO: - Episode: 142/1000, Reward: 36.0, Step: 36 +2022-10-31 23:22:00 - r - INFO: - Episode: 143/1000, Reward: 28.0, Step: 28 +2022-10-31 23:22:00 - r - INFO: - Episode: 144/1000, Reward: 58.0, Step: 58 +2022-10-31 23:22:00 - r - INFO: - Episode: 145/1000, Reward: 43.0, Step: 43 +2022-10-31 23:22:00 - r - INFO: - Episode: 146/1000, Reward: 50.0, Step: 50 +2022-10-31 23:22:01 - r - INFO: - Episode: 147/1000, Reward: 30.0, Step: 30 +2022-10-31 23:22:01 - r - INFO: - Episode: 148/1000, Reward: 42.0, Step: 42 +2022-10-31 23:22:01 - r - INFO: - Episode: 149/1000, Reward: 42.0, Step: 42 +2022-10-31 23:22:01 - r - INFO: - Episode: 150/1000, Reward: 35.0, Step: 35 +2022-10-31 23:22:01 - r - INFO: - Episode: 151/1000, Reward: 67.0, Step: 67 +2022-10-31 23:22:01 - r - INFO: - Episode: 152/1000, Reward: 45.0, Step: 45 +2022-10-31 23:22:01 - r - INFO: - Episode: 153/1000, Reward: 28.0, Step: 28 +2022-10-31 23:22:01 - r - INFO: - Episode: 154/1000, Reward: 59.0, Step: 59 +2022-10-31 23:22:02 - r - INFO: - Episode: 155/1000, Reward: 64.0, Step: 64 +2022-10-31 23:22:02 - r - INFO: - Episode: 156/1000, Reward: 67.0, Step: 67 +2022-10-31 23:22:02 - r - INFO: - Episode: 157/1000, Reward: 41.0, Step: 41 +2022-10-31 23:22:02 - r - INFO: - Episode: 158/1000, Reward: 81.0, Step: 81 +2022-10-31 23:22:02 - r - INFO: - Episode: 159/1000, Reward: 76.0, Step: 76 +2022-10-31 23:22:02 - r - INFO: - Episode: 160/1000, Reward: 91.0, Step: 91 +2022-10-31 23:22:03 - r - INFO: - Episode: 161/1000, Reward: 119.0, Step: 119 +2022-10-31 23:22:03 - r - INFO: - Episode: 162/1000, Reward: 47.0, Step: 47 +2022-10-31 23:22:03 - r - INFO: - Episode: 163/1000, Reward: 64.0, Step: 64 +2022-10-31 23:22:03 - r - INFO: - Episode: 164/1000, Reward: 178.0, Step: 178 +2022-10-31 23:22:04 - r - INFO: - Episode: 165/1000, Reward: 97.0, Step: 97 +2022-10-31 23:22:04 - r - INFO: - Current episode 165 has the best eval reward: 104.10 +2022-10-31 23:22:04 - r - INFO: - Episode: 166/1000, Reward: 181.0, Step: 181 +2022-10-31 23:22:05 - r - INFO: - Episode: 167/1000, Reward: 166.0, Step: 166 +2022-10-31 23:22:05 - r - INFO: - Episode: 168/1000, Reward: 79.0, Step: 79 +2022-10-31 23:22:05 - r - INFO: - Episode: 169/1000, Reward: 141.0, Step: 141 +2022-10-31 23:22:06 - r - INFO: - Episode: 170/1000, Reward: 119.0, Step: 119 +2022-10-31 23:22:06 - r - INFO: - Current episode 170 has the best eval reward: 119.50 +2022-10-31 23:22:06 - r - INFO: - Episode: 171/1000, Reward: 81.0, Step: 81 +2022-10-31 23:22:06 - r - INFO: - Episode: 172/1000, Reward: 124.0, Step: 124 +2022-10-31 23:22:07 - r - INFO: - Episode: 173/1000, Reward: 150.0, Step: 150 +2022-10-31 23:22:07 - r - INFO: - Episode: 174/1000, Reward: 98.0, Step: 98 +2022-10-31 23:22:07 - r - INFO: - Episode: 175/1000, Reward: 164.0, Step: 164 +2022-10-31 23:22:08 - r - INFO: - Current episode 175 has the best eval reward: 132.00 +2022-10-31 23:22:08 - r - INFO: - Episode: 176/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:09 - r - INFO: - Episode: 177/1000, Reward: 115.0, Step: 115 +2022-10-31 23:22:09 - r - INFO: - Episode: 178/1000, Reward: 116.0, Step: 116 +2022-10-31 23:22:09 - r - INFO: - Episode: 179/1000, Reward: 160.0, Step: 160 +2022-10-31 23:22:09 - r - INFO: - Episode: 180/1000, Reward: 103.0, Step: 103 +2022-10-31 23:22:10 - r - INFO: - Current episode 180 has the best eval reward: 134.00 +2022-10-31 23:22:10 - r - INFO: - Episode: 181/1000, Reward: 181.0, Step: 181 +2022-10-31 23:22:11 - r - INFO: - Episode: 182/1000, Reward: 185.0, Step: 185 +2022-10-31 23:22:11 - r - INFO: - Episode: 183/1000, Reward: 93.0, Step: 93 +2022-10-31 23:22:11 - r - INFO: - Episode: 184/1000, Reward: 110.0, Step: 110 +2022-10-31 23:22:12 - r - INFO: - Episode: 185/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:12 - r - INFO: - Current episode 185 has the best eval reward: 155.50 +2022-10-31 23:22:13 - r - INFO: - Episode: 186/1000, Reward: 141.0, Step: 141 +2022-10-31 23:22:13 - r - INFO: - Episode: 187/1000, Reward: 150.0, Step: 150 +2022-10-31 23:22:13 - r - INFO: - Episode: 188/1000, Reward: 121.0, Step: 121 +2022-10-31 23:22:13 - r - INFO: - Episode: 189/1000, Reward: 110.0, Step: 110 +2022-10-31 23:22:14 - r - INFO: - Episode: 190/1000, Reward: 115.0, Step: 115 +2022-10-31 23:22:14 - r - INFO: - Episode: 191/1000, Reward: 114.0, Step: 114 +2022-10-31 23:22:14 - r - INFO: - Episode: 192/1000, Reward: 45.0, Step: 45 +2022-10-31 23:22:15 - r - INFO: - Episode: 193/1000, Reward: 125.0, Step: 125 +2022-10-31 23:22:15 - r - INFO: - Episode: 194/1000, Reward: 142.0, Step: 142 +2022-10-31 23:22:15 - r - INFO: - Episode: 195/1000, Reward: 54.0, Step: 54 +2022-10-31 23:22:16 - r - INFO: - Episode: 196/1000, Reward: 62.0, Step: 62 +2022-10-31 23:22:16 - r - INFO: - Episode: 197/1000, Reward: 122.0, Step: 122 +2022-10-31 23:22:16 - r - INFO: - Episode: 198/1000, Reward: 58.0, Step: 58 +2022-10-31 23:22:16 - r - INFO: - Episode: 199/1000, Reward: 88.0, Step: 88 +2022-10-31 23:22:16 - r - INFO: - Episode: 200/1000, Reward: 141.0, Step: 141 +2022-10-31 23:22:17 - r - INFO: - Episode: 201/1000, Reward: 113.0, Step: 113 +2022-10-31 23:22:18 - r - INFO: - Episode: 202/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:18 - r - INFO: - Episode: 203/1000, Reward: 136.0, Step: 136 +2022-10-31 23:22:18 - r - INFO: - Episode: 204/1000, Reward: 114.0, Step: 114 +2022-10-31 23:22:18 - r - INFO: - Episode: 205/1000, Reward: 102.0, Step: 102 +2022-10-31 23:22:19 - r - INFO: - Episode: 206/1000, Reward: 176.0, Step: 176 +2022-10-31 23:22:20 - r - INFO: - Episode: 207/1000, Reward: 150.0, Step: 150 +2022-10-31 23:22:20 - r - INFO: - Episode: 208/1000, Reward: 105.0, Step: 105 +2022-10-31 23:22:20 - r - INFO: - Episode: 209/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:21 - r - INFO: - Episode: 210/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:21 - r - INFO: - Episode: 211/1000, Reward: 167.0, Step: 167 +2022-10-31 23:22:22 - r - INFO: - Episode: 212/1000, Reward: 104.0, Step: 104 +2022-10-31 23:22:22 - r - INFO: - Episode: 213/1000, Reward: 124.0, Step: 124 +2022-10-31 23:22:22 - r - INFO: - Episode: 214/1000, Reward: 96.0, Step: 96 +2022-10-31 23:22:23 - r - INFO: - Episode: 215/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:24 - r - INFO: - Episode: 216/1000, Reward: 199.0, Step: 199 +2022-10-31 23:22:24 - r - INFO: - Episode: 217/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:24 - r - INFO: - Episode: 218/1000, Reward: 132.0, Step: 132 +2022-10-31 23:22:25 - r - INFO: - Episode: 219/1000, Reward: 188.0, Step: 188 +2022-10-31 23:22:25 - r - INFO: - Episode: 220/1000, Reward: 132.0, Step: 132 +2022-10-31 23:22:26 - r - INFO: - Episode: 221/1000, Reward: 151.0, Step: 151 +2022-10-31 23:22:26 - r - INFO: - Episode: 222/1000, Reward: 125.0, Step: 125 +2022-10-31 23:22:26 - r - INFO: - Episode: 223/1000, Reward: 42.0, Step: 42 +2022-10-31 23:22:27 - r - INFO: - Episode: 224/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:27 - r - INFO: - Episode: 225/1000, Reward: 159.0, Step: 159 +2022-10-31 23:22:28 - r - INFO: - Episode: 226/1000, Reward: 171.0, Step: 171 +2022-10-31 23:22:28 - r - INFO: - Episode: 227/1000, Reward: 122.0, Step: 122 +2022-10-31 23:22:29 - r - INFO: - Episode: 228/1000, Reward: 189.0, Step: 189 +2022-10-31 23:22:29 - r - INFO: - Episode: 229/1000, Reward: 129.0, Step: 129 +2022-10-31 23:22:29 - r - INFO: - Episode: 230/1000, Reward: 106.0, Step: 106 +2022-10-31 23:22:30 - r - INFO: - Episode: 231/1000, Reward: 107.0, Step: 107 +2022-10-31 23:22:30 - r - INFO: - Episode: 232/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:31 - r - INFO: - Episode: 233/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:31 - r - INFO: - Episode: 234/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:32 - r - INFO: - Episode: 235/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:32 - r - INFO: - Current episode 235 has the best eval reward: 169.70 +2022-10-31 23:22:33 - r - INFO: - Episode: 236/1000, Reward: 158.0, Step: 158 +2022-10-31 23:22:33 - r - INFO: - Episode: 237/1000, Reward: 200.0, Step: 200 +2022-10-31 23:22:33 - r - INFO: - Episode: 238/1000, Reward: 192.0, Step: 192 +2022-10-31 23:22:34 - r - INFO: - Episode: 239/1000, Reward: 179.0, Step: 179 +2022-10-31 23:22:34 - r - INFO: - Episode: 240/1000, Reward: 102.0, Step: 102 +2022-10-31 23:22:35 - r - INFO: - Episode: 241/1000, Reward: 125.0, Step: 125 +2022-10-31 23:22:35 - r - INFO: - Episode: 242/1000, Reward: 138.0, Step: 138 +2022-10-31 23:22:36 - r - INFO: - Episode: 243/1000, Reward: 189.0, Step: 189 +2022-10-31 23:22:36 - r - INFO: - Episode: 244/1000, Reward: 41.0, Step: 41 +2022-10-31 23:22:36 - r - INFO: - Episode: 245/1000, Reward: 97.0, Step: 97 +2022-10-31 23:22:36 - r - INFO: - Episode: 246/1000, Reward: 49.0, Step: 49 +2022-10-31 23:22:37 - r - INFO: - Episode: 247/1000, Reward: 86.0, Step: 86 +2022-10-31 23:22:37 - r - INFO: - Episode: 248/1000, Reward: 121.0, Step: 121 +2022-10-31 23:22:37 - r - INFO: - Episode: 249/1000, Reward: 117.0, Step: 117 +2022-10-31 23:22:37 - r - INFO: - Episode: 250/1000, Reward: 43.0, Step: 43 +2022-10-31 23:22:38 - r - INFO: - Episode: 251/1000, Reward: 72.0, Step: 72 +2022-10-31 23:22:38 - r - INFO: - Episode: 252/1000, Reward: 34.0, Step: 34 +2022-10-31 23:22:38 - r - INFO: - Episode: 253/1000, Reward: 83.0, Step: 83 +2022-10-31 23:22:38 - r - INFO: - Episode: 254/1000, Reward: 83.0, Step: 83 +2022-10-31 23:22:38 - r - INFO: - Episode: 255/1000, Reward: 38.0, Step: 38 +2022-10-31 23:22:38 - r - INFO: - Episode: 256/1000, Reward: 34.0, Step: 34 +2022-10-31 23:22:39 - r - INFO: - Episode: 257/1000, Reward: 99.0, Step: 99 +2022-10-31 23:22:39 - r - INFO: - Episode: 258/1000, Reward: 45.0, Step: 45 +2022-10-31 23:22:39 - r - INFO: - Episode: 259/1000, Reward: 47.0, Step: 47 +2022-10-31 23:22:39 - r - INFO: - Episode: 260/1000, Reward: 44.0, Step: 44 +2022-10-31 23:22:39 - r - INFO: - Episode: 261/1000, Reward: 26.0, Step: 26 +2022-10-31 23:22:39 - r - INFO: - Episode: 262/1000, Reward: 37.0, Step: 37 +2022-10-31 23:22:39 - r - INFO: - Episode: 263/1000, Reward: 26.0, Step: 26 +2022-10-31 23:22:39 - r - INFO: - Episode: 264/1000, Reward: 43.0, Step: 43 +2022-10-31 23:22:40 - r - INFO: - Episode: 265/1000, Reward: 27.0, Step: 27 +2022-10-31 23:22:40 - r - INFO: - Episode: 266/1000, Reward: 24.0, Step: 24 +2022-10-31 23:22:40 - r - INFO: - Episode: 267/1000, Reward: 42.0, Step: 42 +2022-10-31 23:22:40 - r - INFO: - Episode: 268/1000, Reward: 86.0, Step: 86 +2022-10-31 23:22:40 - r - INFO: - Episode: 269/1000, Reward: 23.0, Step: 23 +2022-10-31 23:22:40 - r - INFO: - Episode: 270/1000, Reward: 32.0, Step: 32 +2022-10-31 23:22:40 - r - INFO: - Episode: 271/1000, Reward: 57.0, Step: 57 +2022-10-31 23:22:40 - r - INFO: - Episode: 272/1000, Reward: 25.0, Step: 25 +2022-10-31 23:22:41 - r - INFO: - Episode: 273/1000, Reward: 98.0, Step: 98 +2022-10-31 23:22:41 - r - INFO: - Episode: 274/1000, Reward: 29.0, Step: 29 +2022-10-31 23:22:41 - r - INFO: - Episode: 275/1000, Reward: 25.0, Step: 25 +2022-10-31 23:22:41 - r - INFO: - Episode: 276/1000, Reward: 29.0, Step: 29 +2022-10-31 23:22:41 - r - INFO: - Episode: 277/1000, Reward: 39.0, Step: 39 +2022-10-31 23:22:41 - r - INFO: - Episode: 278/1000, Reward: 20.0, Step: 20 +2022-10-31 23:22:41 - r - INFO: - Episode: 279/1000, Reward: 92.0, Step: 92 +2022-10-31 23:22:41 - r - INFO: - Episode: 280/1000, Reward: 28.0, Step: 28 +2022-10-31 23:22:42 - r - INFO: - Episode: 281/1000, Reward: 78.0, Step: 78 +2022-10-31 23:22:42 - r - INFO: - Episode: 282/1000, Reward: 25.0, Step: 25 +2022-10-31 23:22:42 - r - INFO: - Episode: 283/1000, Reward: 31.0, Step: 31 +2022-10-31 23:22:42 - r - INFO: - Episode: 284/1000, Reward: 88.0, Step: 88 +2022-10-31 23:22:42 - r - INFO: - Episode: 285/1000, Reward: 85.0, Step: 85 +2022-10-31 23:22:43 - r - INFO: - Episode: 286/1000, Reward: 37.0, Step: 37 +2022-10-31 23:22:43 - r - INFO: - Episode: 287/1000, Reward: 26.0, Step: 26 +2022-10-31 23:22:43 - r - INFO: - Episode: 288/1000, Reward: 19.0, Step: 19 +2022-10-31 23:22:43 - r - INFO: - Episode: 289/1000, Reward: 40.0, Step: 40 +2022-10-31 23:22:43 - r - INFO: - Episode: 290/1000, Reward: 27.0, Step: 27 +2022-10-31 23:22:43 - r - INFO: - Episode: 291/1000, Reward: 17.0, Step: 17 +2022-10-31 23:22:43 - r - INFO: - Episode: 292/1000, Reward: 27.0, Step: 27 +2022-10-31 23:22:43 - r - INFO: - Episode: 293/1000, Reward: 26.0, Step: 26 +2022-10-31 23:22:43 - r - INFO: - Episode: 294/1000, Reward: 82.0, Step: 82 +2022-10-31 23:22:43 - r - INFO: - Episode: 295/1000, Reward: 36.0, Step: 36 +2022-10-31 23:22:44 - r - INFO: - Episode: 296/1000, Reward: 24.0, Step: 24 +2022-10-31 23:22:44 - r - INFO: - Episode: 297/1000, Reward: 30.0, Step: 30 +2022-10-31 23:22:44 - r - INFO: - Episode: 298/1000, Reward: 20.0, Step: 20 +2022-10-31 23:22:44 - r - INFO: - Episode: 299/1000, Reward: 34.0, Step: 34 +2022-10-31 23:22:44 - r - INFO: - Episode: 300/1000, Reward: 30.0, Step: 30 +2022-10-31 23:22:44 - r - INFO: - Episode: 301/1000, Reward: 23.0, Step: 23 +2022-10-31 23:22:44 - r - INFO: - Episode: 302/1000, Reward: 36.0, Step: 36 +2022-10-31 23:22:44 - r - INFO: - Episode: 303/1000, Reward: 29.0, Step: 29 +2022-10-31 23:22:44 - r - INFO: - Episode: 304/1000, Reward: 34.0, Step: 34 +2022-10-31 23:22:44 - r - INFO: - Episode: 305/1000, Reward: 25.0, Step: 25 +2022-10-31 23:22:45 - r - INFO: - Episode: 306/1000, Reward: 42.0, Step: 42 +2022-10-31 23:22:45 - r - INFO: - Episode: 307/1000, Reward: 88.0, Step: 88 +2022-10-31 23:22:45 - r - INFO: - Episode: 308/1000, Reward: 26.0, Step: 26 +2022-10-31 23:22:45 - r - INFO: - Episode: 309/1000, Reward: 85.0, Step: 85 +2022-10-31 23:22:45 - r - INFO: - Episode: 310/1000, Reward: 89.0, Step: 89 +2022-10-31 23:22:46 - r - INFO: - Episode: 311/1000, Reward: 48.0, Step: 48 +2022-10-31 23:22:46 - r - INFO: - Episode: 312/1000, Reward: 83.0, Step: 83 +2022-10-31 23:22:46 - r - INFO: - Episode: 313/1000, Reward: 109.0, Step: 109 +2022-10-31 23:22:46 - r - INFO: - Episode: 314/1000, Reward: 42.0, Step: 42 +2022-10-31 23:22:46 - r - INFO: - Episode: 315/1000, Reward: 93.0, Step: 93 +2022-10-31 23:22:47 - r - INFO: - Episode: 316/1000, Reward: 85.0, Step: 85 +2022-10-31 23:22:47 - r - INFO: - Episode: 317/1000, Reward: 100.0, Step: 100 +2022-10-31 23:22:47 - r - INFO: - Episode: 318/1000, Reward: 106.0, Step: 106 +2022-10-31 23:22:47 - r - INFO: - Episode: 319/1000, Reward: 28.0, Step: 28 +2022-10-31 23:22:48 - r - INFO: - Episode: 320/1000, Reward: 108.0, Step: 108 +2022-10-31 23:22:48 - r - INFO: - Episode: 321/1000, Reward: 112.0, Step: 112 +2022-10-31 23:22:48 - r - INFO: - Episode: 322/1000, Reward: 88.0, Step: 88 +2022-10-31 23:22:49 - r - INFO: - Episode: 323/1000, Reward: 108.0, Step: 108 +2022-10-31 23:22:49 - r - INFO: - Episode: 324/1000, Reward: 108.0, Step: 108 +2022-10-31 23:22:49 - r - INFO: - Episode: 325/1000, Reward: 90.0, Step: 90 +2022-10-31 23:22:50 - r - INFO: - Episode: 326/1000, Reward: 112.0, Step: 112 +2022-10-31 23:22:50 - r - INFO: - Episode: 327/1000, Reward: 113.0, Step: 113 +2022-10-31 23:22:50 - r - INFO: - Episode: 328/1000, Reward: 94.0, Step: 94 +2022-10-31 23:22:50 - r - INFO: - Episode: 329/1000, Reward: 99.0, Step: 99 +2022-10-31 23:22:51 - r - INFO: - Episode: 330/1000, Reward: 45.0, Step: 45 +2022-10-31 23:22:51 - r - INFO: - Episode: 331/1000, Reward: 121.0, Step: 121 +2022-10-31 23:22:51 - r - INFO: - Episode: 332/1000, Reward: 102.0, Step: 102 +2022-10-31 23:22:52 - r - INFO: - Episode: 333/1000, Reward: 111.0, Step: 111 +2022-10-31 23:22:52 - r - INFO: - Episode: 334/1000, Reward: 54.0, Step: 54 +2022-10-31 23:22:52 - r - INFO: - Episode: 335/1000, Reward: 198.0, Step: 198 +2022-10-31 23:22:53 - r - INFO: - Episode: 336/1000, Reward: 83.0, Step: 83 +2022-10-31 23:22:53 - r - INFO: - Episode: 337/1000, Reward: 107.0, Step: 107 +2022-10-31 23:22:53 - r - INFO: - Episode: 338/1000, Reward: 101.0, Step: 101 +2022-10-31 23:22:54 - r - INFO: - Episode: 339/1000, Reward: 129.0, Step: 129 +2022-10-31 23:22:54 - r - INFO: - Episode: 340/1000, Reward: 88.0, Step: 88 +2022-10-31 23:22:54 - r - INFO: - Episode: 341/1000, Reward: 86.0, Step: 86 +2022-10-31 23:22:55 - r - INFO: - Episode: 342/1000, Reward: 199.0, Step: 199 +2022-10-31 23:22:55 - r - INFO: - Episode: 343/1000, Reward: 95.0, Step: 95 +2022-10-31 23:22:55 - r - INFO: - Episode: 344/1000, Reward: 103.0, Step: 103 +2022-10-31 23:22:56 - r - INFO: - Episode: 345/1000, Reward: 100.0, Step: 100 +2022-10-31 23:22:56 - r - INFO: - Episode: 346/1000, Reward: 89.0, Step: 89 +2022-10-31 23:22:56 - r - INFO: - Episode: 347/1000, Reward: 87.0, Step: 87 +2022-10-31 23:22:57 - r - INFO: - Episode: 348/1000, Reward: 110.0, Step: 110 +2022-10-31 23:22:57 - r - INFO: - Episode: 349/1000, Reward: 127.0, Step: 127 +2022-10-31 23:22:57 - r - INFO: - Episode: 350/1000, Reward: 97.0, Step: 97 +2022-10-31 23:22:57 - r - INFO: - Episode: 351/1000, Reward: 34.0, Step: 34 +2022-10-31 23:22:58 - r - INFO: - Episode: 352/1000, Reward: 123.0, Step: 123 +2022-10-31 23:22:58 - r - INFO: - Episode: 353/1000, Reward: 49.0, Step: 49 +2022-10-31 23:22:58 - r - INFO: - Episode: 354/1000, Reward: 96.0, Step: 96 +2022-10-31 23:22:58 - r - INFO: - Episode: 355/1000, Reward: 90.0, Step: 90 +2022-10-31 23:22:59 - r - INFO: - Episode: 356/1000, Reward: 110.0, Step: 110 +2022-10-31 23:22:59 - r - INFO: - Episode: 357/1000, Reward: 93.0, Step: 93 +2022-10-31 23:22:59 - r - INFO: - Episode: 358/1000, Reward: 102.0, Step: 102 +2022-10-31 23:23:00 - r - INFO: - Episode: 359/1000, Reward: 128.0, Step: 128 +2022-10-31 23:23:00 - r - INFO: - Episode: 360/1000, Reward: 125.0, Step: 125 +2022-10-31 23:23:01 - r - INFO: - Episode: 361/1000, Reward: 92.0, Step: 92 +2022-10-31 23:23:01 - r - INFO: - Episode: 362/1000, Reward: 109.0, Step: 109 +2022-10-31 23:23:01 - r - INFO: - Episode: 363/1000, Reward: 114.0, Step: 114 +2022-10-31 23:23:01 - r - INFO: - Episode: 364/1000, Reward: 111.0, Step: 111 +2022-10-31 23:23:02 - r - INFO: - Episode: 365/1000, Reward: 38.0, Step: 38 +2022-10-31 23:23:02 - r - INFO: - Episode: 366/1000, Reward: 55.0, Step: 55 +2022-10-31 23:23:02 - r - INFO: - Episode: 367/1000, Reward: 106.0, Step: 106 +2022-10-31 23:23:02 - r - INFO: - Episode: 368/1000, Reward: 115.0, Step: 115 +2022-10-31 23:23:03 - r - INFO: - Episode: 369/1000, Reward: 103.0, Step: 103 +2022-10-31 23:23:03 - r - INFO: - Episode: 370/1000, Reward: 50.0, Step: 50 +2022-10-31 23:23:03 - r - INFO: - Episode: 371/1000, Reward: 110.0, Step: 110 +2022-10-31 23:23:04 - r - INFO: - Episode: 372/1000, Reward: 102.0, Step: 102 +2022-10-31 23:23:04 - r - INFO: - Episode: 373/1000, Reward: 110.0, Step: 110 +2022-10-31 23:23:04 - r - INFO: - Episode: 374/1000, Reward: 29.0, Step: 29 +2022-10-31 23:23:04 - r - INFO: - Episode: 375/1000, Reward: 35.0, Step: 35 +2022-10-31 23:23:04 - r - INFO: - Episode: 376/1000, Reward: 42.0, Step: 42 +2022-10-31 23:23:05 - r - INFO: - Episode: 377/1000, Reward: 62.0, Step: 62 +2022-10-31 23:23:05 - r - INFO: - Episode: 378/1000, Reward: 119.0, Step: 119 +2022-10-31 23:23:05 - r - INFO: - Episode: 379/1000, Reward: 33.0, Step: 33 +2022-10-31 23:23:05 - r - INFO: - Episode: 380/1000, Reward: 31.0, Step: 31 +2022-10-31 23:23:05 - r - INFO: - Episode: 381/1000, Reward: 97.0, Step: 97 +2022-10-31 23:23:06 - r - INFO: - Episode: 382/1000, Reward: 192.0, Step: 192 +2022-10-31 23:23:06 - r - INFO: - Episode: 383/1000, Reward: 179.0, Step: 179 +2022-10-31 23:23:07 - r - INFO: - Episode: 384/1000, Reward: 89.0, Step: 89 +2022-10-31 23:23:07 - r - INFO: - Episode: 385/1000, Reward: 32.0, Step: 32 +2022-10-31 23:23:07 - r - INFO: - Episode: 386/1000, Reward: 33.0, Step: 33 +2022-10-31 23:23:07 - r - INFO: - Episode: 387/1000, Reward: 52.0, Step: 52 +2022-10-31 23:23:07 - r - INFO: - Episode: 388/1000, Reward: 31.0, Step: 31 +2022-10-31 23:23:07 - r - INFO: - Episode: 389/1000, Reward: 22.0, Step: 22 +2022-10-31 23:23:08 - r - INFO: - Episode: 390/1000, Reward: 118.0, Step: 118 +2022-10-31 23:23:08 - r - INFO: - Episode: 391/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:08 - r - INFO: - Episode: 392/1000, Reward: 115.0, Step: 115 +2022-10-31 23:23:08 - r - INFO: - Episode: 393/1000, Reward: 20.0, Step: 20 +2022-10-31 23:23:08 - r - INFO: - Episode: 394/1000, Reward: 33.0, Step: 33 +2022-10-31 23:23:08 - r - INFO: - Episode: 395/1000, Reward: 40.0, Step: 40 +2022-10-31 23:23:08 - r - INFO: - Episode: 396/1000, Reward: 27.0, Step: 27 +2022-10-31 23:23:08 - r - INFO: - Episode: 397/1000, Reward: 26.0, Step: 26 +2022-10-31 23:23:09 - r - INFO: - Episode: 398/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:09 - r - INFO: - Episode: 399/1000, Reward: 19.0, Step: 19 +2022-10-31 23:23:09 - r - INFO: - Episode: 400/1000, Reward: 22.0, Step: 22 +2022-10-31 23:23:09 - r - INFO: - Episode: 401/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:09 - r - INFO: - Episode: 402/1000, Reward: 18.0, Step: 18 +2022-10-31 23:23:09 - r - INFO: - Episode: 403/1000, Reward: 23.0, Step: 23 +2022-10-31 23:23:09 - r - INFO: - Episode: 404/1000, Reward: 27.0, Step: 27 +2022-10-31 23:23:09 - r - INFO: - Episode: 405/1000, Reward: 20.0, Step: 20 +2022-10-31 23:23:09 - r - INFO: - Episode: 406/1000, Reward: 27.0, Step: 27 +2022-10-31 23:23:09 - r - INFO: - Episode: 407/1000, Reward: 17.0, Step: 17 +2022-10-31 23:23:09 - r - INFO: - Episode: 408/1000, Reward: 27.0, Step: 27 +2022-10-31 23:23:09 - r - INFO: - Episode: 409/1000, Reward: 25.0, Step: 25 +2022-10-31 23:23:09 - r - INFO: - Episode: 410/1000, Reward: 25.0, Step: 25 +2022-10-31 23:23:09 - r - INFO: - Episode: 411/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:10 - r - INFO: - Episode: 412/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:10 - r - INFO: - Episode: 413/1000, Reward: 18.0, Step: 18 +2022-10-31 23:23:10 - r - INFO: - Episode: 414/1000, Reward: 20.0, Step: 20 +2022-10-31 23:23:10 - r - INFO: - Episode: 415/1000, Reward: 27.0, Step: 27 +2022-10-31 23:23:10 - r - INFO: - Episode: 416/1000, Reward: 28.0, Step: 28 +2022-10-31 23:23:10 - r - INFO: - Episode: 417/1000, Reward: 30.0, Step: 30 +2022-10-31 23:23:10 - r - INFO: - Episode: 418/1000, Reward: 28.0, Step: 28 +2022-10-31 23:23:10 - r - INFO: - Episode: 419/1000, Reward: 33.0, Step: 33 +2022-10-31 23:23:10 - r - INFO: - Episode: 420/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:10 - r - INFO: - Episode: 421/1000, Reward: 96.0, Step: 96 +2022-10-31 23:23:11 - r - INFO: - Episode: 422/1000, Reward: 26.0, Step: 26 +2022-10-31 23:23:11 - r - INFO: - Episode: 423/1000, Reward: 29.0, Step: 29 +2022-10-31 23:23:11 - r - INFO: - Episode: 424/1000, Reward: 25.0, Step: 25 +2022-10-31 23:23:11 - r - INFO: - Episode: 425/1000, Reward: 38.0, Step: 38 +2022-10-31 23:23:11 - r - INFO: - Episode: 426/1000, Reward: 33.0, Step: 33 +2022-10-31 23:23:11 - r - INFO: - Episode: 427/1000, Reward: 23.0, Step: 23 +2022-10-31 23:23:11 - r - INFO: - Episode: 428/1000, Reward: 39.0, Step: 39 +2022-10-31 23:23:11 - r - INFO: - Episode: 429/1000, Reward: 28.0, Step: 28 +2022-10-31 23:23:11 - r - INFO: - Episode: 430/1000, Reward: 97.0, Step: 97 +2022-10-31 23:23:12 - r - INFO: - Episode: 431/1000, Reward: 30.0, Step: 30 +2022-10-31 23:23:12 - r - INFO: - Episode: 432/1000, Reward: 29.0, Step: 29 +2022-10-31 23:23:12 - r - INFO: - Episode: 433/1000, Reward: 103.0, Step: 103 +2022-10-31 23:23:12 - r - INFO: - Episode: 434/1000, Reward: 36.0, Step: 36 +2022-10-31 23:23:12 - r - INFO: - Episode: 435/1000, Reward: 32.0, Step: 32 +2022-10-31 23:23:12 - r - INFO: - Episode: 436/1000, Reward: 41.0, Step: 41 +2022-10-31 23:23:13 - r - INFO: - Episode: 437/1000, Reward: 111.0, Step: 111 +2022-10-31 23:23:13 - r - INFO: - Episode: 438/1000, Reward: 48.0, Step: 48 +2022-10-31 23:23:13 - r - INFO: - Episode: 439/1000, Reward: 24.0, Step: 24 +2022-10-31 23:23:13 - r - INFO: - Episode: 440/1000, Reward: 49.0, Step: 49 +2022-10-31 23:23:14 - r - INFO: - Episode: 441/1000, Reward: 116.0, Step: 116 +2022-10-31 23:23:14 - r - INFO: - Episode: 442/1000, Reward: 118.0, Step: 118 +2022-10-31 23:23:14 - r - INFO: - Episode: 443/1000, Reward: 94.0, Step: 94 +2022-10-31 23:23:14 - r - INFO: - Episode: 444/1000, Reward: 132.0, Step: 132 +2022-10-31 23:23:14 - r - INFO: - Episode: 445/1000, Reward: 41.0, Step: 41 +2022-10-31 23:23:15 - r - INFO: - Episode: 446/1000, Reward: 105.0, Step: 105 +2022-10-31 23:23:15 - r - INFO: - Episode: 447/1000, Reward: 116.0, Step: 116 +2022-10-31 23:23:16 - r - INFO: - Episode: 448/1000, Reward: 136.0, Step: 136 +2022-10-31 23:23:16 - r - INFO: - Episode: 449/1000, Reward: 137.0, Step: 137 +2022-10-31 23:23:16 - r - INFO: - Episode: 450/1000, Reward: 45.0, Step: 45 +2022-10-31 23:23:17 - r - INFO: - Episode: 451/1000, Reward: 157.0, Step: 157 +2022-10-31 23:23:17 - r - INFO: - Episode: 452/1000, Reward: 116.0, Step: 116 +2022-10-31 23:23:17 - r - INFO: - Episode: 453/1000, Reward: 125.0, Step: 125 +2022-10-31 23:23:18 - r - INFO: - Episode: 454/1000, Reward: 120.0, Step: 120 +2022-10-31 23:23:18 - r - INFO: - Episode: 455/1000, Reward: 150.0, Step: 150 +2022-10-31 23:23:19 - r - INFO: - Episode: 456/1000, Reward: 114.0, Step: 114 +2022-10-31 23:23:19 - r - INFO: - Episode: 457/1000, Reward: 44.0, Step: 44 +2022-10-31 23:23:19 - r - INFO: - Episode: 458/1000, Reward: 138.0, Step: 138 +2022-10-31 23:23:19 - r - INFO: - Episode: 459/1000, Reward: 133.0, Step: 133 +2022-10-31 23:23:20 - r - INFO: - Episode: 460/1000, Reward: 141.0, Step: 141 +2022-10-31 23:23:20 - r - INFO: - Episode: 461/1000, Reward: 124.0, Step: 124 +2022-10-31 23:23:21 - r - INFO: - Episode: 462/1000, Reward: 143.0, Step: 143 +2022-10-31 23:23:21 - r - INFO: - Episode: 463/1000, Reward: 123.0, Step: 123 +2022-10-31 23:23:21 - r - INFO: - Episode: 464/1000, Reward: 134.0, Step: 134 +2022-10-31 23:23:22 - r - INFO: - Episode: 465/1000, Reward: 152.0, Step: 152 +2022-10-31 23:23:23 - r - INFO: - Episode: 466/1000, Reward: 140.0, Step: 140 +2022-10-31 23:23:23 - r - INFO: - Episode: 467/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:23 - r - INFO: - Episode: 468/1000, Reward: 168.0, Step: 168 +2022-10-31 23:23:24 - r - INFO: - Episode: 469/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:24 - r - INFO: - Episode: 470/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:25 - r - INFO: - Current episode 470 has the best eval reward: 199.80 +2022-10-31 23:23:25 - r - INFO: - Episode: 471/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:26 - r - INFO: - Episode: 472/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:26 - r - INFO: - Episode: 473/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:27 - r - INFO: - Episode: 474/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:27 - r - INFO: - Episode: 475/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:28 - r - INFO: - Current episode 475 has the best eval reward: 200.00 +2022-10-31 23:23:28 - r - INFO: - Episode: 476/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:29 - r - INFO: - Episode: 477/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:29 - r - INFO: - Episode: 478/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:30 - r - INFO: - Episode: 479/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:30 - r - INFO: - Episode: 480/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:31 - r - INFO: - Current episode 480 has the best eval reward: 200.00 +2022-10-31 23:23:31 - r - INFO: - Episode: 481/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:32 - r - INFO: - Episode: 482/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:32 - r - INFO: - Episode: 483/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:33 - r - INFO: - Episode: 484/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:33 - r - INFO: - Episode: 485/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:34 - r - INFO: - Current episode 485 has the best eval reward: 200.00 +2022-10-31 23:23:34 - r - INFO: - Episode: 486/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:35 - r - INFO: - Episode: 487/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:35 - r - INFO: - Episode: 488/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:36 - r - INFO: - Episode: 489/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:36 - r - INFO: - Episode: 490/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:37 - r - INFO: - Current episode 490 has the best eval reward: 200.00 +2022-10-31 23:23:37 - r - INFO: - Episode: 491/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:38 - r - INFO: - Episode: 492/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:38 - r - INFO: - Episode: 493/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:38 - r - INFO: - Episode: 494/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:39 - r - INFO: - Episode: 495/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:40 - r - INFO: - Current episode 495 has the best eval reward: 200.00 +2022-10-31 23:23:40 - r - INFO: - Episode: 496/1000, Reward: 169.0, Step: 169 +2022-10-31 23:23:40 - r - INFO: - Episode: 497/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:41 - r - INFO: - Episode: 498/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:41 - r - INFO: - Episode: 499/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:42 - r - INFO: - Episode: 500/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:42 - r - INFO: - Current episode 500 has the best eval reward: 200.00 +2022-10-31 23:23:43 - r - INFO: - Episode: 501/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:43 - r - INFO: - Episode: 502/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:44 - r - INFO: - Episode: 503/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:44 - r - INFO: - Episode: 504/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:45 - r - INFO: - Episode: 505/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:45 - r - INFO: - Current episode 505 has the best eval reward: 200.00 +2022-10-31 23:23:46 - r - INFO: - Episode: 506/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:46 - r - INFO: - Episode: 507/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:47 - r - INFO: - Episode: 508/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:47 - r - INFO: - Episode: 509/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:48 - r - INFO: - Episode: 510/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:49 - r - INFO: - Episode: 511/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:49 - r - INFO: - Episode: 512/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:50 - r - INFO: - Episode: 513/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:50 - r - INFO: - Episode: 514/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:51 - r - INFO: - Episode: 515/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:52 - r - INFO: - Episode: 516/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:52 - r - INFO: - Episode: 517/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:53 - r - INFO: - Episode: 518/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:53 - r - INFO: - Episode: 519/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:54 - r - INFO: - Episode: 520/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:55 - r - INFO: - Current episode 520 has the best eval reward: 200.00 +2022-10-31 23:23:55 - r - INFO: - Episode: 521/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:55 - r - INFO: - Episode: 522/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:56 - r - INFO: - Episode: 523/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:56 - r - INFO: - Episode: 524/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:57 - r - INFO: - Episode: 525/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:58 - r - INFO: - Current episode 525 has the best eval reward: 200.00 +2022-10-31 23:23:58 - r - INFO: - Episode: 526/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:59 - r - INFO: - Episode: 527/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:59 - r - INFO: - Episode: 528/1000, Reward: 200.0, Step: 200 +2022-10-31 23:23:59 - r - INFO: - Episode: 529/1000, Reward: 186.0, Step: 186 +2022-10-31 23:24:00 - r - INFO: - Episode: 530/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:00 - r - INFO: - Current episode 530 has the best eval reward: 200.00 +2022-10-31 23:24:01 - r - INFO: - Episode: 531/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:01 - r - INFO: - Episode: 532/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:02 - r - INFO: - Episode: 533/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:02 - r - INFO: - Episode: 534/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:03 - r - INFO: - Episode: 535/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:04 - r - INFO: - Current episode 535 has the best eval reward: 200.00 +2022-10-31 23:24:04 - r - INFO: - Episode: 536/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:04 - r - INFO: - Episode: 537/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:05 - r - INFO: - Episode: 538/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:05 - r - INFO: - Episode: 539/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:06 - r - INFO: - Episode: 540/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:07 - r - INFO: - Current episode 540 has the best eval reward: 200.00 +2022-10-31 23:24:07 - r - INFO: - Episode: 541/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:08 - r - INFO: - Episode: 542/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:08 - r - INFO: - Episode: 543/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:08 - r - INFO: - Episode: 544/1000, Reward: 84.0, Step: 84 +2022-10-31 23:24:09 - r - INFO: - Episode: 545/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:09 - r - INFO: - Current episode 545 has the best eval reward: 200.00 +2022-10-31 23:24:10 - r - INFO: - Episode: 546/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:10 - r - INFO: - Episode: 547/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:11 - r - INFO: - Episode: 548/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:11 - r - INFO: - Episode: 549/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:12 - r - INFO: - Episode: 550/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:13 - r - INFO: - Episode: 551/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:13 - r - INFO: - Episode: 552/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:14 - r - INFO: - Episode: 553/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:14 - r - INFO: - Episode: 554/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:15 - r - INFO: - Episode: 555/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:16 - r - INFO: - Episode: 556/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:16 - r - INFO: - Episode: 557/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:17 - r - INFO: - Episode: 558/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:17 - r - INFO: - Episode: 559/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:17 - r - INFO: - Episode: 560/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:18 - r - INFO: - Current episode 560 has the best eval reward: 200.00 +2022-10-31 23:24:19 - r - INFO: - Episode: 561/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:19 - r - INFO: - Episode: 562/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:20 - r - INFO: - Episode: 563/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:20 - r - INFO: - Episode: 564/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:20 - r - INFO: - Episode: 565/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:21 - r - INFO: - Current episode 565 has the best eval reward: 200.00 +2022-10-31 23:24:21 - r - INFO: - Episode: 566/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:22 - r - INFO: - Episode: 567/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:22 - r - INFO: - Episode: 568/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:23 - r - INFO: - Episode: 569/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:23 - r - INFO: - Episode: 570/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:24 - r - INFO: - Current episode 570 has the best eval reward: 200.00 +2022-10-31 23:24:24 - r - INFO: - Episode: 571/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:25 - r - INFO: - Episode: 572/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:25 - r - INFO: - Episode: 573/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:26 - r - INFO: - Episode: 574/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:26 - r - INFO: - Episode: 575/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:28 - r - INFO: - Episode: 576/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:28 - r - INFO: - Episode: 577/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:28 - r - INFO: - Episode: 578/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:29 - r - INFO: - Episode: 579/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:29 - r - INFO: - Episode: 580/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:30 - r - INFO: - Current episode 580 has the best eval reward: 200.00 +2022-10-31 23:24:31 - r - INFO: - Episode: 581/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:31 - r - INFO: - Episode: 582/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:32 - r - INFO: - Episode: 583/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:32 - r - INFO: - Episode: 584/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:33 - r - INFO: - Episode: 585/1000, Reward: 199.0, Step: 199 +2022-10-31 23:24:34 - r - INFO: - Episode: 586/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:34 - r - INFO: - Episode: 587/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:35 - r - INFO: - Episode: 588/1000, Reward: 178.0, Step: 178 +2022-10-31 23:24:35 - r - INFO: - Episode: 589/1000, Reward: 200.0, Step: 200 +2022-10-31 23:24:36 - r - INFO: - Episode: 590/1000, Reward: 188.0, Step: 188 +2022-10-31 23:24:36 - r - INFO: - Episode: 591/1000, Reward: 156.0, Step: 156 +2022-10-31 23:24:37 - r - INFO: - Episode: 592/1000, Reward: 165.0, Step: 165 +2022-10-31 23:24:37 - r - INFO: - Episode: 593/1000, Reward: 131.0, Step: 131 +2022-10-31 23:24:37 - r - INFO: - Episode: 594/1000, Reward: 157.0, Step: 157 +2022-10-31 23:24:38 - r - INFO: - Episode: 595/1000, Reward: 170.0, Step: 170 +2022-10-31 23:24:39 - r - INFO: - Episode: 596/1000, Reward: 123.0, Step: 123 +2022-10-31 23:24:39 - r - INFO: - Episode: 597/1000, Reward: 109.0, Step: 109 +2022-10-31 23:24:39 - r - INFO: - Episode: 598/1000, Reward: 124.0, Step: 124 +2022-10-31 23:24:39 - r - INFO: - Episode: 599/1000, Reward: 113.0, Step: 113 +2022-10-31 23:24:39 - r - INFO: - Episode: 600/1000, Reward: 38.0, Step: 38 +2022-10-31 23:24:40 - r - INFO: - Episode: 601/1000, Reward: 107.0, Step: 107 +2022-10-31 23:24:40 - r - INFO: - Episode: 602/1000, Reward: 115.0, Step: 115 +2022-10-31 23:24:41 - r - INFO: - Episode: 603/1000, Reward: 101.0, Step: 101 +2022-10-31 23:24:41 - r - INFO: - Episode: 604/1000, Reward: 113.0, Step: 113 +2022-10-31 23:24:41 - r - INFO: - Episode: 605/1000, Reward: 100.0, Step: 100 +2022-10-31 23:24:42 - r - INFO: - Episode: 606/1000, Reward: 109.0, Step: 109 +2022-10-31 23:24:42 - r - INFO: - Episode: 607/1000, Reward: 119.0, Step: 119 +2022-10-31 23:24:42 - r - INFO: - Episode: 608/1000, Reward: 117.0, Step: 117 +2022-10-31 23:24:43 - r - INFO: - Episode: 609/1000, Reward: 108.0, Step: 108 +2022-10-31 23:24:43 - r - INFO: - Episode: 610/1000, Reward: 101.0, Step: 101 +2022-10-31 23:24:43 - r - INFO: - Episode: 611/1000, Reward: 110.0, Step: 110 +2022-10-31 23:24:44 - r - INFO: - Episode: 612/1000, Reward: 59.0, Step: 59 +2022-10-31 23:24:44 - r - INFO: - Episode: 613/1000, Reward: 112.0, Step: 112 +2022-10-31 23:24:44 - r - INFO: - Episode: 614/1000, Reward: 104.0, Step: 104 +2022-10-31 23:24:44 - r - INFO: - Episode: 615/1000, Reward: 45.0, Step: 45 +2022-10-31 23:24:44 - r - INFO: - Episode: 616/1000, Reward: 29.0, Step: 29 +2022-10-31 23:24:44 - r - INFO: - Episode: 617/1000, Reward: 42.0, Step: 42 +2022-10-31 23:24:45 - r - INFO: - Episode: 618/1000, Reward: 74.0, Step: 74 +2022-10-31 23:24:45 - r - INFO: - Episode: 619/1000, Reward: 79.0, Step: 79 +2022-10-31 23:24:45 - r - INFO: - Episode: 620/1000, Reward: 50.0, Step: 50 +2022-10-31 23:24:45 - r - INFO: - Episode: 621/1000, Reward: 30.0, Step: 30 +2022-10-31 23:24:45 - r - INFO: - Episode: 622/1000, Reward: 43.0, Step: 43 +2022-10-31 23:24:46 - r - INFO: - Episode: 623/1000, Reward: 77.0, Step: 77 +2022-10-31 23:24:46 - r - INFO: - Episode: 624/1000, Reward: 36.0, Step: 36 +2022-10-31 23:24:46 - r - INFO: - Episode: 625/1000, Reward: 61.0, Step: 61 +2022-10-31 23:24:46 - r - INFO: - Episode: 626/1000, Reward: 36.0, Step: 36 +2022-10-31 23:24:46 - r - INFO: - Episode: 627/1000, Reward: 30.0, Step: 30 +2022-10-31 23:24:46 - r - INFO: - Episode: 628/1000, Reward: 43.0, Step: 43 +2022-10-31 23:24:46 - r - INFO: - Episode: 629/1000, Reward: 27.0, Step: 27 +2022-10-31 23:24:46 - r - INFO: - Episode: 630/1000, Reward: 88.0, Step: 88 +2022-10-31 23:24:47 - r - INFO: - Episode: 631/1000, Reward: 42.0, Step: 42 +2022-10-31 23:24:47 - r - INFO: - Episode: 632/1000, Reward: 40.0, Step: 40 +2022-10-31 23:24:47 - r - INFO: - Episode: 633/1000, Reward: 59.0, Step: 59 +2022-10-31 23:24:47 - r - INFO: - Episode: 634/1000, Reward: 81.0, Step: 81 +2022-10-31 23:24:47 - r - INFO: - Episode: 635/1000, Reward: 85.0, Step: 85 +2022-10-31 23:24:48 - r - INFO: - Episode: 636/1000, Reward: 55.0, Step: 55 +2022-10-31 23:24:48 - r - INFO: - Episode: 637/1000, Reward: 40.0, Step: 40 +2022-10-31 23:24:48 - r - INFO: - Episode: 638/1000, Reward: 99.0, Step: 99 +2022-10-31 23:24:48 - r - INFO: - Episode: 639/1000, Reward: 104.0, Step: 104 +2022-10-31 23:24:49 - r - INFO: - Episode: 640/1000, Reward: 117.0, Step: 117 +2022-10-31 23:24:49 - r - INFO: - Episode: 641/1000, Reward: 112.0, Step: 112 +2022-10-31 23:24:49 - r - INFO: - Episode: 642/1000, Reward: 43.0, Step: 43 +2022-10-31 23:24:50 - r - INFO: - Episode: 643/1000, Reward: 96.0, Step: 96 +2022-10-31 23:24:50 - r - INFO: - Episode: 644/1000, Reward: 105.0, Step: 105 +2022-10-31 23:24:50 - r - INFO: - Episode: 645/1000, Reward: 115.0, Step: 115 +2022-10-31 23:24:51 - r - INFO: - Episode: 646/1000, Reward: 99.0, Step: 99 +2022-10-31 23:24:51 - r - INFO: - Episode: 647/1000, Reward: 123.0, Step: 123 +2022-10-31 23:24:51 - r - INFO: - Episode: 648/1000, Reward: 123.0, Step: 123 +2022-10-31 23:24:51 - r - INFO: - Episode: 649/1000, Reward: 40.0, Step: 40 +2022-10-31 23:24:51 - r - INFO: - Episode: 650/1000, Reward: 100.0, Step: 100 +2022-10-31 23:24:52 - r - INFO: - Episode: 651/1000, Reward: 124.0, Step: 124 +2022-10-31 23:24:52 - r - INFO: - Episode: 652/1000, Reward: 106.0, Step: 106 +2022-10-31 23:24:53 - r - INFO: - Episode: 653/1000, Reward: 122.0, Step: 122 +2022-10-31 23:24:53 - r - INFO: - Episode: 654/1000, Reward: 127.0, Step: 127 +2022-10-31 23:24:53 - r - INFO: - Episode: 655/1000, Reward: 121.0, Step: 121 +2022-10-31 23:24:54 - r - INFO: - Episode: 656/1000, Reward: 121.0, Step: 121 +2022-10-31 23:24:54 - r - INFO: - Episode: 657/1000, Reward: 125.0, Step: 125 +2022-10-31 23:24:54 - r - INFO: - Episode: 658/1000, Reward: 127.0, Step: 127 +2022-10-31 23:24:55 - r - INFO: - Episode: 659/1000, Reward: 132.0, Step: 132 +2022-10-31 23:24:55 - r - INFO: - Episode: 660/1000, Reward: 142.0, Step: 142 +2022-10-31 23:24:56 - r - INFO: - Episode: 661/1000, Reward: 134.0, Step: 134 +2022-10-31 23:24:56 - r - INFO: - Episode: 662/1000, Reward: 147.0, Step: 147 +2022-10-31 23:24:57 - r - INFO: - Episode: 663/1000, Reward: 175.0, Step: 175 +2022-10-31 23:24:57 - r - INFO: - Episode: 664/1000, Reward: 180.0, Step: 180 +2022-10-31 23:24:57 - r - INFO: - Episode: 665/1000, Reward: 183.0, Step: 183 +2022-10-31 23:24:58 - r - INFO: - Episode: 666/1000, Reward: 167.0, Step: 167 +2022-10-31 23:24:59 - r - INFO: - Episode: 667/1000, Reward: 179.0, Step: 179 +2022-10-31 23:24:59 - r - INFO: - Episode: 668/1000, Reward: 173.0, Step: 173 +2022-10-31 23:25:00 - r - INFO: - Episode: 669/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:00 - r - INFO: - Episode: 670/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:01 - r - INFO: - Episode: 671/1000, Reward: 184.0, Step: 184 +2022-10-31 23:25:02 - r - INFO: - Episode: 672/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:02 - r - INFO: - Episode: 673/1000, Reward: 193.0, Step: 193 +2022-10-31 23:25:03 - r - INFO: - Episode: 674/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:03 - r - INFO: - Episode: 675/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:04 - r - INFO: - Current episode 675 has the best eval reward: 200.00 +2022-10-31 23:25:04 - r - INFO: - Episode: 676/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:05 - r - INFO: - Episode: 677/1000, Reward: 199.0, Step: 199 +2022-10-31 23:25:05 - r - INFO: - Episode: 678/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:06 - r - INFO: - Episode: 679/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:06 - r - INFO: - Episode: 680/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:07 - r - INFO: - Current episode 680 has the best eval reward: 200.00 +2022-10-31 23:25:08 - r - INFO: - Episode: 681/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:08 - r - INFO: - Episode: 682/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:09 - r - INFO: - Episode: 683/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:09 - r - INFO: - Episode: 684/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:10 - r - INFO: - Episode: 685/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:10 - r - INFO: - Current episode 685 has the best eval reward: 200.00 +2022-10-31 23:25:11 - r - INFO: - Episode: 686/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:11 - r - INFO: - Episode: 687/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:12 - r - INFO: - Episode: 688/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:12 - r - INFO: - Episode: 689/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:13 - r - INFO: - Episode: 690/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:14 - r - INFO: - Episode: 691/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:14 - r - INFO: - Episode: 692/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:15 - r - INFO: - Episode: 693/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:15 - r - INFO: - Episode: 694/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:15 - r - INFO: - Episode: 695/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:17 - r - INFO: - Episode: 696/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:17 - r - INFO: - Episode: 697/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:17 - r - INFO: - Episode: 698/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:18 - r - INFO: - Episode: 699/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:18 - r - INFO: - Episode: 700/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:19 - r - INFO: - Episode: 701/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:20 - r - INFO: - Episode: 702/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:20 - r - INFO: - Episode: 703/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:21 - r - INFO: - Episode: 704/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:21 - r - INFO: - Episode: 705/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:22 - r - INFO: - Current episode 705 has the best eval reward: 200.00 +2022-10-31 23:25:22 - r - INFO: - Episode: 706/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:23 - r - INFO: - Episode: 707/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:23 - r - INFO: - Episode: 708/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:24 - r - INFO: - Episode: 709/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:24 - r - INFO: - Episode: 710/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:25 - r - INFO: - Current episode 710 has the best eval reward: 200.00 +2022-10-31 23:25:26 - r - INFO: - Episode: 711/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:26 - r - INFO: - Episode: 712/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:26 - r - INFO: - Episode: 713/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:27 - r - INFO: - Episode: 714/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:27 - r - INFO: - Episode: 715/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:28 - r - INFO: - Current episode 715 has the best eval reward: 200.00 +2022-10-31 23:25:28 - r - INFO: - Episode: 716/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:29 - r - INFO: - Episode: 717/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:29 - r - INFO: - Episode: 718/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:30 - r - INFO: - Episode: 719/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:30 - r - INFO: - Episode: 720/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:31 - r - INFO: - Current episode 720 has the best eval reward: 200.00 +2022-10-31 23:25:31 - r - INFO: - Episode: 721/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:32 - r - INFO: - Episode: 722/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:32 - r - INFO: - Episode: 723/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:33 - r - INFO: - Episode: 724/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:33 - r - INFO: - Episode: 725/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:34 - r - INFO: - Current episode 725 has the best eval reward: 200.00 +2022-10-31 23:25:34 - r - INFO: - Episode: 726/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:35 - r - INFO: - Episode: 727/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:35 - r - INFO: - Episode: 728/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:35 - r - INFO: - Episode: 729/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:36 - r - INFO: - Episode: 730/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:37 - r - INFO: - Current episode 730 has the best eval reward: 200.00 +2022-10-31 23:25:37 - r - INFO: - Episode: 731/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:37 - r - INFO: - Episode: 732/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:38 - r - INFO: - Episode: 733/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:38 - r - INFO: - Episode: 734/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:39 - r - INFO: - Episode: 735/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:39 - r - INFO: - Current episode 735 has the best eval reward: 200.00 +2022-10-31 23:25:40 - r - INFO: - Episode: 736/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:40 - r - INFO: - Episode: 737/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:41 - r - INFO: - Episode: 738/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:41 - r - INFO: - Episode: 739/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:42 - r - INFO: - Episode: 740/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:42 - r - INFO: - Current episode 740 has the best eval reward: 200.00 +2022-10-31 23:25:43 - r - INFO: - Episode: 741/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:43 - r - INFO: - Episode: 742/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:44 - r - INFO: - Episode: 743/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:44 - r - INFO: - Episode: 744/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:44 - r - INFO: - Episode: 745/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:45 - r - INFO: - Current episode 745 has the best eval reward: 200.00 +2022-10-31 23:25:46 - r - INFO: - Episode: 746/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:46 - r - INFO: - Episode: 747/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:46 - r - INFO: - Episode: 748/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:47 - r - INFO: - Episode: 749/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:47 - r - INFO: - Episode: 750/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:48 - r - INFO: - Current episode 750 has the best eval reward: 200.00 +2022-10-31 23:25:48 - r - INFO: - Episode: 751/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:49 - r - INFO: - Episode: 752/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:49 - r - INFO: - Episode: 753/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:50 - r - INFO: - Episode: 754/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:50 - r - INFO: - Episode: 755/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:51 - r - INFO: - Current episode 755 has the best eval reward: 200.00 +2022-10-31 23:25:51 - r - INFO: - Episode: 756/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:52 - r - INFO: - Episode: 757/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:52 - r - INFO: - Episode: 758/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:53 - r - INFO: - Episode: 759/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:53 - r - INFO: - Episode: 760/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:54 - r - INFO: - Current episode 760 has the best eval reward: 200.00 +2022-10-31 23:25:54 - r - INFO: - Episode: 761/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:55 - r - INFO: - Episode: 762/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:55 - r - INFO: - Episode: 763/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:55 - r - INFO: - Episode: 764/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:56 - r - INFO: - Episode: 765/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:57 - r - INFO: - Current episode 765 has the best eval reward: 200.00 +2022-10-31 23:25:57 - r - INFO: - Episode: 766/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:57 - r - INFO: - Episode: 767/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:58 - r - INFO: - Episode: 768/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:58 - r - INFO: - Episode: 769/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:59 - r - INFO: - Episode: 770/1000, Reward: 200.0, Step: 200 +2022-10-31 23:25:59 - r - INFO: - Current episode 770 has the best eval reward: 200.00 +2022-10-31 23:26:00 - r - INFO: - Episode: 771/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:00 - r - INFO: - Episode: 772/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:01 - r - INFO: - Episode: 773/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:01 - r - INFO: - Episode: 774/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:02 - r - INFO: - Episode: 775/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:02 - r - INFO: - Current episode 775 has the best eval reward: 200.00 +2022-10-31 23:26:03 - r - INFO: - Episode: 776/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:03 - r - INFO: - Episode: 777/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:04 - r - INFO: - Episode: 778/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:04 - r - INFO: - Episode: 779/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:04 - r - INFO: - Episode: 780/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:06 - r - INFO: - Episode: 781/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:06 - r - INFO: - Episode: 782/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:06 - r - INFO: - Episode: 783/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:07 - r - INFO: - Episode: 784/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:07 - r - INFO: - Episode: 785/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:08 - r - INFO: - Episode: 786/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:09 - r - INFO: - Episode: 787/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:09 - r - INFO: - Episode: 788/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:10 - r - INFO: - Episode: 789/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:10 - r - INFO: - Episode: 790/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:11 - r - INFO: - Current episode 790 has the best eval reward: 200.00 +2022-10-31 23:26:11 - r - INFO: - Episode: 791/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:12 - r - INFO: - Episode: 792/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:12 - r - INFO: - Episode: 793/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:12 - r - INFO: - Episode: 794/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:13 - r - INFO: - Episode: 795/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:14 - r - INFO: - Current episode 795 has the best eval reward: 200.00 +2022-10-31 23:26:14 - r - INFO: - Episode: 796/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:14 - r - INFO: - Episode: 797/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:15 - r - INFO: - Episode: 798/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:15 - r - INFO: - Episode: 799/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:16 - r - INFO: - Episode: 800/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:16 - r - INFO: - Current episode 800 has the best eval reward: 200.00 +2022-10-31 23:26:17 - r - INFO: - Episode: 801/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:17 - r - INFO: - Episode: 802/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:18 - r - INFO: - Episode: 803/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:18 - r - INFO: - Episode: 804/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:19 - r - INFO: - Episode: 805/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:19 - r - INFO: - Current episode 805 has the best eval reward: 200.00 +2022-10-31 23:26:20 - r - INFO: - Episode: 806/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:20 - r - INFO: - Episode: 807/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:21 - r - INFO: - Episode: 808/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:21 - r - INFO: - Episode: 809/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:21 - r - INFO: - Episode: 810/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:22 - r - INFO: - Current episode 810 has the best eval reward: 200.00 +2022-10-31 23:26:23 - r - INFO: - Episode: 811/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:23 - r - INFO: - Episode: 812/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:23 - r - INFO: - Episode: 813/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:24 - r - INFO: - Episode: 814/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:24 - r - INFO: - Episode: 815/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:25 - r - INFO: - Current episode 815 has the best eval reward: 200.00 +2022-10-31 23:26:25 - r - INFO: - Episode: 816/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:26 - r - INFO: - Episode: 817/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:26 - r - INFO: - Episode: 818/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:27 - r - INFO: - Episode: 819/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:27 - r - INFO: - Episode: 820/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:28 - r - INFO: - Current episode 820 has the best eval reward: 200.00 +2022-10-31 23:26:28 - r - INFO: - Episode: 821/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:29 - r - INFO: - Episode: 822/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:29 - r - INFO: - Episode: 823/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:30 - r - INFO: - Episode: 824/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:30 - r - INFO: - Episode: 825/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:31 - r - INFO: - Current episode 825 has the best eval reward: 200.00 +2022-10-31 23:26:31 - r - INFO: - Episode: 826/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:32 - r - INFO: - Episode: 827/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:32 - r - INFO: - Episode: 828/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:32 - r - INFO: - Episode: 829/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:33 - r - INFO: - Episode: 830/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:34 - r - INFO: - Current episode 830 has the best eval reward: 200.00 +2022-10-31 23:26:34 - r - INFO: - Episode: 831/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:34 - r - INFO: - Episode: 832/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:35 - r - INFO: - Episode: 833/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:35 - r - INFO: - Episode: 834/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:36 - r - INFO: - Episode: 835/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:36 - r - INFO: - Current episode 835 has the best eval reward: 200.00 +2022-10-31 23:26:37 - r - INFO: - Episode: 836/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:37 - r - INFO: - Episode: 837/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:38 - r - INFO: - Episode: 838/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:38 - r - INFO: - Episode: 839/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:38 - r - INFO: - Episode: 840/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:39 - r - INFO: - Current episode 840 has the best eval reward: 200.00 +2022-10-31 23:26:40 - r - INFO: - Episode: 841/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:40 - r - INFO: - Episode: 842/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:40 - r - INFO: - Episode: 843/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:41 - r - INFO: - Episode: 844/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:41 - r - INFO: - Episode: 845/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:42 - r - INFO: - Current episode 845 has the best eval reward: 200.00 +2022-10-31 23:26:42 - r - INFO: - Episode: 846/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:43 - r - INFO: - Episode: 847/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:43 - r - INFO: - Episode: 848/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:44 - r - INFO: - Episode: 849/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:44 - r - INFO: - Episode: 850/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:45 - r - INFO: - Current episode 850 has the best eval reward: 200.00 +2022-10-31 23:26:45 - r - INFO: - Episode: 851/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:46 - r - INFO: - Episode: 852/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:46 - r - INFO: - Episode: 853/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:47 - r - INFO: - Episode: 854/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:47 - r - INFO: - Episode: 855/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:48 - r - INFO: - Current episode 855 has the best eval reward: 200.00 +2022-10-31 23:26:48 - r - INFO: - Episode: 856/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:49 - r - INFO: - Episode: 857/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:49 - r - INFO: - Episode: 858/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:49 - r - INFO: - Episode: 859/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:50 - r - INFO: - Episode: 860/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:51 - r - INFO: - Current episode 860 has the best eval reward: 200.00 +2022-10-31 23:26:51 - r - INFO: - Episode: 861/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:51 - r - INFO: - Episode: 862/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:52 - r - INFO: - Episode: 863/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:52 - r - INFO: - Episode: 864/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:53 - r - INFO: - Episode: 865/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:53 - r - INFO: - Current episode 865 has the best eval reward: 200.00 +2022-10-31 23:26:54 - r - INFO: - Episode: 866/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:54 - r - INFO: - Episode: 867/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:55 - r - INFO: - Episode: 868/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:55 - r - INFO: - Episode: 869/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:56 - r - INFO: - Episode: 870/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:56 - r - INFO: - Current episode 870 has the best eval reward: 200.00 +2022-10-31 23:26:57 - r - INFO: - Episode: 871/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:57 - r - INFO: - Episode: 872/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:58 - r - INFO: - Episode: 873/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:58 - r - INFO: - Episode: 874/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:59 - r - INFO: - Episode: 875/1000, Reward: 200.0, Step: 200 +2022-10-31 23:26:59 - r - INFO: - Current episode 875 has the best eval reward: 200.00 +2022-10-31 23:27:00 - r - INFO: - Episode: 876/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:00 - r - INFO: - Episode: 877/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:01 - r - INFO: - Episode: 878/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:01 - r - INFO: - Episode: 879/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:01 - r - INFO: - Episode: 880/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:02 - r - INFO: - Current episode 880 has the best eval reward: 200.00 +2022-10-31 23:27:03 - r - INFO: - Episode: 881/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:03 - r - INFO: - Episode: 882/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:03 - r - INFO: - Episode: 883/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:04 - r - INFO: - Episode: 884/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:04 - r - INFO: - Episode: 885/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:05 - r - INFO: - Current episode 885 has the best eval reward: 200.00 +2022-10-31 23:27:05 - r - INFO: - Episode: 886/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:06 - r - INFO: - Episode: 887/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:06 - r - INFO: - Episode: 888/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:07 - r - INFO: - Episode: 889/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:07 - r - INFO: - Episode: 890/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:08 - r - INFO: - Current episode 890 has the best eval reward: 200.00 +2022-10-31 23:27:08 - r - INFO: - Episode: 891/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:09 - r - INFO: - Episode: 892/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:09 - r - INFO: - Episode: 893/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:10 - r - INFO: - Episode: 894/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:10 - r - INFO: - Episode: 895/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:11 - r - INFO: - Current episode 895 has the best eval reward: 200.00 +2022-10-31 23:27:11 - r - INFO: - Episode: 896/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:12 - r - INFO: - Episode: 897/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:12 - r - INFO: - Episode: 898/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:12 - r - INFO: - Episode: 899/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:13 - r - INFO: - Episode: 900/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:14 - r - INFO: - Current episode 900 has the best eval reward: 200.00 +2022-10-31 23:27:14 - r - INFO: - Episode: 901/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:15 - r - INFO: - Episode: 902/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:15 - r - INFO: - Episode: 903/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:16 - r - INFO: - Episode: 904/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:16 - r - INFO: - Episode: 905/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:17 - r - INFO: - Current episode 905 has the best eval reward: 200.00 +2022-10-31 23:27:17 - r - INFO: - Episode: 906/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:18 - r - INFO: - Episode: 907/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:18 - r - INFO: - Episode: 908/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:19 - r - INFO: - Episode: 909/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:19 - r - INFO: - Episode: 910/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:20 - r - INFO: - Current episode 910 has the best eval reward: 200.00 +2022-10-31 23:27:20 - r - INFO: - Episode: 911/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:21 - r - INFO: - Episode: 912/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:21 - r - INFO: - Episode: 913/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:21 - r - INFO: - Episode: 914/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:22 - r - INFO: - Episode: 915/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:23 - r - INFO: - Current episode 915 has the best eval reward: 200.00 +2022-10-31 23:27:23 - r - INFO: - Episode: 916/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:23 - r - INFO: - Episode: 917/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:24 - r - INFO: - Episode: 918/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:24 - r - INFO: - Episode: 919/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:25 - r - INFO: - Episode: 920/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:25 - r - INFO: - Current episode 920 has the best eval reward: 200.00 +2022-10-31 23:27:26 - r - INFO: - Episode: 921/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:26 - r - INFO: - Episode: 922/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:27 - r - INFO: - Episode: 923/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:27 - r - INFO: - Episode: 924/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:28 - r - INFO: - Episode: 925/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:29 - r - INFO: - Episode: 926/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:29 - r - INFO: - Episode: 927/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:30 - r - INFO: - Episode: 928/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:30 - r - INFO: - Episode: 929/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:30 - r - INFO: - Episode: 930/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:31 - r - INFO: - Episode: 931/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:32 - r - INFO: - Episode: 932/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:32 - r - INFO: - Episode: 933/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:33 - r - INFO: - Episode: 934/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:33 - r - INFO: - Episode: 935/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:34 - r - INFO: - Episode: 936/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:35 - r - INFO: - Episode: 937/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:35 - r - INFO: - Episode: 938/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:36 - r - INFO: - Episode: 939/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:36 - r - INFO: - Episode: 940/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:37 - r - INFO: - Episode: 941/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:38 - r - INFO: - Episode: 942/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:38 - r - INFO: - Episode: 943/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:38 - r - INFO: - Episode: 944/1000, Reward: 153.0, Step: 153 +2022-10-31 23:27:39 - r - INFO: - Episode: 945/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:40 - r - INFO: - Episode: 946/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:40 - r - INFO: - Episode: 947/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:41 - r - INFO: - Episode: 948/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:41 - r - INFO: - Episode: 949/1000, Reward: 150.0, Step: 150 +2022-10-31 23:27:41 - r - INFO: - Episode: 950/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:43 - r - INFO: - Episode: 951/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:43 - r - INFO: - Episode: 952/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:43 - r - INFO: - Episode: 953/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:44 - r - INFO: - Episode: 954/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:44 - r - INFO: - Episode: 955/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:45 - r - INFO: - Episode: 956/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:46 - r - INFO: - Episode: 957/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:46 - r - INFO: - Episode: 958/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:47 - r - INFO: - Episode: 959/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:47 - r - INFO: - Episode: 960/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:48 - r - INFO: - Current episode 960 has the best eval reward: 200.00 +2022-10-31 23:27:48 - r - INFO: - Episode: 961/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:49 - r - INFO: - Episode: 962/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:49 - r - INFO: - Episode: 963/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:49 - r - INFO: - Episode: 964/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:50 - r - INFO: - Episode: 965/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:51 - r - INFO: - Current episode 965 has the best eval reward: 200.00 +2022-10-31 23:27:51 - r - INFO: - Episode: 966/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:51 - r - INFO: - Episode: 967/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:52 - r - INFO: - Episode: 968/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:52 - r - INFO: - Episode: 969/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:53 - r - INFO: - Episode: 970/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:53 - r - INFO: - Current episode 970 has the best eval reward: 200.00 +2022-10-31 23:27:54 - r - INFO: - Episode: 971/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:54 - r - INFO: - Episode: 972/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:55 - r - INFO: - Episode: 973/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:55 - r - INFO: - Episode: 974/1000, Reward: 161.0, Step: 161 +2022-10-31 23:27:55 - r - INFO: - Episode: 975/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:57 - r - INFO: - Episode: 976/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:57 - r - INFO: - Episode: 977/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:57 - r - INFO: - Episode: 978/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:58 - r - INFO: - Episode: 979/1000, Reward: 200.0, Step: 200 +2022-10-31 23:27:58 - r - INFO: - Episode: 980/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:00 - r - INFO: - Episode: 981/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:00 - r - INFO: - Episode: 982/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:01 - r - INFO: - Episode: 983/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:01 - r - INFO: - Episode: 984/1000, Reward: 111.0, Step: 111 +2022-10-31 23:28:01 - r - INFO: - Episode: 985/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:03 - r - INFO: - Episode: 986/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:03 - r - INFO: - Episode: 987/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:04 - r - INFO: - Episode: 988/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:04 - r - INFO: - Episode: 989/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:04 - r - INFO: - Episode: 990/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:05 - r - INFO: - Current episode 990 has the best eval reward: 200.00 +2022-10-31 23:28:06 - r - INFO: - Episode: 991/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:06 - r - INFO: - Episode: 992/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:07 - r - INFO: - Episode: 993/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:07 - r - INFO: - Episode: 994/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:07 - r - INFO: - Episode: 995/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:09 - r - INFO: - Episode: 996/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:09 - r - INFO: - Episode: 997/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:09 - r - INFO: - Episode: 998/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:10 - r - INFO: - Episode: 999/1000, Reward: 154.0, Step: 154 +2022-10-31 23:28:10 - r - INFO: - Episode: 1000/1000, Reward: 200.0, Step: 200 +2022-10-31 23:28:11 - r - INFO: - Finish training! diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/models/actor_checkpoint.pt b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/models/actor_checkpoint.pt new file mode 100644 index 0000000..05bd7b6 Binary files /dev/null and b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/models/actor_checkpoint.pt differ diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/models/critic_checkpoint.pt b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/models/critic_checkpoint.pt new file mode 100644 index 0000000..720f388 Binary files /dev/null and b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/models/critic_checkpoint.pt differ diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/results/learning_curve.png b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/results/learning_curve.png new file mode 100644 index 0000000..841a786 Binary files /dev/null and b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/results/learning_curve.png differ diff --git a/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/results/res.csv b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/results/res.csv new file mode 100644 index 0000000..ee82c68 --- /dev/null +++ b/projects/codes/A2C/Train_CartPole-v1_A2C_20221031-232138/results/res.csv @@ -0,0 +1,1001 @@ +episodes,rewards,steps +0,25.0,25 +1,11.0,11 +2,32.0,32 +3,11.0,11 +4,14.0,14 +5,11.0,11 +6,23.0,23 +7,27.0,27 +8,10.0,10 +9,21.0,21 +10,15.0,15 +11,26.0,26 +12,22.0,22 +13,14.0,14 +14,14.0,14 +15,21.0,21 +16,10.0,10 +17,19.0,19 +18,18.0,18 +19,26.0,26 +20,29.0,29 +21,40.0,40 +22,35.0,35 +23,33.0,33 +24,47.0,47 +25,50.0,50 +26,21.0,21 +27,30.0,30 +28,26.0,26 +29,40.0,40 +30,31.0,31 +31,54.0,54 +32,59.0,59 +33,50.0,50 +34,26.0,26 +35,34.0,34 +36,25.0,25 +37,166.0,166 +38,35.0,35 +39,25.0,25 +40,110.0,110 +41,22.0,22 +42,57.0,57 +43,45.0,45 +44,35.0,35 +45,45.0,45 +46,51.0,51 +47,32.0,32 +48,67.0,67 +49,46.0,46 +50,61.0,61 +51,49.0,49 +52,47.0,47 +53,37.0,37 +54,32.0,32 +55,31.0,31 +56,33.0,33 +57,93.0,93 +58,60.0,60 +59,128.0,128 +60,200.0,200 +61,47.0,47 +62,47.0,47 +63,63.0,63 +64,68.0,68 +65,45.0,45 +66,101.0,101 +67,47.0,47 +68,49.0,49 +69,54.0,54 +70,42.0,42 +71,77.0,77 +72,67.0,67 +73,41.0,41 +74,89.0,89 +75,51.0,51 +76,54.0,54 +77,37.0,37 +78,49.0,49 +79,46.0,46 +80,31.0,31 +81,43.0,43 +82,60.0,60 +83,41.0,41 +84,40.0,40 +85,28.0,28 +86,50.0,50 +87,159.0,159 +88,30.0,30 +89,34.0,34 +90,70.0,70 +91,22.0,22 +92,39.0,39 +93,50.0,50 +94,40.0,40 +95,37.0,37 +96,121.0,121 +97,26.0,26 +98,40.0,40 +99,30.0,30 +100,35.0,35 +101,40.0,40 +102,28.0,28 +103,29.0,29 +104,42.0,42 +105,54.0,54 +106,25.0,25 +107,47.0,47 +108,32.0,32 +109,50.0,50 +110,30.0,30 +111,58.0,58 +112,32.0,32 +113,43.0,43 +114,57.0,57 +115,20.0,20 +116,48.0,48 +117,45.0,45 +118,47.0,47 +119,69.0,69 +120,34.0,34 +121,22.0,22 +122,22.0,22 +123,38.0,38 +124,36.0,36 +125,41.0,41 +126,28.0,28 +127,35.0,35 +128,48.0,48 +129,51.0,51 +130,51.0,51 +131,36.0,36 +132,45.0,45 +133,27.0,27 +134,40.0,40 +135,43.0,43 +136,64.0,64 +137,43.0,43 +138,37.0,37 +139,38.0,38 +140,69.0,69 +141,36.0,36 +142,28.0,28 +143,58.0,58 +144,43.0,43 +145,50.0,50 +146,30.0,30 +147,42.0,42 +148,42.0,42 +149,35.0,35 +150,67.0,67 +151,45.0,45 +152,28.0,28 +153,59.0,59 +154,64.0,64 +155,67.0,67 +156,41.0,41 +157,81.0,81 +158,76.0,76 +159,91.0,91 +160,119.0,119 +161,47.0,47 +162,64.0,64 +163,178.0,178 +164,97.0,97 +165,181.0,181 +166,166.0,166 +167,79.0,79 +168,141.0,141 +169,119.0,119 +170,81.0,81 +171,124.0,124 +172,150.0,150 +173,98.0,98 +174,164.0,164 +175,200.0,200 +176,115.0,115 +177,116.0,116 +178,160.0,160 +179,103.0,103 +180,181.0,181 +181,185.0,185 +182,93.0,93 +183,110.0,110 +184,200.0,200 +185,141.0,141 +186,150.0,150 +187,121.0,121 +188,110.0,110 +189,115.0,115 +190,114.0,114 +191,45.0,45 +192,125.0,125 +193,142.0,142 +194,54.0,54 +195,62.0,62 +196,122.0,122 +197,58.0,58 +198,88.0,88 +199,141.0,141 +200,113.0,113 +201,200.0,200 +202,136.0,136 +203,114.0,114 +204,102.0,102 +205,176.0,176 +206,150.0,150 +207,105.0,105 +208,200.0,200 +209,200.0,200 +210,167.0,167 +211,104.0,104 +212,124.0,124 +213,96.0,96 +214,200.0,200 +215,199.0,199 +216,200.0,200 +217,132.0,132 +218,188.0,188 +219,132.0,132 +220,151.0,151 +221,125.0,125 +222,42.0,42 +223,200.0,200 +224,159.0,159 +225,171.0,171 +226,122.0,122 +227,189.0,189 +228,129.0,129 +229,106.0,106 +230,107.0,107 +231,200.0,200 +232,200.0,200 +233,200.0,200 +234,200.0,200 +235,158.0,158 +236,200.0,200 +237,192.0,192 +238,179.0,179 +239,102.0,102 +240,125.0,125 +241,138.0,138 +242,189.0,189 +243,41.0,41 +244,97.0,97 +245,49.0,49 +246,86.0,86 +247,121.0,121 +248,117.0,117 +249,43.0,43 +250,72.0,72 +251,34.0,34 +252,83.0,83 +253,83.0,83 +254,38.0,38 +255,34.0,34 +256,99.0,99 +257,45.0,45 +258,47.0,47 +259,44.0,44 +260,26.0,26 +261,37.0,37 +262,26.0,26 +263,43.0,43 +264,27.0,27 +265,24.0,24 +266,42.0,42 +267,86.0,86 +268,23.0,23 +269,32.0,32 +270,57.0,57 +271,25.0,25 +272,98.0,98 +273,29.0,29 +274,25.0,25 +275,29.0,29 +276,39.0,39 +277,20.0,20 +278,92.0,92 +279,28.0,28 +280,78.0,78 +281,25.0,25 +282,31.0,31 +283,88.0,88 +284,85.0,85 +285,37.0,37 +286,26.0,26 +287,19.0,19 +288,40.0,40 +289,27.0,27 +290,17.0,17 +291,27.0,27 +292,26.0,26 +293,82.0,82 +294,36.0,36 +295,24.0,24 +296,30.0,30 +297,20.0,20 +298,34.0,34 +299,30.0,30 +300,23.0,23 +301,36.0,36 +302,29.0,29 +303,34.0,34 +304,25.0,25 +305,42.0,42 +306,88.0,88 +307,26.0,26 +308,85.0,85 +309,89.0,89 +310,48.0,48 +311,83.0,83 +312,109.0,109 +313,42.0,42 +314,93.0,93 +315,85.0,85 +316,100.0,100 +317,106.0,106 +318,28.0,28 +319,108.0,108 +320,112.0,112 +321,88.0,88 +322,108.0,108 +323,108.0,108 +324,90.0,90 +325,112.0,112 +326,113.0,113 +327,94.0,94 +328,99.0,99 +329,45.0,45 +330,121.0,121 +331,102.0,102 +332,111.0,111 +333,54.0,54 +334,198.0,198 +335,83.0,83 +336,107.0,107 +337,101.0,101 +338,129.0,129 +339,88.0,88 +340,86.0,86 +341,199.0,199 +342,95.0,95 +343,103.0,103 +344,100.0,100 +345,89.0,89 +346,87.0,87 +347,110.0,110 +348,127.0,127 +349,97.0,97 +350,34.0,34 +351,123.0,123 +352,49.0,49 +353,96.0,96 +354,90.0,90 +355,110.0,110 +356,93.0,93 +357,102.0,102 +358,128.0,128 +359,125.0,125 +360,92.0,92 +361,109.0,109 +362,114.0,114 +363,111.0,111 +364,38.0,38 +365,55.0,55 +366,106.0,106 +367,115.0,115 +368,103.0,103 +369,50.0,50 +370,110.0,110 +371,102.0,102 +372,110.0,110 +373,29.0,29 +374,35.0,35 +375,42.0,42 +376,62.0,62 +377,119.0,119 +378,33.0,33 +379,31.0,31 +380,97.0,97 +381,192.0,192 +382,179.0,179 +383,89.0,89 +384,32.0,32 +385,33.0,33 +386,52.0,52 +387,31.0,31 +388,22.0,22 +389,118.0,118 +390,24.0,24 +391,115.0,115 +392,20.0,20 +393,33.0,33 +394,40.0,40 +395,27.0,27 +396,26.0,26 +397,24.0,24 +398,19.0,19 +399,22.0,22 +400,24.0,24 +401,18.0,18 +402,23.0,23 +403,27.0,27 +404,20.0,20 +405,27.0,27 +406,17.0,17 +407,27.0,27 +408,25.0,25 +409,25.0,25 +410,24.0,24 +411,24.0,24 +412,18.0,18 +413,20.0,20 +414,27.0,27 +415,28.0,28 +416,30.0,30 +417,28.0,28 +418,33.0,33 +419,24.0,24 +420,96.0,96 +421,26.0,26 +422,29.0,29 +423,25.0,25 +424,38.0,38 +425,33.0,33 +426,23.0,23 +427,39.0,39 +428,28.0,28 +429,97.0,97 +430,30.0,30 +431,29.0,29 +432,103.0,103 +433,36.0,36 +434,32.0,32 +435,41.0,41 +436,111.0,111 +437,48.0,48 +438,24.0,24 +439,49.0,49 +440,116.0,116 +441,118.0,118 +442,94.0,94 +443,132.0,132 +444,41.0,41 +445,105.0,105 +446,116.0,116 +447,136.0,136 +448,137.0,137 +449,45.0,45 +450,157.0,157 +451,116.0,116 +452,125.0,125 +453,120.0,120 +454,150.0,150 +455,114.0,114 +456,44.0,44 +457,138.0,138 +458,133.0,133 +459,141.0,141 +460,124.0,124 +461,143.0,143 +462,123.0,123 +463,134.0,134 +464,152.0,152 +465,140.0,140 +466,200.0,200 +467,168.0,168 +468,200.0,200 +469,200.0,200 +470,200.0,200 +471,200.0,200 +472,200.0,200 +473,200.0,200 +474,200.0,200 +475,200.0,200 +476,200.0,200 +477,200.0,200 +478,200.0,200 +479,200.0,200 +480,200.0,200 +481,200.0,200 +482,200.0,200 +483,200.0,200 +484,200.0,200 +485,200.0,200 +486,200.0,200 +487,200.0,200 +488,200.0,200 +489,200.0,200 +490,200.0,200 +491,200.0,200 +492,200.0,200 +493,200.0,200 +494,200.0,200 +495,169.0,169 +496,200.0,200 +497,200.0,200 +498,200.0,200 +499,200.0,200 +500,200.0,200 +501,200.0,200 +502,200.0,200 +503,200.0,200 +504,200.0,200 +505,200.0,200 +506,200.0,200 +507,200.0,200 +508,200.0,200 +509,200.0,200 +510,200.0,200 +511,200.0,200 +512,200.0,200 +513,200.0,200 +514,200.0,200 +515,200.0,200 +516,200.0,200 +517,200.0,200 +518,200.0,200 +519,200.0,200 +520,200.0,200 +521,200.0,200 +522,200.0,200 +523,200.0,200 +524,200.0,200 +525,200.0,200 +526,200.0,200 +527,200.0,200 +528,186.0,186 +529,200.0,200 +530,200.0,200 +531,200.0,200 +532,200.0,200 +533,200.0,200 +534,200.0,200 +535,200.0,200 +536,200.0,200 +537,200.0,200 +538,200.0,200 +539,200.0,200 +540,200.0,200 +541,200.0,200 +542,200.0,200 +543,84.0,84 +544,200.0,200 +545,200.0,200 +546,200.0,200 +547,200.0,200 +548,200.0,200 +549,200.0,200 +550,200.0,200 +551,200.0,200 +552,200.0,200 +553,200.0,200 +554,200.0,200 +555,200.0,200 +556,200.0,200 +557,200.0,200 +558,200.0,200 +559,200.0,200 +560,200.0,200 +561,200.0,200 +562,200.0,200 +563,200.0,200 +564,200.0,200 +565,200.0,200 +566,200.0,200 +567,200.0,200 +568,200.0,200 +569,200.0,200 +570,200.0,200 +571,200.0,200 +572,200.0,200 +573,200.0,200 +574,200.0,200 +575,200.0,200 +576,200.0,200 +577,200.0,200 +578,200.0,200 +579,200.0,200 +580,200.0,200 +581,200.0,200 +582,200.0,200 +583,200.0,200 +584,199.0,199 +585,200.0,200 +586,200.0,200 +587,178.0,178 +588,200.0,200 +589,188.0,188 +590,156.0,156 +591,165.0,165 +592,131.0,131 +593,157.0,157 +594,170.0,170 +595,123.0,123 +596,109.0,109 +597,124.0,124 +598,113.0,113 +599,38.0,38 +600,107.0,107 +601,115.0,115 +602,101.0,101 +603,113.0,113 +604,100.0,100 +605,109.0,109 +606,119.0,119 +607,117.0,117 +608,108.0,108 +609,101.0,101 +610,110.0,110 +611,59.0,59 +612,112.0,112 +613,104.0,104 +614,45.0,45 +615,29.0,29 +616,42.0,42 +617,74.0,74 +618,79.0,79 +619,50.0,50 +620,30.0,30 +621,43.0,43 +622,77.0,77 +623,36.0,36 +624,61.0,61 +625,36.0,36 +626,30.0,30 +627,43.0,43 +628,27.0,27 +629,88.0,88 +630,42.0,42 +631,40.0,40 +632,59.0,59 +633,81.0,81 +634,85.0,85 +635,55.0,55 +636,40.0,40 +637,99.0,99 +638,104.0,104 +639,117.0,117 +640,112.0,112 +641,43.0,43 +642,96.0,96 +643,105.0,105 +644,115.0,115 +645,99.0,99 +646,123.0,123 +647,123.0,123 +648,40.0,40 +649,100.0,100 +650,124.0,124 +651,106.0,106 +652,122.0,122 +653,127.0,127 +654,121.0,121 +655,121.0,121 +656,125.0,125 +657,127.0,127 +658,132.0,132 +659,142.0,142 +660,134.0,134 +661,147.0,147 +662,175.0,175 +663,180.0,180 +664,183.0,183 +665,167.0,167 +666,179.0,179 +667,173.0,173 +668,200.0,200 +669,200.0,200 +670,184.0,184 +671,200.0,200 +672,193.0,193 +673,200.0,200 +674,200.0,200 +675,200.0,200 +676,199.0,199 +677,200.0,200 +678,200.0,200 +679,200.0,200 +680,200.0,200 +681,200.0,200 +682,200.0,200 +683,200.0,200 +684,200.0,200 +685,200.0,200 +686,200.0,200 +687,200.0,200 +688,200.0,200 +689,200.0,200 +690,200.0,200 +691,200.0,200 +692,200.0,200 +693,200.0,200 +694,200.0,200 +695,200.0,200 +696,200.0,200 +697,200.0,200 +698,200.0,200 +699,200.0,200 +700,200.0,200 +701,200.0,200 +702,200.0,200 +703,200.0,200 +704,200.0,200 +705,200.0,200 +706,200.0,200 +707,200.0,200 +708,200.0,200 +709,200.0,200 +710,200.0,200 +711,200.0,200 +712,200.0,200 +713,200.0,200 +714,200.0,200 +715,200.0,200 +716,200.0,200 +717,200.0,200 +718,200.0,200 +719,200.0,200 +720,200.0,200 +721,200.0,200 +722,200.0,200 +723,200.0,200 +724,200.0,200 +725,200.0,200 +726,200.0,200 +727,200.0,200 +728,200.0,200 +729,200.0,200 +730,200.0,200 +731,200.0,200 +732,200.0,200 +733,200.0,200 +734,200.0,200 +735,200.0,200 +736,200.0,200 +737,200.0,200 +738,200.0,200 +739,200.0,200 +740,200.0,200 +741,200.0,200 +742,200.0,200 +743,200.0,200 +744,200.0,200 +745,200.0,200 +746,200.0,200 +747,200.0,200 +748,200.0,200 +749,200.0,200 +750,200.0,200 +751,200.0,200 +752,200.0,200 +753,200.0,200 +754,200.0,200 +755,200.0,200 +756,200.0,200 +757,200.0,200 +758,200.0,200 +759,200.0,200 +760,200.0,200 +761,200.0,200 +762,200.0,200 +763,200.0,200 +764,200.0,200 +765,200.0,200 +766,200.0,200 +767,200.0,200 +768,200.0,200 +769,200.0,200 +770,200.0,200 +771,200.0,200 +772,200.0,200 +773,200.0,200 +774,200.0,200 +775,200.0,200 +776,200.0,200 +777,200.0,200 +778,200.0,200 +779,200.0,200 +780,200.0,200 +781,200.0,200 +782,200.0,200 +783,200.0,200 +784,200.0,200 +785,200.0,200 +786,200.0,200 +787,200.0,200 +788,200.0,200 +789,200.0,200 +790,200.0,200 +791,200.0,200 +792,200.0,200 +793,200.0,200 +794,200.0,200 +795,200.0,200 +796,200.0,200 +797,200.0,200 +798,200.0,200 +799,200.0,200 +800,200.0,200 +801,200.0,200 +802,200.0,200 +803,200.0,200 +804,200.0,200 +805,200.0,200 +806,200.0,200 +807,200.0,200 +808,200.0,200 +809,200.0,200 +810,200.0,200 +811,200.0,200 +812,200.0,200 +813,200.0,200 +814,200.0,200 +815,200.0,200 +816,200.0,200 +817,200.0,200 +818,200.0,200 +819,200.0,200 +820,200.0,200 +821,200.0,200 +822,200.0,200 +823,200.0,200 +824,200.0,200 +825,200.0,200 +826,200.0,200 +827,200.0,200 +828,200.0,200 +829,200.0,200 +830,200.0,200 +831,200.0,200 +832,200.0,200 +833,200.0,200 +834,200.0,200 +835,200.0,200 +836,200.0,200 +837,200.0,200 +838,200.0,200 +839,200.0,200 +840,200.0,200 +841,200.0,200 +842,200.0,200 +843,200.0,200 +844,200.0,200 +845,200.0,200 +846,200.0,200 +847,200.0,200 +848,200.0,200 +849,200.0,200 +850,200.0,200 +851,200.0,200 +852,200.0,200 +853,200.0,200 +854,200.0,200 +855,200.0,200 +856,200.0,200 +857,200.0,200 +858,200.0,200 +859,200.0,200 +860,200.0,200 +861,200.0,200 +862,200.0,200 +863,200.0,200 +864,200.0,200 +865,200.0,200 +866,200.0,200 +867,200.0,200 +868,200.0,200 +869,200.0,200 +870,200.0,200 +871,200.0,200 +872,200.0,200 +873,200.0,200 +874,200.0,200 +875,200.0,200 +876,200.0,200 +877,200.0,200 +878,200.0,200 +879,200.0,200 +880,200.0,200 +881,200.0,200 +882,200.0,200 +883,200.0,200 +884,200.0,200 +885,200.0,200 +886,200.0,200 +887,200.0,200 +888,200.0,200 +889,200.0,200 +890,200.0,200 +891,200.0,200 +892,200.0,200 +893,200.0,200 +894,200.0,200 +895,200.0,200 +896,200.0,200 +897,200.0,200 +898,200.0,200 +899,200.0,200 +900,200.0,200 +901,200.0,200 +902,200.0,200 +903,200.0,200 +904,200.0,200 +905,200.0,200 +906,200.0,200 +907,200.0,200 +908,200.0,200 +909,200.0,200 +910,200.0,200 +911,200.0,200 +912,200.0,200 +913,200.0,200 +914,200.0,200 +915,200.0,200 +916,200.0,200 +917,200.0,200 +918,200.0,200 +919,200.0,200 +920,200.0,200 +921,200.0,200 +922,200.0,200 +923,200.0,200 +924,200.0,200 +925,200.0,200 +926,200.0,200 +927,200.0,200 +928,200.0,200 +929,200.0,200 +930,200.0,200 +931,200.0,200 +932,200.0,200 +933,200.0,200 +934,200.0,200 +935,200.0,200 +936,200.0,200 +937,200.0,200 +938,200.0,200 +939,200.0,200 +940,200.0,200 +941,200.0,200 +942,200.0,200 +943,153.0,153 +944,200.0,200 +945,200.0,200 +946,200.0,200 +947,200.0,200 +948,150.0,150 +949,200.0,200 +950,200.0,200 +951,200.0,200 +952,200.0,200 +953,200.0,200 +954,200.0,200 +955,200.0,200 +956,200.0,200 +957,200.0,200 +958,200.0,200 +959,200.0,200 +960,200.0,200 +961,200.0,200 +962,200.0,200 +963,200.0,200 +964,200.0,200 +965,200.0,200 +966,200.0,200 +967,200.0,200 +968,200.0,200 +969,200.0,200 +970,200.0,200 +971,200.0,200 +972,200.0,200 +973,161.0,161 +974,200.0,200 +975,200.0,200 +976,200.0,200 +977,200.0,200 +978,200.0,200 +979,200.0,200 +980,200.0,200 +981,200.0,200 +982,200.0,200 +983,111.0,111 +984,200.0,200 +985,200.0,200 +986,200.0,200 +987,200.0,200 +988,200.0,200 +989,200.0,200 +990,200.0,200 +991,200.0,200 +992,200.0,200 +993,200.0,200 +994,200.0,200 +995,200.0,200 +996,200.0,200 +997,200.0,200 +998,154.0,154 +999,200.0,200 diff --git a/projects/codes/A2C/a2c.py b/projects/codes/A2C/a2c.py index c1a88a5..f822451 100644 --- a/projects/codes/A2C/a2c.py +++ b/projects/codes/A2C/a2c.py @@ -1,34 +1,79 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-08-16 23:05:25 +LastEditor: JiangJi +LastEditTime: 2022-11-01 00:33:49 +Discription: +''' import torch import numpy as np - +from torch.distributions import Categorical,Normal class A2C: def __init__(self,models,memories,cfg): - self.n_actions = cfg['n_actions'] - self.gamma = cfg['gamma'] - self.device = torch.device(cfg['device']) + self.n_actions = cfg.n_actions + self.gamma = cfg.gamma + self.device = torch.device(cfg.device) + self.continuous = cfg.continuous + if hasattr(cfg,'action_bound'): + self.action_bound = cfg.action_bound self.memory = memories['ACMemory'] self.actor = models['Actor'].to(self.device) self.critic = models['Critic'].to(self.device) - self.actor_optim = torch.optim.Adam(self.actor.parameters(), lr=cfg['actor_lr']) - self.critic_optim = torch.optim.Adam(self.critic.parameters(), lr=cfg['critic_lr']) + self.actor_optim = torch.optim.Adam(self.actor.parameters(), lr=cfg.actor_lr) + self.critic_optim = torch.optim.Adam(self.critic.parameters(), lr=cfg.critic_lr) def sample_action(self,state): - state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) - dist = self.actor(state) - value = self.critic(state) # note that 'dist' need require_grad=True - value = value.detach().numpy().squeeze(0)[0] - action = np.random.choice(self.n_actions, p=dist.detach().numpy().squeeze(0)) # shape(p=(n_actions,1) - return action,value,dist + # state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) + # dist = self.actor(state) + # self.entropy = - np.sum(np.mean(dist.detach().cpu().numpy()) * np.log(dist.detach().cpu().numpy())) + # value = self.critic(state) # note that 'dist' need require_grad=True + # self.value = value.detach().cpu().numpy().squeeze(0)[0] + # action = np.random.choice(self.n_actions, p=dist.detach().cpu().numpy().squeeze(0)) # shape(p=(n_actions,1) + # self.log_prob = torch.log(dist.squeeze(0)[action]) + if self.continuous: + state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) + mu, sigma = self.actor(state) + dist = Normal(self.action_bound * mu.view(1,), sigma.view(1,)) + action = dist.sample() + value = self.critic(state) + # self.entropy = - np.sum(np.mean(dist.detach().cpu().numpy()) * np.log(dist.detach().cpu().numpy())) + self.value = value.detach().cpu().numpy().squeeze(0)[0] # detach() to avoid gradient + self.log_prob = dist.log_prob(action).squeeze(dim=0) # Tensor([0.]) + self.entropy = dist.entropy().cpu().detach().numpy().squeeze(0) # detach() to avoid gradient + return action.cpu().detach().numpy() + else: + state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) + probs = self.actor(state) + dist = Categorical(probs) + action = dist.sample() # Tensor([0]) + value = self.critic(state) + self.value = value.detach().cpu().numpy().squeeze(0)[0] # detach() to avoid gradient + self.log_prob = dist.log_prob(action).squeeze(dim=0) # Tensor([0.]) + self.entropy = dist.entropy().cpu().detach().numpy().squeeze(0) # detach() to avoid gradient + return action.cpu().numpy().item() + @torch.no_grad() def predict_action(self,state): - state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) - dist = self.actor(state) - value = self.critic(state) # note that 'dist' need require_grad=True - value = value.detach().numpy().squeeze(0)[0] - action = np.random.choice(self.n_actions, p=dist.detach().numpy().squeeze(0)) # shape(p=(n_actions,1) - return action,value,dist + if self.continuous: + state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) + mu, sigma = self.actor(state) + dist = Normal(self.action_bound * mu.view(1,), sigma.view(1,)) + action = dist.sample() + return action.cpu().detach().numpy() + else: + state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) + dist = self.actor(state) + # value = self.critic(state) # note that 'dist' need require_grad=True + # value = value.detach().cpu().numpy().squeeze(0)[0] + action = np.random.choice(self.n_actions, p=dist.detach().cpu().numpy().squeeze(0)) # shape(p=(n_actions,1) + return action def update(self,next_state,entropy): value_pool,log_prob_pool,reward_pool = self.memory.sample() + value_pool = torch.tensor(value_pool, device=self.device) + log_prob_pool = torch.stack(log_prob_pool) next_state = torch.tensor(next_state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) next_value = self.critic(next_state) returns = np.zeros_like(reward_pool) @@ -36,9 +81,7 @@ class A2C: next_value = reward_pool[t] + self.gamma * next_value # G(s_{t},a{t}) = r_{t+1} + gamma * V(s_{t+1}) returns[t] = next_value returns = torch.tensor(returns, device=self.device) - value_pool = torch.tensor(value_pool, device=self.device) advantages = returns - value_pool - log_prob_pool = torch.stack(log_prob_pool) actor_loss = (-log_prob_pool * advantages).mean() critic_loss = 0.5 * advantages.pow(2).mean() tot_loss = actor_loss + critic_loss + 0.001 * entropy diff --git a/projects/codes/A2C/a2c_2.py b/projects/codes/A2C/a2c_2.py index 74e2cfe..e29acdc 100644 --- a/projects/codes/A2C/a2c_2.py +++ b/projects/codes/A2C/a2c_2.py @@ -1,14 +1,24 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-09-19 14:48:16 +LastEditor: JiangJi +LastEditTime: 2022-10-30 01:21:50 +Discription: #TODO,待更新模版 +''' import torch import numpy as np class A2C_2: def __init__(self,models,memories,cfg): - self.n_actions = cfg['n_actions'] - self.gamma = cfg['gamma'] - self.device = torch.device(cfg['device']) + self.n_actions = cfg.n_actions + self.gamma = cfg.gamma + self.device = torch.device(cfg.device) self.memory = memories['ACMemory'] self.ac_net = models['ActorCritic'].to(self.device) - self.ac_optimizer = torch.optim.Adam(self.ac_net.parameters(), lr=cfg['lr']) + self.ac_optimizer = torch.optim.Adam(self.ac_net.parameters(), lr = cfg.lr) def sample_action(self,state): state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) value, dist = self.ac_net(state) # note that 'dist' need require_grad=True diff --git a/projects/codes/A2C/config/CartPole-v1_A2C_Test.yaml b/projects/codes/A2C/config/CartPole-v1_A2C_Test.yaml new file mode 100644 index 0000000..d148bb0 --- /dev/null +++ b/projects/codes/A2C/config/CartPole-v1_A2C_Test.yaml @@ -0,0 +1,21 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: CartPole-v1 + mode: test + load_checkpoint: true + load_path: Train_CartPole-v1_A2C_20221031-232138 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 1000 +algo_cfg: + continuous: false + batch_size: 64 + buffer_size: 100000 + gamma: 0.99 + actor_lr: 0.0003 + critic_lr: 0.001 + target_update: 4 diff --git a/projects/codes/A2C/config/CartPole-v1_A2C_Train.yaml b/projects/codes/A2C/config/CartPole-v1_A2C_Train.yaml new file mode 100644 index 0000000..f79f148 --- /dev/null +++ b/projects/codes/A2C/config/CartPole-v1_A2C_Train.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: CartPole-v1 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 600 +algo_cfg: + continuous: false + batch_size: 64 + buffer_size: 100000 + gamma: 0.0003 + lr: 0.001 diff --git a/projects/codes/A2C/config/Pendulum-v1_A2C_Train.yaml b/projects/codes/A2C/config/Pendulum-v1_A2C_Train.yaml new file mode 100644 index 0000000..a1680c9 --- /dev/null +++ b/projects/codes/A2C/config/Pendulum-v1_A2C_Train.yaml @@ -0,0 +1,21 @@ +general_cfg: + algo_name: A2C + device: cuda + env_name: Pendulum-v1 + mode: train + eval_per_episode: 200 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 1000 +algo_cfg: + continuous: true + batch_size: 64 + buffer_size: 100000 + gamma: 0.0003 + actor_lr: 0.0003 + critic_lr: 0.001 diff --git a/projects/codes/A2C/config/config.py b/projects/codes/A2C/config/config.py new file mode 100644 index 0000000..a552d38 --- /dev/null +++ b/projects/codes/A2C/config/config.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 00:53:03 +LastEditor: JiangJi +LastEditTime: 2022-11-01 00:17:55 +Discription: default parameters of A2C +''' +from common.config import GeneralConfig,AlgoConfig + +class GeneralConfigA2C(GeneralConfig): + def __init__(self) -> None: + self.env_name = "CartPole-v1" # name of environment + self.algo_name = "A2C" # name of algorithm + self.mode = "train" # train or test + self.seed = 1 # random seed + self.device = "cuda" # device to use + self.train_eps = 1000 # number of episodes for training + self.test_eps = 20 # number of episodes for testing + self.max_steps = 200 # max steps for each episode + self.load_checkpoint = False + self.load_path = "tasks" # path to load model + self.show_fig = False # show figure or not + self.save_fig = True # save figure or not + +class AlgoConfigA2C(AlgoConfig): + def __init__(self) -> None: + self.continuous = False # continuous or discrete action space + self.hidden_dim = 256 # hidden_dim for MLP + self.gamma = 0.99 # discount factor + self.actor_lr = 3e-4 # learning rate of actor + self.critic_lr = 1e-3 # learning rate of critic + self.actor_hidden_dim = 256 # hidden_dim for actor MLP + self.critic_hidden_dim = 256 # hidden_dim for critic MLP + self.buffer_size = 100000 # size of replay buffer + self.batch_size = 64 # batch size \ No newline at end of file diff --git a/projects/codes/A2C/main.py b/projects/codes/A2C/main.py deleted file mode 100644 index e5585e8..0000000 --- a/projects/codes/A2C/main.py +++ /dev/null @@ -1,121 +0,0 @@ -import sys,os -os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." -curr_path = os.path.dirname(os.path.abspath(__file__)) # current path -parent_path = os.path.dirname(curr_path) # parent path -sys.path.append(parent_path) # add path to system path - -import datetime -import argparse -import gym -import torch -import numpy as np -from common.utils import all_seed -from common.launcher import Launcher -from common.memories import PGReplay -from common.models import ActorSoftmax,Critic -from envs.register import register_env -from a2c import A2C - -class Main(Launcher): - def get_args(self): - curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # obtain current time - parser = argparse.ArgumentParser(description="hyperparameters") - parser.add_argument('--algo_name',default='A2C',type=str,help="name of algorithm") - parser.add_argument('--env_name',default='CartPole-v0',type=str,help="name of environment") - parser.add_argument('--train_eps',default=1600,type=int,help="episodes of training") - parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") - parser.add_argument('--ep_max_steps',default = 100000,type=int,help="steps per episode, much larger value can simulate infinite steps") - parser.add_argument('--gamma',default=0.99,type=float,help="discounted factor") - parser.add_argument('--actor_lr',default=3e-4,type=float,help="learning rate of actor") - parser.add_argument('--critic_lr',default=1e-3,type=float,help="learning rate of critic") - parser.add_argument('--actor_hidden_dim',default=256,type=int,help="hidden of actor net") - parser.add_argument('--critic_hidden_dim',default=256,type=int,help="hidden of critic net") - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--seed',default=10,type=int,help="seed") - parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") - parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") - args = parser.parse_args() - default_args = {'result_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/results/", - 'model_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/models/", - } - args = {**vars(args),**default_args} # type(dict) - return args - def env_agent_config(self,cfg): - ''' create env and agent - ''' - register_env(cfg['env_name']) - env = gym.make(cfg['env_name']) - if cfg['seed'] !=0: # set random seed - all_seed(env,seed=cfg["seed"]) - try: # state dimension - n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) - except AttributeError: - n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) - n_actions = env.action_space.n # action dimension - print(f"n_states: {n_states}, n_actions: {n_actions}") - cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters - models = {'Actor':ActorSoftmax(cfg['n_states'],cfg['n_actions'], hidden_dim = cfg['actor_hidden_dim']),'Critic':Critic(cfg['n_states'],1,hidden_dim=cfg['critic_hidden_dim'])} - memories = {'ACMemory':PGReplay()} - agent = A2C(models,memories,cfg) - return env,agent - def train(self,cfg,env,agent): - print("Start training!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # record rewards for all episodes - steps = [] # record steps for all episodes - - for i_ep in range(cfg['train_eps']): - ep_reward = 0 # reward per episode - ep_step = 0 # step per episode - ep_entropy = 0 - state = env.reset() # reset and obtain initial state - - for _ in range(cfg['ep_max_steps']): - action, value, dist = agent.sample_action(state) # sample action - next_state, reward, done, _ = env.step(action) # update env and return transitions - log_prob = torch.log(dist.squeeze(0)[action]) - entropy = -np.sum(np.mean(dist.detach().numpy()) * np.log(dist.detach().numpy())) - agent.memory.push((value,log_prob,reward)) # save transitions - state = next_state # update state - ep_reward += reward - ep_entropy += entropy - ep_step += 1 - if done: - break - agent.update(next_state,ep_entropy) # update agent - rewards.append(ep_reward) - steps.append(ep_step) - if (i_ep+1)%10==0: - print(f'Episode: {i_ep+1}/{cfg["train_eps"]}, Reward: {ep_reward:.2f}, Steps:{ep_step}') - print("Finish training!") - return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} - def test(self,cfg,env,agent): - print("Start testing!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # record rewards for all episodes - steps = [] # record steps for all episodes - for i_ep in range(cfg['test_eps']): - ep_reward = 0 # reward per episode - ep_step = 0 - state = env.reset() # reset and obtain initial state - for _ in range(cfg['ep_max_steps']): - action,_,_ = agent.predict_action(state) # predict action - next_state, reward, done, _ = env.step(action) - state = next_state - ep_reward += reward - ep_step += 1 - if done: - break - rewards.append(ep_reward) - steps.append(ep_step) - print(f"Episode: {i_ep+1}/{cfg['test_eps']}, Steps:{ep_step}, Reward: {ep_reward:.2f}") - print("Finish testing!") - return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} - -if __name__ == "__main__": - main = Main() - main.run() - - - - diff --git a/projects/codes/A2C/main2.py b/projects/codes/A2C/main2.py index c81754f..60bd7c2 100644 --- a/projects/codes/A2C/main2.py +++ b/projects/codes/A2C/main2.py @@ -1,3 +1,13 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-09-19 14:48:16 +LastEditor: JiangJi +LastEditTime: 2022-10-30 01:21:15 +Discription: #TODO,待更新模版 +''' import sys,os os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." curr_path = os.path.dirname(os.path.abspath(__file__)) # current path diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/models/a2c_checkpoint.pt b/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/models/a2c_checkpoint.pt deleted file mode 100644 index c346b1b..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/models/a2c_checkpoint.pt and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/params.json b/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/params.json deleted file mode 100644 index 2ce53a7..0000000 --- a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/params.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "algo_name": "A2C", - "env_name": "CartPole-v0", - "train_eps": 2000, - "test_eps": 20, - "ep_max_steps": 100000, - "gamma": 0.99, - "lr": 0.0003, - "actor_hidden_dim": 256, - "critic_hidden_dim": 256, - "device": "cpu", - "seed": 10, - "show_fig": false, - "save_fig": true, - "result_path": "/Users/jj/Desktop/rl-tutorials/codes/A2C/outputs/CartPole-v0/20220829-135818/results/", - "model_path": "/Users/jj/Desktop/rl-tutorials/codes/A2C/outputs/CartPole-v0/20220829-135818/models/", - "n_states": 4, - "n_actions": 2 -} \ No newline at end of file diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/testing_curve.png b/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/testing_curve.png deleted file mode 100644 index b1bbebb..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/training_curve.png b/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/training_curve.png deleted file mode 100644 index 4410e5e..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/training_curve.png and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/training_results.csv b/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/training_results.csv deleted file mode 100644 index 7d5debb..0000000 --- a/projects/codes/A2C/outputs/CartPole-v0/20220829-135818/results/training_results.csv +++ /dev/null @@ -1,2001 +0,0 @@ -episodes,rewards,steps -0,16.0,16 -1,17.0,17 -2,19.0,19 -3,95.0,95 -4,13.0,13 -5,22.0,22 -6,15.0,15 -7,20.0,20 -8,13.0,13 -9,20.0,20 -10,21.0,21 -11,59.0,59 -12,16.0,16 -13,35.0,35 -14,17.0,17 -15,22.0,22 -16,28.0,28 -17,19.0,19 -18,12.0,12 -19,17.0,17 -20,16.0,16 -21,28.0,28 -22,11.0,11 -23,11.0,11 -24,11.0,11 -25,18.0,18 -26,15.0,15 -27,33.0,33 -28,21.0,21 -29,34.0,34 -30,11.0,11 -31,16.0,16 -32,27.0,27 -33,19.0,19 -34,16.0,16 -35,33.0,33 -36,21.0,21 -37,12.0,12 -38,26.0,26 -39,34.0,34 -40,11.0,11 -41,38.0,38 -42,13.0,13 -43,12.0,12 -44,20.0,20 -45,17.0,17 -46,10.0,10 -47,20.0,20 -48,22.0,22 -49,21.0,21 -50,20.0,20 -51,32.0,32 -52,10.0,10 -53,33.0,33 -54,25.0,25 -55,30.0,30 -56,22.0,22 -57,25.0,25 -58,19.0,19 -59,12.0,12 -60,9.0,9 -61,11.0,11 -62,12.0,12 -63,28.0,28 -64,12.0,12 -65,12.0,12 -66,12.0,12 -67,34.0,34 -68,12.0,12 -69,25.0,25 -70,13.0,13 -71,26.0,26 -72,13.0,13 -73,22.0,22 -74,24.0,24 -75,9.0,9 -76,14.0,14 -77,17.0,17 -78,14.0,14 -79,25.0,25 -80,23.0,23 -81,38.0,38 -82,30.0,30 -83,28.0,28 -84,25.0,25 -85,16.0,16 -86,13.0,13 -87,34.0,34 -88,16.0,16 -89,48.0,48 -90,12.0,12 -91,25.0,25 -92,25.0,25 -93,17.0,17 -94,13.0,13 -95,12.0,12 -96,23.0,23 -97,22.0,22 -98,12.0,12 -99,16.0,16 -100,16.0,16 -101,10.0,10 -102,14.0,14 -103,20.0,20 -104,13.0,13 -105,16.0,16 -106,14.0,14 -107,22.0,22 -108,17.0,17 -109,19.0,19 -110,26.0,26 -111,16.0,16 -112,22.0,22 -113,20.0,20 -114,27.0,27 -115,16.0,16 -116,40.0,40 -117,14.0,14 -118,15.0,15 -119,40.0,40 -120,23.0,23 -121,32.0,32 -122,13.0,13 -123,33.0,33 -124,18.0,18 -125,26.0,26 -126,30.0,30 -127,28.0,28 -128,12.0,12 -129,45.0,45 -130,14.0,14 -131,40.0,40 -132,13.0,13 -133,16.0,16 -134,78.0,78 -135,19.0,19 -136,19.0,19 -137,20.0,20 -138,26.0,26 -139,21.0,21 -140,28.0,28 -141,17.0,17 -142,19.0,19 -143,13.0,13 -144,54.0,54 -145,41.0,41 -146,10.0,10 -147,15.0,15 -148,14.0,14 -149,19.0,19 -150,19.0,19 -151,32.0,32 -152,39.0,39 -153,36.0,36 -154,21.0,21 -155,58.0,58 -156,15.0,15 -157,55.0,55 -158,16.0,16 -159,46.0,46 -160,25.0,25 -161,15.0,15 -162,13.0,13 -163,18.0,18 -164,19.0,19 -165,22.0,22 -166,17.0,17 -167,48.0,48 -168,28.0,28 -169,29.0,29 -170,60.0,60 -171,12.0,12 -172,34.0,34 -173,18.0,18 -174,20.0,20 -175,18.0,18 -176,29.0,29 -177,14.0,14 -178,23.0,23 -179,26.0,26 -180,23.0,23 -181,77.0,77 -182,46.0,46 -183,25.0,25 -184,37.0,37 -185,12.0,12 -186,12.0,12 -187,36.0,36 -188,30.0,30 -189,135.0,135 -190,11.0,11 -191,18.0,18 -192,34.0,34 -193,12.0,12 -194,22.0,22 -195,19.0,19 -196,21.0,21 -197,26.0,26 -198,13.0,13 -199,128.0,128 -200,11.0,11 -201,21.0,21 -202,27.0,27 -203,11.0,11 -204,14.0,14 -205,70.0,70 -206,10.0,10 -207,18.0,18 -208,35.0,35 -209,80.0,80 -210,19.0,19 -211,95.0,95 -212,14.0,14 -213,20.0,20 -214,30.0,30 -215,19.0,19 -216,20.0,20 -217,54.0,54 -218,27.0,27 -219,19.0,19 -220,30.0,30 -221,19.0,19 -222,55.0,55 -223,29.0,29 -224,65.0,65 -225,19.0,19 -226,38.0,38 -227,14.0,14 -228,62.0,62 -229,37.0,37 -230,50.0,50 -231,40.0,40 -232,39.0,39 -233,16.0,16 -234,18.0,18 -235,86.0,86 -236,45.0,45 -237,37.0,37 -238,35.0,35 -239,20.0,20 -240,22.0,22 -241,40.0,40 -242,29.0,29 -243,17.0,17 -244,34.0,34 -245,91.0,91 -246,31.0,31 -247,69.0,69 -248,31.0,31 -249,30.0,30 -250,30.0,30 -251,23.0,23 -252,22.0,22 -253,52.0,52 -254,25.0,25 -255,32.0,32 -256,37.0,37 -257,31.0,31 -258,18.0,18 -259,60.0,60 -260,15.0,15 -261,23.0,23 -262,34.0,34 -263,43.0,43 -264,66.0,66 -265,15.0,15 -266,19.0,19 -267,55.0,55 -268,65.0,65 -269,50.0,50 -270,19.0,19 -271,37.0,37 -272,33.0,33 -273,33.0,33 -274,16.0,16 -275,19.0,19 -276,18.0,18 -277,52.0,52 -278,27.0,27 -279,48.0,48 -280,39.0,39 -281,29.0,29 -282,86.0,86 -283,37.0,37 -284,21.0,21 -285,21.0,21 -286,52.0,52 -287,88.0,88 -288,30.0,30 -289,34.0,34 -290,22.0,22 -291,26.0,26 -292,18.0,18 -293,29.0,29 -294,57.0,57 -295,61.0,61 -296,73.0,73 -297,19.0,19 -298,32.0,32 -299,49.0,49 -300,58.0,58 -301,31.0,31 -302,29.0,29 -303,73.0,73 -304,21.0,21 -305,33.0,33 -306,23.0,23 -307,22.0,22 -308,36.0,36 -309,41.0,41 -310,19.0,19 -311,41.0,41 -312,67.0,67 -313,95.0,95 -314,43.0,43 -315,27.0,27 -316,29.0,29 -317,30.0,30 -318,23.0,23 -319,32.0,32 -320,48.0,48 -321,33.0,33 -322,32.0,32 -323,63.0,63 -324,20.0,20 -325,25.0,25 -326,23.0,23 -327,42.0,42 -328,15.0,15 -329,66.0,66 -330,40.0,40 -331,31.0,31 -332,73.0,73 -333,52.0,52 -334,31.0,31 -335,69.0,69 -336,33.0,33 -337,39.0,39 -338,21.0,21 -339,34.0,34 -340,32.0,32 -341,38.0,38 -342,29.0,29 -343,32.0,32 -344,14.0,14 -345,51.0,51 -346,38.0,38 -347,51.0,51 -348,28.0,28 -349,85.0,85 -350,34.0,34 -351,57.0,57 -352,21.0,21 -353,22.0,22 -354,27.0,27 -355,19.0,19 -356,77.0,77 -357,30.0,30 -358,28.0,28 -359,53.0,53 -360,48.0,48 -361,41.0,41 -362,26.0,26 -363,35.0,35 -364,52.0,52 -365,42.0,42 -366,21.0,21 -367,34.0,34 -368,43.0,43 -369,82.0,82 -370,43.0,43 -371,67.0,67 -372,56.0,56 -373,54.0,54 -374,27.0,27 -375,37.0,37 -376,32.0,32 -377,23.0,23 -378,32.0,32 -379,40.0,40 -380,26.0,26 -381,22.0,22 -382,23.0,23 -383,100.0,100 -384,45.0,45 -385,57.0,57 -386,51.0,51 -387,15.0,15 -388,17.0,17 -389,63.0,63 -390,67.0,67 -391,80.0,80 -392,64.0,64 -393,29.0,29 -394,74.0,74 -395,51.0,51 -396,88.0,88 -397,11.0,11 -398,27.0,27 -399,30.0,30 -400,22.0,22 -401,36.0,36 -402,13.0,13 -403,37.0,37 -404,86.0,86 -405,18.0,18 -406,25.0,25 -407,21.0,21 -408,30.0,30 -409,28.0,28 -410,43.0,43 -411,23.0,23 -412,17.0,17 -413,32.0,32 -414,25.0,25 -415,22.0,22 -416,36.0,36 -417,52.0,52 -418,33.0,33 -419,16.0,16 -420,30.0,30 -421,52.0,52 -422,59.0,59 -423,35.0,35 -424,39.0,39 -425,47.0,47 -426,30.0,30 -427,32.0,32 -428,42.0,42 -429,37.0,37 -430,35.0,35 -431,25.0,25 -432,39.0,39 -433,26.0,26 -434,58.0,58 -435,64.0,64 -436,30.0,30 -437,33.0,33 -438,42.0,42 -439,30.0,30 -440,47.0,47 -441,69.0,69 -442,47.0,47 -443,40.0,40 -444,53.0,53 -445,38.0,38 -446,176.0,176 -447,116.0,116 -448,40.0,40 -449,86.0,86 -450,38.0,38 -451,39.0,39 -452,48.0,48 -453,22.0,22 -454,64.0,64 -455,30.0,30 -456,36.0,36 -457,46.0,46 -458,16.0,16 -459,103.0,103 -460,58.0,58 -461,16.0,16 -462,36.0,36 -463,21.0,21 -464,79.0,79 -465,29.0,29 -466,67.0,67 -467,59.0,59 -468,50.0,50 -469,72.0,72 -470,75.0,75 -471,26.0,26 -472,36.0,36 -473,35.0,35 -474,40.0,40 -475,49.0,49 -476,47.0,47 -477,42.0,42 -478,37.0,37 -479,33.0,33 -480,60.0,60 -481,34.0,34 -482,20.0,20 -483,69.0,69 -484,63.0,63 -485,49.0,49 -486,18.0,18 -487,68.0,68 -488,24.0,24 -489,79.0,79 -490,22.0,22 -491,39.0,39 -492,64.0,64 -493,20.0,20 -494,21.0,21 -495,22.0,22 -496,56.0,56 -497,56.0,56 -498,39.0,39 -499,64.0,64 -500,42.0,42 -501,40.0,40 -502,44.0,44 -503,30.0,30 -504,56.0,56 -505,137.0,137 -506,37.0,37 -507,19.0,19 -508,59.0,59 -509,29.0,29 -510,108.0,108 -511,53.0,53 -512,26.0,26 -513,43.0,43 -514,27.0,27 -515,34.0,34 -516,51.0,51 -517,35.0,35 -518,90.0,90 -519,64.0,64 -520,63.0,63 -521,33.0,33 -522,29.0,29 -523,48.0,48 -524,40.0,40 -525,55.0,55 -526,26.0,26 -527,69.0,69 -528,48.0,48 -529,50.0,50 -530,34.0,34 -531,31.0,31 -532,26.0,26 -533,60.0,60 -534,60.0,60 -535,80.0,80 -536,44.0,44 -537,62.0,62 -538,47.0,47 -539,79.0,79 -540,91.0,91 -541,84.0,84 -542,134.0,134 -543,49.0,49 -544,37.0,37 -545,23.0,23 -546,52.0,52 -547,52.0,52 -548,57.0,57 -549,69.0,69 -550,76.0,76 -551,33.0,33 -552,117.0,117 -553,83.0,83 -554,38.0,38 -555,45.0,45 -556,119.0,119 -557,105.0,105 -558,151.0,151 -559,59.0,59 -560,41.0,41 -561,49.0,49 -562,29.0,29 -563,61.0,61 -564,106.0,106 -565,43.0,43 -566,51.0,51 -567,54.0,54 -568,60.0,60 -569,29.0,29 -570,54.0,54 -571,47.0,47 -572,101.0,101 -573,26.0,26 -574,71.0,71 -575,115.0,115 -576,21.0,21 -577,47.0,47 -578,71.0,71 -579,61.0,61 -580,30.0,30 -581,72.0,72 -582,37.0,37 -583,62.0,62 -584,76.0,76 -585,49.0,49 -586,78.0,78 -587,62.0,62 -588,86.0,86 -589,56.0,56 -590,103.0,103 -591,97.0,97 -592,53.0,53 -593,110.0,110 -594,91.0,91 -595,52.0,52 -596,67.0,67 -597,40.0,40 -598,71.0,71 -599,52.0,52 -600,49.0,49 -601,101.0,101 -602,93.0,93 -603,33.0,33 -604,56.0,56 -605,53.0,53 -606,103.0,103 -607,134.0,134 -608,83.0,83 -609,78.0,78 -610,25.0,25 -611,52.0,52 -612,61.0,61 -613,49.0,49 -614,91.0,91 -615,46.0,46 -616,34.0,34 -617,72.0,72 -618,62.0,62 -619,42.0,42 -620,63.0,63 -621,60.0,60 -622,178.0,178 -623,43.0,43 -624,66.0,66 -625,23.0,23 -626,42.0,42 -627,26.0,26 -628,73.0,73 -629,30.0,30 -630,39.0,39 -631,36.0,36 -632,47.0,47 -633,58.0,58 -634,45.0,45 -635,82.0,82 -636,55.0,55 -637,31.0,31 -638,71.0,71 -639,68.0,68 -640,119.0,119 -641,42.0,42 -642,72.0,72 -643,36.0,36 -644,47.0,47 -645,126.0,126 -646,64.0,64 -647,60.0,60 -648,147.0,147 -649,34.0,34 -650,17.0,17 -651,59.0,59 -652,46.0,46 -653,126.0,126 -654,76.0,76 -655,85.0,85 -656,68.0,68 -657,36.0,36 -658,53.0,53 -659,116.0,116 -660,99.0,99 -661,29.0,29 -662,22.0,22 -663,89.0,89 -664,166.0,166 -665,73.0,73 -666,28.0,28 -667,110.0,110 -668,92.0,92 -669,76.0,76 -670,65.0,65 -671,48.0,48 -672,27.0,27 -673,38.0,38 -674,44.0,44 -675,70.0,70 -676,103.0,103 -677,48.0,48 -678,56.0,56 -679,51.0,51 -680,30.0,30 -681,118.0,118 -682,35.0,35 -683,12.0,12 -684,64.0,64 -685,105.0,105 -686,23.0,23 -687,52.0,52 -688,153.0,153 -689,65.0,65 -690,44.0,44 -691,38.0,38 -692,55.0,55 -693,37.0,37 -694,18.0,18 -695,106.0,106 -696,175.0,175 -697,88.0,88 -698,22.0,22 -699,60.0,60 -700,22.0,22 -701,78.0,78 -702,54.0,54 -703,61.0,61 -704,50.0,50 -705,55.0,55 -706,34.0,34 -707,23.0,23 -708,39.0,39 -709,45.0,45 -710,43.0,43 -711,113.0,113 -712,59.0,59 -713,36.0,36 -714,71.0,71 -715,35.0,35 -716,45.0,45 -717,42.0,42 -718,40.0,40 -719,26.0,26 -720,52.0,52 -721,29.0,29 -722,47.0,47 -723,45.0,45 -724,73.0,73 -725,42.0,42 -726,42.0,42 -727,30.0,30 -728,119.0,119 -729,60.0,60 -730,18.0,18 -731,18.0,18 -732,21.0,21 -733,33.0,33 -734,45.0,45 -735,35.0,35 -736,28.0,28 -737,37.0,37 -738,26.0,26 -739,28.0,28 -740,31.0,31 -741,130.0,130 -742,48.0,48 -743,65.0,65 -744,38.0,38 -745,54.0,54 -746,92.0,92 -747,53.0,53 -748,42.0,42 -749,87.0,87 -750,65.0,65 -751,45.0,45 -752,58.0,58 -753,27.0,27 -754,20.0,20 -755,59.0,59 -756,105.0,105 -757,54.0,54 -758,27.0,27 -759,46.0,46 -760,29.0,29 -761,15.0,15 -762,58.0,58 -763,22.0,22 -764,45.0,45 -765,44.0,44 -766,81.0,81 -767,61.0,61 -768,23.0,23 -769,134.0,134 -770,38.0,38 -771,200.0,200 -772,63.0,63 -773,62.0,62 -774,36.0,36 -775,68.0,68 -776,94.0,94 -777,26.0,26 -778,61.0,61 -779,77.0,77 -780,71.0,71 -781,63.0,63 -782,40.0,40 -783,26.0,26 -784,126.0,126 -785,59.0,59 -786,64.0,64 -787,57.0,57 -788,99.0,99 -789,47.0,47 -790,68.0,68 -791,38.0,38 -792,57.0,57 -793,42.0,42 -794,79.0,79 -795,108.0,108 -796,63.0,63 -797,62.0,62 -798,189.0,189 -799,157.0,157 -800,93.0,93 -801,53.0,53 -802,56.0,56 -803,144.0,144 -804,63.0,63 -805,41.0,41 -806,134.0,134 -807,23.0,23 -808,90.0,90 -809,124.0,124 -810,42.0,42 -811,40.0,40 -812,29.0,29 -813,46.0,46 -814,160.0,160 -815,34.0,34 -816,91.0,91 -817,60.0,60 -818,50.0,50 -819,113.0,113 -820,108.0,108 -821,56.0,56 -822,200.0,200 -823,154.0,154 -824,78.0,78 -825,55.0,55 -826,136.0,136 -827,66.0,66 -828,81.0,81 -829,23.0,23 -830,63.0,63 -831,85.0,85 -832,91.0,91 -833,85.0,85 -834,17.0,17 -835,85.0,85 -836,152.0,152 -837,59.0,59 -838,40.0,40 -839,103.0,103 -840,135.0,135 -841,50.0,50 -842,22.0,22 -843,75.0,75 -844,97.0,97 -845,59.0,59 -846,57.0,57 -847,122.0,122 -848,100.0,100 -849,132.0,132 -850,53.0,53 -851,106.0,106 -852,87.0,87 -853,82.0,82 -854,154.0,154 -855,139.0,139 -856,27.0,27 -857,35.0,35 -858,60.0,60 -859,188.0,188 -860,116.0,116 -861,160.0,160 -862,190.0,190 -863,61.0,61 -864,122.0,122 -865,97.0,97 -866,54.0,54 -867,24.0,24 -868,122.0,122 -869,161.0,161 -870,40.0,40 -871,165.0,165 -872,145.0,145 -873,155.0,155 -874,90.0,90 -875,58.0,58 -876,53.0,53 -877,47.0,47 -878,53.0,53 -879,86.0,86 -880,56.0,56 -881,152.0,152 -882,77.0,77 -883,50.0,50 -884,85.0,85 -885,200.0,200 -886,96.0,96 -887,85.0,85 -888,44.0,44 -889,39.0,39 -890,200.0,200 -891,164.0,164 -892,36.0,36 -893,139.0,139 -894,44.0,44 -895,46.0,46 -896,103.0,103 -897,168.0,168 -898,189.0,189 -899,200.0,200 -900,69.0,69 -901,71.0,71 -902,147.0,147 -903,140.0,140 -904,200.0,200 -905,82.0,82 -906,129.0,129 -907,164.0,164 -908,28.0,28 -909,73.0,73 -910,174.0,174 -911,176.0,176 -912,132.0,132 -913,149.0,149 -914,93.0,93 -915,52.0,52 -916,93.0,93 -917,33.0,33 -918,154.0,154 -919,200.0,200 -920,200.0,200 -921,200.0,200 -922,67.0,67 -923,83.0,83 -924,162.0,162 -925,41.0,41 -926,103.0,103 -927,200.0,200 -928,131.0,131 -929,117.0,117 -930,77.0,77 -931,45.0,45 -932,144.0,144 -933,123.0,123 -934,122.0,122 -935,29.0,29 -936,89.0,89 -937,71.0,71 -938,200.0,200 -939,80.0,80 -940,98.0,98 -941,143.0,143 -942,200.0,200 -943,95.0,95 -944,83.0,83 -945,62.0,62 -946,62.0,62 -947,118.0,118 -948,144.0,144 -949,113.0,113 -950,110.0,110 -951,139.0,139 -952,70.0,70 -953,79.0,79 -954,176.0,176 -955,151.0,151 -956,24.0,24 -957,50.0,50 -958,90.0,90 -959,20.0,20 -960,65.0,65 -961,176.0,176 -962,37.0,37 -963,48.0,48 -964,89.0,89 -965,190.0,190 -966,155.0,155 -967,26.0,26 -968,200.0,200 -969,186.0,186 -970,60.0,60 -971,115.0,115 -972,115.0,115 -973,121.0,121 -974,177.0,177 -975,200.0,200 -976,51.0,51 -977,105.0,105 -978,200.0,200 -979,68.0,68 -980,170.0,170 -981,70.0,70 -982,55.0,55 -983,70.0,70 -984,66.0,66 -985,161.0,161 -986,40.0,40 -987,200.0,200 -988,107.0,107 -989,80.0,80 -990,128.0,128 -991,154.0,154 -992,101.0,101 -993,178.0,178 -994,129.0,129 -995,128.0,128 -996,146.0,146 -997,142.0,142 -998,200.0,200 -999,62.0,62 -1000,19.0,19 -1001,82.0,82 -1002,63.0,63 -1003,129.0,129 -1004,54.0,54 -1005,125.0,125 -1006,113.0,113 -1007,93.0,93 -1008,200.0,200 -1009,48.0,48 -1010,58.0,58 -1011,66.0,66 -1012,41.0,41 -1013,145.0,145 -1014,42.0,42 -1015,185.0,185 -1016,199.0,199 -1017,200.0,200 -1018,125.0,125 -1019,145.0,145 -1020,32.0,32 -1021,141.0,141 -1022,195.0,195 -1023,175.0,175 -1024,162.0,162 -1025,127.0,127 -1026,154.0,154 -1027,166.0,166 -1028,200.0,200 -1029,188.0,188 -1030,200.0,200 -1031,200.0,200 -1032,162.0,162 -1033,141.0,141 -1034,200.0,200 -1035,155.0,155 -1036,134.0,134 -1037,146.0,146 -1038,192.0,192 -1039,136.0,136 -1040,200.0,200 -1041,149.0,149 -1042,113.0,113 -1043,40.0,40 -1044,178.0,178 -1045,126.0,126 -1046,200.0,200 -1047,37.0,37 -1048,200.0,200 -1049,141.0,141 -1050,118.0,118 -1051,34.0,34 -1052,142.0,142 -1053,65.0,65 -1054,200.0,200 -1055,133.0,133 -1056,137.0,137 -1057,148.0,148 -1058,148.0,148 -1059,136.0,136 -1060,159.0,159 -1061,48.0,48 -1062,109.0,109 -1063,65.0,65 -1064,130.0,130 -1065,191.0,191 -1066,200.0,200 -1067,200.0,200 -1068,48.0,48 -1069,200.0,200 -1070,65.0,65 -1071,164.0,164 -1072,200.0,200 -1073,156.0,156 -1074,200.0,200 -1075,131.0,131 -1076,126.0,126 -1077,200.0,200 -1078,200.0,200 -1079,32.0,32 -1080,175.0,175 -1081,200.0,200 -1082,84.0,84 -1083,81.0,81 -1084,183.0,183 -1085,51.0,51 -1086,155.0,155 -1087,146.0,146 -1088,108.0,108 -1089,176.0,176 -1090,189.0,189 -1091,200.0,200 -1092,164.0,164 -1093,70.0,70 -1094,200.0,200 -1095,172.0,172 -1096,163.0,163 -1097,168.0,168 -1098,181.0,181 -1099,200.0,200 -1100,33.0,33 -1101,200.0,200 -1102,58.0,58 -1103,200.0,200 -1104,156.0,156 -1105,200.0,200 -1106,138.0,138 -1107,200.0,200 -1108,81.0,81 -1109,105.0,105 -1110,87.0,87 -1111,170.0,170 -1112,200.0,200 -1113,200.0,200 -1114,200.0,200 -1115,200.0,200 -1116,200.0,200 -1117,200.0,200 -1118,200.0,200 -1119,158.0,158 -1120,64.0,64 -1121,138.0,138 -1122,200.0,200 -1123,158.0,158 -1124,86.0,86 -1125,125.0,125 -1126,105.0,105 -1127,200.0,200 -1128,120.0,120 -1129,53.0,53 -1130,127.0,127 -1131,200.0,200 -1132,48.0,48 -1133,200.0,200 -1134,144.0,144 -1135,42.0,42 -1136,100.0,100 -1137,160.0,160 -1138,200.0,200 -1139,200.0,200 -1140,200.0,200 -1141,200.0,200 -1142,135.0,135 -1143,184.0,184 -1144,184.0,184 -1145,168.0,168 -1146,162.0,162 -1147,52.0,52 -1148,120.0,120 -1149,133.0,133 -1150,200.0,200 -1151,178.0,178 -1152,200.0,200 -1153,22.0,22 -1154,200.0,200 -1155,108.0,108 -1156,200.0,200 -1157,200.0,200 -1158,102.0,102 -1159,200.0,200 -1160,200.0,200 -1161,200.0,200 -1162,65.0,65 -1163,131.0,131 -1164,129.0,129 -1165,136.0,136 -1166,137.0,137 -1167,40.0,40 -1168,130.0,130 -1169,99.0,99 -1170,131.0,131 -1171,200.0,200 -1172,172.0,172 -1173,200.0,200 -1174,200.0,200 -1175,83.0,83 -1176,151.0,151 -1177,200.0,200 -1178,70.0,70 -1179,84.0,84 -1180,172.0,172 -1181,200.0,200 -1182,22.0,22 -1183,118.0,118 -1184,200.0,200 -1185,200.0,200 -1186,200.0,200 -1187,200.0,200 -1188,200.0,200 -1189,145.0,145 -1190,121.0,121 -1191,159.0,159 -1192,126.0,126 -1193,49.0,49 -1194,200.0,200 -1195,119.0,119 -1196,155.0,155 -1197,71.0,71 -1198,200.0,200 -1199,79.0,79 -1200,68.0,68 -1201,200.0,200 -1202,200.0,200 -1203,143.0,143 -1204,200.0,200 -1205,54.0,54 -1206,180.0,180 -1207,158.0,158 -1208,149.0,149 -1209,170.0,170 -1210,118.0,118 -1211,155.0,155 -1212,200.0,200 -1213,200.0,200 -1214,143.0,143 -1215,200.0,200 -1216,200.0,200 -1217,55.0,55 -1218,200.0,200 -1219,200.0,200 -1220,168.0,168 -1221,170.0,170 -1222,112.0,112 -1223,108.0,108 -1224,104.0,104 -1225,135.0,135 -1226,131.0,131 -1227,98.0,98 -1228,63.0,63 -1229,200.0,200 -1230,119.0,119 -1231,130.0,130 -1232,113.0,113 -1233,170.0,170 -1234,200.0,200 -1235,164.0,164 -1236,149.0,149 -1237,200.0,200 -1238,116.0,116 -1239,200.0,200 -1240,133.0,133 -1241,200.0,200 -1242,164.0,164 -1243,154.0,154 -1244,191.0,191 -1245,128.0,128 -1246,119.0,119 -1247,114.0,114 -1248,200.0,200 -1249,111.0,111 -1250,78.0,78 -1251,200.0,200 -1252,200.0,200 -1253,172.0,172 -1254,200.0,200 -1255,105.0,105 -1256,181.0,181 -1257,200.0,200 -1258,83.0,83 -1259,200.0,200 -1260,176.0,176 -1261,200.0,200 -1262,147.0,147 -1263,165.0,165 -1264,167.0,167 -1265,183.0,183 -1266,117.0,117 -1267,200.0,200 -1268,200.0,200 -1269,171.0,171 -1270,20.0,20 -1271,200.0,200 -1272,200.0,200 -1273,200.0,200 -1274,109.0,109 -1275,142.0,142 -1276,117.0,117 -1277,200.0,200 -1278,176.0,176 -1279,200.0,200 -1280,101.0,101 -1281,200.0,200 -1282,130.0,130 -1283,200.0,200 -1284,111.0,111 -1285,124.0,124 -1286,178.0,178 -1287,200.0,200 -1288,184.0,184 -1289,200.0,200 -1290,200.0,200 -1291,200.0,200 -1292,200.0,200 -1293,130.0,130 -1294,200.0,200 -1295,134.0,134 -1296,195.0,195 -1297,200.0,200 -1298,62.0,62 -1299,200.0,200 -1300,200.0,200 -1301,165.0,165 -1302,190.0,190 -1303,200.0,200 -1304,200.0,200 -1305,168.0,168 -1306,200.0,200 -1307,64.0,64 -1308,122.0,122 -1309,200.0,200 -1310,134.0,134 -1311,200.0,200 -1312,200.0,200 -1313,200.0,200 -1314,150.0,150 -1315,187.0,187 -1316,130.0,130 -1317,140.0,140 -1318,157.0,157 -1319,200.0,200 -1320,149.0,149 -1321,200.0,200 -1322,58.0,58 -1323,84.0,84 -1324,140.0,140 -1325,139.0,139 -1326,117.0,117 -1327,175.0,175 -1328,135.0,135 -1329,169.0,169 -1330,200.0,200 -1331,143.0,143 -1332,127.0,127 -1333,127.0,127 -1334,148.0,148 -1335,200.0,200 -1336,136.0,136 -1337,200.0,200 -1338,200.0,200 -1339,175.0,175 -1340,102.0,102 -1341,200.0,200 -1342,97.0,97 -1343,120.0,120 -1344,59.0,59 -1345,200.0,200 -1346,200.0,200 -1347,104.0,104 -1348,128.0,128 -1349,200.0,200 -1350,195.0,195 -1351,96.0,96 -1352,196.0,196 -1353,200.0,200 -1354,58.0,58 -1355,200.0,200 -1356,200.0,200 -1357,114.0,114 -1358,104.0,104 -1359,200.0,200 -1360,179.0,179 -1361,200.0,200 -1362,200.0,200 -1363,140.0,140 -1364,138.0,138 -1365,57.0,57 -1366,165.0,165 -1367,174.0,174 -1368,199.0,199 -1369,110.0,110 -1370,200.0,200 -1371,154.0,154 -1372,200.0,200 -1373,78.0,78 -1374,200.0,200 -1375,185.0,185 -1376,167.0,167 -1377,161.0,161 -1378,155.0,155 -1379,117.0,117 -1380,128.0,128 -1381,94.0,94 -1382,200.0,200 -1383,121.0,121 -1384,61.0,61 -1385,21.0,21 -1386,105.0,105 -1387,185.0,185 -1388,200.0,200 -1389,124.0,124 -1390,200.0,200 -1391,133.0,133 -1392,200.0,200 -1393,153.0,153 -1394,200.0,200 -1395,200.0,200 -1396,152.0,152 -1397,146.0,146 -1398,200.0,200 -1399,183.0,183 -1400,195.0,195 -1401,172.0,172 -1402,151.0,151 -1403,122.0,122 -1404,200.0,200 -1405,200.0,200 -1406,200.0,200 -1407,200.0,200 -1408,130.0,130 -1409,148.0,148 -1410,200.0,200 -1411,200.0,200 -1412,200.0,200 -1413,157.0,157 -1414,136.0,136 -1415,115.0,115 -1416,200.0,200 -1417,105.0,105 -1418,124.0,124 -1419,144.0,144 -1420,34.0,34 -1421,151.0,151 -1422,101.0,101 -1423,64.0,64 -1424,200.0,200 -1425,100.0,100 -1426,54.0,54 -1427,132.0,132 -1428,200.0,200 -1429,131.0,131 -1430,51.0,51 -1431,123.0,123 -1432,99.0,99 -1433,200.0,200 -1434,200.0,200 -1435,144.0,144 -1436,166.0,166 -1437,122.0,122 -1438,147.0,147 -1439,200.0,200 -1440,103.0,103 -1441,164.0,164 -1442,76.0,76 -1443,159.0,159 -1444,152.0,152 -1445,200.0,200 -1446,129.0,129 -1447,124.0,124 -1448,40.0,40 -1449,200.0,200 -1450,117.0,117 -1451,175.0,175 -1452,51.0,51 -1453,101.0,101 -1454,117.0,117 -1455,179.0,179 -1456,44.0,44 -1457,190.0,190 -1458,135.0,135 -1459,183.0,183 -1460,118.0,118 -1461,200.0,200 -1462,109.0,109 -1463,86.0,86 -1464,147.0,147 -1465,200.0,200 -1466,124.0,124 -1467,128.0,128 -1468,156.0,156 -1469,200.0,200 -1470,167.0,167 -1471,197.0,197 -1472,75.0,75 -1473,168.0,168 -1474,114.0,114 -1475,153.0,153 -1476,146.0,146 -1477,188.0,188 -1478,144.0,144 -1479,200.0,200 -1480,51.0,51 -1481,35.0,35 -1482,152.0,152 -1483,161.0,161 -1484,114.0,114 -1485,200.0,200 -1486,161.0,161 -1487,200.0,200 -1488,93.0,93 -1489,116.0,116 -1490,152.0,152 -1491,200.0,200 -1492,200.0,200 -1493,200.0,200 -1494,86.0,86 -1495,200.0,200 -1496,178.0,178 -1497,200.0,200 -1498,200.0,200 -1499,154.0,154 -1500,135.0,135 -1501,200.0,200 -1502,146.0,146 -1503,78.0,78 -1504,115.0,115 -1505,189.0,189 -1506,133.0,133 -1507,123.0,123 -1508,158.0,158 -1509,200.0,200 -1510,200.0,200 -1511,200.0,200 -1512,200.0,200 -1513,200.0,200 -1514,200.0,200 -1515,200.0,200 -1516,119.0,119 -1517,162.0,162 -1518,200.0,200 -1519,114.0,114 -1520,200.0,200 -1521,128.0,128 -1522,200.0,200 -1523,200.0,200 -1524,130.0,130 -1525,65.0,65 -1526,200.0,200 -1527,200.0,200 -1528,200.0,200 -1529,188.0,188 -1530,159.0,159 -1531,200.0,200 -1532,200.0,200 -1533,200.0,200 -1534,147.0,147 -1535,180.0,180 -1536,152.0,152 -1537,178.0,178 -1538,131.0,131 -1539,118.0,118 -1540,153.0,153 -1541,197.0,197 -1542,200.0,200 -1543,200.0,200 -1544,178.0,178 -1545,67.0,67 -1546,137.0,137 -1547,51.0,51 -1548,160.0,160 -1549,200.0,200 -1550,124.0,124 -1551,109.0,109 -1552,181.0,181 -1553,182.0,182 -1554,136.0,136 -1555,91.0,91 -1556,159.0,159 -1557,192.0,192 -1558,106.0,106 -1559,200.0,200 -1560,169.0,169 -1561,167.0,167 -1562,141.0,141 -1563,127.0,127 -1564,71.0,71 -1565,134.0,134 -1566,200.0,200 -1567,115.0,115 -1568,99.0,99 -1569,184.0,184 -1570,200.0,200 -1571,133.0,133 -1572,153.0,153 -1573,200.0,200 -1574,194.0,194 -1575,169.0,169 -1576,113.0,113 -1577,147.0,147 -1578,140.0,140 -1579,200.0,200 -1580,113.0,113 -1581,181.0,181 -1582,200.0,200 -1583,182.0,182 -1584,185.0,185 -1585,197.0,197 -1586,200.0,200 -1587,151.0,151 -1588,49.0,49 -1589,137.0,137 -1590,166.0,166 -1591,149.0,149 -1592,126.0,126 -1593,73.0,73 -1594,127.0,127 -1595,104.0,104 -1596,65.0,65 -1597,63.0,63 -1598,126.0,126 -1599,181.0,181 -1600,132.0,132 -1601,89.0,89 -1602,130.0,130 -1603,150.0,150 -1604,100.0,100 -1605,139.0,139 -1606,119.0,119 -1607,48.0,48 -1608,80.0,80 -1609,105.0,105 -1610,85.0,85 -1611,200.0,200 -1612,142.0,142 -1613,95.0,95 -1614,50.0,50 -1615,51.0,51 -1616,124.0,124 -1617,47.0,47 -1618,159.0,159 -1619,154.0,154 -1620,200.0,200 -1621,88.0,88 -1622,65.0,65 -1623,111.0,111 -1624,99.0,99 -1625,120.0,120 -1626,127.0,127 -1627,43.0,43 -1628,80.0,80 -1629,163.0,163 -1630,90.0,90 -1631,154.0,154 -1632,127.0,127 -1633,39.0,39 -1634,200.0,200 -1635,161.0,161 -1636,119.0,119 -1637,156.0,156 -1638,200.0,200 -1639,200.0,200 -1640,41.0,41 -1641,200.0,200 -1642,136.0,136 -1643,157.0,157 -1644,142.0,142 -1645,125.0,125 -1646,155.0,155 -1647,139.0,139 -1648,122.0,122 -1649,116.0,116 -1650,200.0,200 -1651,144.0,144 -1652,170.0,170 -1653,200.0,200 -1654,103.0,103 -1655,105.0,105 -1656,193.0,193 -1657,122.0,122 -1658,200.0,200 -1659,191.0,191 -1660,200.0,200 -1661,200.0,200 -1662,200.0,200 -1663,200.0,200 -1664,200.0,200 -1665,200.0,200 -1666,200.0,200 -1667,64.0,64 -1668,200.0,200 -1669,121.0,121 -1670,200.0,200 -1671,171.0,171 -1672,200.0,200 -1673,130.0,130 -1674,200.0,200 -1675,200.0,200 -1676,188.0,188 -1677,200.0,200 -1678,200.0,200 -1679,200.0,200 -1680,181.0,181 -1681,200.0,200 -1682,200.0,200 -1683,135.0,135 -1684,200.0,200 -1685,114.0,114 -1686,189.0,189 -1687,200.0,200 -1688,200.0,200 -1689,200.0,200 -1690,184.0,184 -1691,200.0,200 -1692,200.0,200 -1693,55.0,55 -1694,153.0,153 -1695,200.0,200 -1696,200.0,200 -1697,125.0,125 -1698,177.0,177 -1699,154.0,154 -1700,53.0,53 -1701,112.0,112 -1702,184.0,184 -1703,200.0,200 -1704,200.0,200 -1705,137.0,137 -1706,72.0,72 -1707,200.0,200 -1708,200.0,200 -1709,200.0,200 -1710,121.0,121 -1711,200.0,200 -1712,200.0,200 -1713,142.0,142 -1714,200.0,200 -1715,200.0,200 -1716,169.0,169 -1717,200.0,200 -1718,200.0,200 -1719,196.0,196 -1720,135.0,135 -1721,200.0,200 -1722,200.0,200 -1723,200.0,200 -1724,96.0,96 -1725,200.0,200 -1726,200.0,200 -1727,200.0,200 -1728,200.0,200 -1729,138.0,138 -1730,200.0,200 -1731,139.0,139 -1732,200.0,200 -1733,190.0,190 -1734,200.0,200 -1735,200.0,200 -1736,138.0,138 -1737,114.0,114 -1738,159.0,159 -1739,120.0,120 -1740,186.0,186 -1741,200.0,200 -1742,183.0,183 -1743,200.0,200 -1744,200.0,200 -1745,200.0,200 -1746,99.0,99 -1747,200.0,200 -1748,100.0,100 -1749,187.0,187 -1750,106.0,106 -1751,200.0,200 -1752,200.0,200 -1753,200.0,200 -1754,52.0,52 -1755,197.0,197 -1756,165.0,165 -1757,200.0,200 -1758,200.0,200 -1759,92.0,92 -1760,200.0,200 -1761,200.0,200 -1762,70.0,70 -1763,165.0,165 -1764,192.0,192 -1765,200.0,200 -1766,200.0,200 -1767,87.0,87 -1768,150.0,150 -1769,149.0,149 -1770,79.0,79 -1771,200.0,200 -1772,200.0,200 -1773,117.0,117 -1774,200.0,200 -1775,135.0,135 -1776,200.0,200 -1777,130.0,130 -1778,200.0,200 -1779,200.0,200 -1780,200.0,200 -1781,200.0,200 -1782,200.0,200 -1783,200.0,200 -1784,200.0,200 -1785,200.0,200 -1786,200.0,200 -1787,200.0,200 -1788,140.0,140 -1789,200.0,200 -1790,200.0,200 -1791,42.0,42 -1792,198.0,198 -1793,200.0,200 -1794,200.0,200 -1795,85.0,85 -1796,164.0,164 -1797,99.0,99 -1798,151.0,151 -1799,200.0,200 -1800,200.0,200 -1801,199.0,199 -1802,200.0,200 -1803,190.0,190 -1804,114.0,114 -1805,200.0,200 -1806,200.0,200 -1807,161.0,161 -1808,200.0,200 -1809,187.0,187 -1810,145.0,145 -1811,200.0,200 -1812,200.0,200 -1813,200.0,200 -1814,96.0,96 -1815,163.0,163 -1816,160.0,160 -1817,200.0,200 -1818,200.0,200 -1819,50.0,50 -1820,200.0,200 -1821,102.0,102 -1822,200.0,200 -1823,200.0,200 -1824,200.0,200 -1825,200.0,200 -1826,109.0,109 -1827,200.0,200 -1828,129.0,129 -1829,200.0,200 -1830,171.0,171 -1831,183.0,183 -1832,106.0,106 -1833,200.0,200 -1834,136.0,136 -1835,100.0,100 -1836,200.0,200 -1837,188.0,188 -1838,200.0,200 -1839,200.0,200 -1840,162.0,162 -1841,200.0,200 -1842,200.0,200 -1843,177.0,177 -1844,200.0,200 -1845,200.0,200 -1846,200.0,200 -1847,200.0,200 -1848,166.0,166 -1849,200.0,200 -1850,53.0,53 -1851,200.0,200 -1852,200.0,200 -1853,153.0,153 -1854,190.0,190 -1855,200.0,200 -1856,200.0,200 -1857,200.0,200 -1858,200.0,200 -1859,136.0,136 -1860,200.0,200 -1861,143.0,143 -1862,45.0,45 -1863,129.0,129 -1864,200.0,200 -1865,200.0,200 -1866,200.0,200 -1867,200.0,200 -1868,60.0,60 -1869,150.0,150 -1870,174.0,174 -1871,157.0,157 -1872,198.0,198 -1873,200.0,200 -1874,91.0,91 -1875,200.0,200 -1876,112.0,112 -1877,159.0,159 -1878,186.0,186 -1879,200.0,200 -1880,82.0,82 -1881,192.0,192 -1882,147.0,147 -1883,200.0,200 -1884,200.0,200 -1885,174.0,174 -1886,181.0,181 -1887,200.0,200 -1888,74.0,74 -1889,200.0,200 -1890,200.0,200 -1891,200.0,200 -1892,157.0,157 -1893,200.0,200 -1894,200.0,200 -1895,180.0,180 -1896,170.0,170 -1897,200.0,200 -1898,135.0,135 -1899,200.0,200 -1900,175.0,175 -1901,200.0,200 -1902,200.0,200 -1903,118.0,118 -1904,147.0,147 -1905,44.0,44 -1906,200.0,200 -1907,58.0,58 -1908,185.0,185 -1909,200.0,200 -1910,200.0,200 -1911,200.0,200 -1912,78.0,78 -1913,190.0,190 -1914,177.0,177 -1915,112.0,112 -1916,200.0,200 -1917,142.0,142 -1918,200.0,200 -1919,92.0,92 -1920,172.0,172 -1921,200.0,200 -1922,178.0,178 -1923,200.0,200 -1924,200.0,200 -1925,138.0,138 -1926,100.0,100 -1927,200.0,200 -1928,95.0,95 -1929,200.0,200 -1930,200.0,200 -1931,129.0,129 -1932,154.0,154 -1933,200.0,200 -1934,200.0,200 -1935,133.0,133 -1936,152.0,152 -1937,133.0,133 -1938,200.0,200 -1939,200.0,200 -1940,200.0,200 -1941,200.0,200 -1942,200.0,200 -1943,167.0,167 -1944,179.0,179 -1945,164.0,164 -1946,187.0,187 -1947,156.0,156 -1948,200.0,200 -1949,200.0,200 -1950,130.0,130 -1951,200.0,200 -1952,200.0,200 -1953,200.0,200 -1954,200.0,200 -1955,65.0,65 -1956,200.0,200 -1957,148.0,148 -1958,200.0,200 -1959,200.0,200 -1960,200.0,200 -1961,168.0,168 -1962,164.0,164 -1963,200.0,200 -1964,200.0,200 -1965,103.0,103 -1966,200.0,200 -1967,173.0,173 -1968,200.0,200 -1969,146.0,146 -1970,197.0,197 -1971,123.0,123 -1972,162.0,162 -1973,200.0,200 -1974,162.0,162 -1975,82.0,82 -1976,157.0,157 -1977,138.0,138 -1978,37.0,37 -1979,200.0,200 -1980,194.0,194 -1981,200.0,200 -1982,104.0,104 -1983,198.0,198 -1984,200.0,200 -1985,200.0,200 -1986,154.0,154 -1987,200.0,200 -1988,200.0,200 -1989,158.0,158 -1990,200.0,200 -1991,142.0,142 -1992,185.0,185 -1993,69.0,69 -1994,200.0,200 -1995,144.0,144 -1996,164.0,164 -1997,189.0,189 -1998,200.0,200 -1999,141.0,141 diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/models/actor_checkpoint.pt b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/models/actor_checkpoint.pt deleted file mode 100644 index 20d78c0..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/models/actor_checkpoint.pt and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/models/critic_checkpoint.pt b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/models/critic_checkpoint.pt deleted file mode 100644 index c35547d..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/models/critic_checkpoint.pt and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/params.json b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/params.json deleted file mode 100644 index 010058e..0000000 --- a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/params.json +++ /dev/null @@ -1 +0,0 @@ -{"algo_name": "A2C", "env_name": "CartPole-v0", "train_eps": 1600, "test_eps": 20, "ep_max_steps": 100000, "gamma": 0.99, "actor_lr": 0.0003, "critic_lr": 0.001, "actor_hidden_dim": 256, "critic_hidden_dim": 256, "device": "cpu", "seed": 10, "show_fig": false, "save_fig": true, "result_path": "/Users/jj/Desktop/rl-tutorials/codes/A2C/outputs/CartPole-v0/20220829-143327/results/", "model_path": "/Users/jj/Desktop/rl-tutorials/codes/A2C/outputs/CartPole-v0/20220829-143327/models/", "n_states": 4, "n_actions": 2} \ No newline at end of file diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/testing_curve.png b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/testing_curve.png deleted file mode 100644 index 96a9a22..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/testing_results.csv b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/testing_results.csv deleted file mode 100644 index ebf3893..0000000 --- a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/testing_results.csv +++ /dev/null @@ -1,21 +0,0 @@ -episodes,rewards,steps -0,177.0,177 -1,180.0,180 -2,200.0,200 -3,200.0,200 -4,167.0,167 -5,124.0,124 -6,128.0,128 -7,200.0,200 -8,200.0,200 -9,200.0,200 -10,186.0,186 -11,187.0,187 -12,200.0,200 -13,176.0,176 -14,200.0,200 -15,200.0,200 -16,200.0,200 -17,200.0,200 -18,185.0,185 -19,180.0,180 diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/training_curve.png b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/training_curve.png deleted file mode 100644 index 860a49c..0000000 Binary files a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/training_curve.png and /dev/null differ diff --git a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/training_results.csv b/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/training_results.csv deleted file mode 100644 index f05699c..0000000 --- a/projects/codes/A2C/outputs/CartPole-v0/20220829-143327/results/training_results.csv +++ /dev/null @@ -1,1601 +0,0 @@ -episodes,rewards,steps -0,16.0,16 -1,14.0,14 -2,18.0,18 -3,31.0,31 -4,23.0,23 -5,43.0,43 -6,14.0,14 -7,20.0,20 -8,24.0,24 -9,14.0,14 -10,12.0,12 -11,16.0,16 -12,17.0,17 -13,13.0,13 -14,78.0,78 -15,36.0,36 -16,9.0,9 -17,19.0,19 -18,18.0,18 -19,20.0,20 -20,33.0,33 -21,37.0,37 -22,15.0,15 -23,24.0,24 -24,32.0,32 -25,19.0,19 -26,65.0,65 -27,13.0,13 -28,26.0,26 -29,27.0,27 -30,15.0,15 -31,10.0,10 -32,16.0,16 -33,30.0,30 -34,42.0,42 -35,30.0,30 -36,35.0,35 -37,21.0,21 -38,36.0,36 -39,18.0,18 -40,81.0,81 -41,12.0,12 -42,21.0,21 -43,32.0,32 -44,39.0,39 -45,10.0,10 -46,13.0,13 -47,35.0,35 -48,22.0,22 -49,20.0,20 -50,67.0,67 -51,28.0,28 -52,13.0,13 -53,14.0,14 -54,13.0,13 -55,26.0,26 -56,12.0,12 -57,17.0,17 -58,41.0,41 -59,14.0,14 -60,68.0,68 -61,12.0,12 -62,20.0,20 -63,19.0,19 -64,31.0,31 -65,31.0,31 -66,34.0,34 -67,24.0,24 -68,31.0,31 -69,37.0,37 -70,49.0,49 -71,15.0,15 -72,97.0,97 -73,18.0,18 -74,20.0,20 -75,31.0,31 -76,68.0,68 -77,21.0,21 -78,19.0,19 -79,19.0,19 -80,19.0,19 -81,14.0,14 -82,17.0,17 -83,35.0,35 -84,25.0,25 -85,59.0,59 -86,29.0,29 -87,35.0,35 -88,73.0,73 -89,26.0,26 -90,81.0,81 -91,20.0,20 -92,78.0,78 -93,26.0,26 -94,43.0,43 -95,25.0,25 -96,24.0,24 -97,14.0,14 -98,27.0,27 -99,16.0,16 -100,68.0,68 -101,57.0,57 -102,31.0,31 -103,46.0,46 -104,17.0,17 -105,16.0,16 -106,21.0,21 -107,25.0,25 -108,13.0,13 -109,50.0,50 -110,12.0,12 -111,34.0,34 -112,16.0,16 -113,34.0,34 -114,19.0,19 -115,38.0,38 -116,20.0,20 -117,42.0,42 -118,28.0,28 -119,53.0,53 -120,43.0,43 -121,37.0,37 -122,13.0,13 -123,29.0,29 -124,17.0,17 -125,23.0,23 -126,22.0,22 -127,21.0,21 -128,62.0,62 -129,52.0,52 -130,32.0,32 -131,37.0,37 -132,38.0,38 -133,28.0,28 -134,33.0,33 -135,33.0,33 -136,35.0,35 -137,43.0,43 -138,41.0,41 -139,18.0,18 -140,30.0,30 -141,48.0,48 -142,50.0,50 -143,34.0,34 -144,86.0,86 -145,21.0,21 -146,29.0,29 -147,29.0,29 -148,24.0,24 -149,88.0,88 -150,28.0,28 -151,19.0,19 -152,35.0,35 -153,24.0,24 -154,11.0,11 -155,49.0,49 -156,30.0,30 -157,44.0,44 -158,26.0,26 -159,19.0,19 -160,12.0,12 -161,65.0,65 -162,18.0,18 -163,11.0,11 -164,38.0,38 -165,28.0,28 -166,17.0,17 -167,51.0,51 -168,18.0,18 -169,39.0,39 -170,22.0,22 -171,26.0,26 -172,33.0,33 -173,35.0,35 -174,60.0,60 -175,12.0,12 -176,19.0,19 -177,62.0,62 -178,79.0,79 -179,36.0,36 -180,31.0,31 -181,23.0,23 -182,23.0,23 -183,40.0,40 -184,19.0,19 -185,18.0,18 -186,18.0,18 -187,23.0,23 -188,43.0,43 -189,45.0,45 -190,28.0,28 -191,61.0,61 -192,50.0,50 -193,40.0,40 -194,9.0,9 -195,56.0,56 -196,43.0,43 -197,43.0,43 -198,18.0,18 -199,43.0,43 -200,26.0,26 -201,44.0,44 -202,35.0,35 -203,25.0,25 -204,31.0,31 -205,26.0,26 -206,40.0,40 -207,36.0,36 -208,50.0,50 -209,25.0,25 -210,29.0,29 -211,11.0,11 -212,23.0,23 -213,23.0,23 -214,36.0,36 -215,39.0,39 -216,45.0,45 -217,14.0,14 -218,46.0,46 -219,62.0,62 -220,15.0,15 -221,19.0,19 -222,28.0,28 -223,39.0,39 -224,14.0,14 -225,25.0,25 -226,35.0,35 -227,16.0,16 -228,22.0,22 -229,41.0,41 -230,21.0,21 -231,22.0,22 -232,37.0,37 -233,32.0,32 -234,18.0,18 -235,23.0,23 -236,23.0,23 -237,16.0,16 -238,38.0,38 -239,25.0,25 -240,37.0,37 -241,13.0,13 -242,30.0,30 -243,27.0,27 -244,27.0,27 -245,23.0,23 -246,62.0,62 -247,31.0,31 -248,37.0,37 -249,26.0,26 -250,77.0,77 -251,15.0,15 -252,25.0,25 -253,20.0,20 -254,27.0,27 -255,42.0,42 -256,41.0,41 -257,34.0,34 -258,23.0,23 -259,37.0,37 -260,47.0,47 -261,22.0,22 -262,34.0,34 -263,10.0,10 -264,37.0,37 -265,29.0,29 -266,49.0,49 -267,67.0,67 -268,15.0,15 -269,81.0,81 -270,95.0,95 -271,54.0,54 -272,19.0,19 -273,31.0,31 -274,54.0,54 -275,46.0,46 -276,21.0,21 -277,22.0,22 -278,58.0,58 -279,58.0,58 -280,37.0,37 -281,37.0,37 -282,25.0,25 -283,20.0,20 -284,46.0,46 -285,80.0,80 -286,25.0,25 -287,18.0,18 -288,18.0,18 -289,18.0,18 -290,37.0,37 -291,20.0,20 -292,62.0,62 -293,22.0,22 -294,23.0,23 -295,28.0,28 -296,38.0,38 -297,15.0,15 -298,17.0,17 -299,20.0,20 -300,20.0,20 -301,18.0,18 -302,77.0,77 -303,54.0,54 -304,95.0,95 -305,25.0,25 -306,79.0,79 -307,116.0,116 -308,52.0,52 -309,58.0,58 -310,15.0,15 -311,60.0,60 -312,97.0,97 -313,61.0,61 -314,18.0,18 -315,69.0,69 -316,18.0,18 -317,20.0,20 -318,19.0,19 -319,16.0,16 -320,21.0,21 -321,12.0,12 -322,30.0,30 -323,51.0,51 -324,37.0,37 -325,28.0,28 -326,29.0,29 -327,66.0,66 -328,56.0,56 -329,79.0,79 -330,56.0,56 -331,70.0,70 -332,33.0,33 -333,54.0,54 -334,35.0,35 -335,18.0,18 -336,141.0,141 -337,38.0,38 -338,18.0,18 -339,34.0,34 -340,20.0,20 -341,95.0,95 -342,29.0,29 -343,40.0,40 -344,20.0,20 -345,14.0,14 -346,83.0,83 -347,72.0,72 -348,88.0,88 -349,41.0,41 -350,103.0,103 -351,85.0,85 -352,14.0,14 -353,51.0,51 -354,68.0,68 -355,102.0,102 -356,61.0,61 -357,22.0,22 -358,22.0,22 -359,15.0,15 -360,23.0,23 -361,35.0,35 -362,72.0,72 -363,32.0,32 -364,107.0,107 -365,34.0,34 -366,28.0,28 -367,99.0,99 -368,140.0,140 -369,40.0,40 -370,24.0,24 -371,157.0,157 -372,33.0,33 -373,35.0,35 -374,18.0,18 -375,21.0,21 -376,23.0,23 -377,67.0,67 -378,112.0,112 -379,21.0,21 -380,38.0,38 -381,12.0,12 -382,23.0,23 -383,31.0,31 -384,36.0,36 -385,20.0,20 -386,82.0,82 -387,20.0,20 -388,32.0,32 -389,28.0,28 -390,26.0,26 -391,26.0,26 -392,46.0,46 -393,35.0,35 -394,32.0,32 -395,67.0,67 -396,30.0,30 -397,36.0,36 -398,67.0,67 -399,51.0,51 -400,21.0,21 -401,28.0,28 -402,46.0,46 -403,29.0,29 -404,30.0,30 -405,22.0,22 -406,24.0,24 -407,78.0,78 -408,28.0,28 -409,41.0,41 -410,38.0,38 -411,56.0,56 -412,19.0,19 -413,38.0,38 -414,51.0,51 -415,33.0,33 -416,40.0,40 -417,35.0,35 -418,59.0,59 -419,138.0,138 -420,18.0,18 -421,10.0,10 -422,25.0,25 -423,104.0,104 -424,127.0,127 -425,44.0,44 -426,35.0,35 -427,62.0,62 -428,108.0,108 -429,39.0,39 -430,15.0,15 -431,73.0,73 -432,24.0,24 -433,23.0,23 -434,35.0,35 -435,14.0,14 -436,47.0,47 -437,112.0,112 -438,79.0,79 -439,99.0,99 -440,66.0,66 -441,64.0,64 -442,63.0,63 -443,28.0,28 -444,116.0,116 -445,94.0,94 -446,91.0,91 -447,60.0,60 -448,22.0,22 -449,68.0,68 -450,22.0,22 -451,34.0,34 -452,23.0,23 -453,117.0,117 -454,26.0,26 -455,30.0,30 -456,31.0,31 -457,50.0,50 -458,56.0,56 -459,81.0,81 -460,43.0,43 -461,49.0,49 -462,62.0,62 -463,64.0,64 -464,16.0,16 -465,37.0,37 -466,103.0,103 -467,66.0,66 -468,25.0,25 -469,50.0,50 -470,118.0,118 -471,42.0,42 -472,69.0,69 -473,55.0,55 -474,41.0,41 -475,25.0,25 -476,114.0,114 -477,27.0,27 -478,27.0,27 -479,61.0,61 -480,61.0,61 -481,66.0,66 -482,73.0,73 -483,35.0,35 -484,47.0,47 -485,77.0,77 -486,34.0,34 -487,16.0,16 -488,22.0,22 -489,47.0,47 -490,72.0,72 -491,76.0,76 -492,74.0,74 -493,36.0,36 -494,47.0,47 -495,25.0,25 -496,22.0,22 -497,20.0,20 -498,40.0,40 -499,44.0,44 -500,41.0,41 -501,42.0,42 -502,112.0,112 -503,64.0,64 -504,95.0,95 -505,112.0,112 -506,117.0,117 -507,84.0,84 -508,79.0,79 -509,129.0,129 -510,139.0,139 -511,41.0,41 -512,82.0,82 -513,54.0,54 -514,69.0,69 -515,44.0,44 -516,31.0,31 -517,64.0,64 -518,41.0,41 -519,100.0,100 -520,86.0,86 -521,44.0,44 -522,38.0,38 -523,36.0,36 -524,41.0,41 -525,22.0,22 -526,51.0,51 -527,24.0,24 -528,47.0,47 -529,79.0,79 -530,125.0,125 -531,50.0,50 -532,35.0,35 -533,48.0,48 -534,85.0,85 -535,58.0,58 -536,101.0,101 -537,200.0,200 -538,79.0,79 -539,159.0,159 -540,71.0,71 -541,71.0,71 -542,77.0,77 -543,78.0,78 -544,46.0,46 -545,49.0,49 -546,74.0,74 -547,71.0,71 -548,106.0,106 -549,36.0,36 -550,33.0,33 -551,160.0,160 -552,53.0,53 -553,54.0,54 -554,27.0,27 -555,55.0,55 -556,174.0,174 -557,33.0,33 -558,61.0,61 -559,118.0,118 -560,128.0,128 -561,148.0,148 -562,97.0,97 -563,63.0,63 -564,44.0,44 -565,110.0,110 -566,156.0,156 -567,50.0,50 -568,163.0,163 -569,126.0,126 -570,114.0,114 -571,78.0,78 -572,48.0,48 -573,59.0,59 -574,116.0,116 -575,46.0,46 -576,135.0,135 -577,71.0,71 -578,19.0,19 -579,43.0,43 -580,89.0,89 -581,97.0,97 -582,21.0,21 -583,120.0,120 -584,54.0,54 -585,24.0,24 -586,62.0,62 -587,78.0,78 -588,36.0,36 -589,71.0,71 -590,25.0,25 -591,71.0,71 -592,56.0,56 -593,78.0,78 -594,65.0,65 -595,200.0,200 -596,200.0,200 -597,167.0,167 -598,59.0,59 -599,73.0,73 -600,66.0,66 -601,35.0,35 -602,186.0,186 -603,140.0,140 -604,49.0,49 -605,134.0,134 -606,46.0,46 -607,149.0,149 -608,82.0,82 -609,119.0,119 -610,126.0,126 -611,52.0,52 -612,89.0,89 -613,200.0,200 -614,89.0,89 -615,93.0,93 -616,200.0,200 -617,39.0,39 -618,113.0,113 -619,67.0,67 -620,164.0,164 -621,120.0,120 -622,74.0,74 -623,153.0,153 -624,124.0,124 -625,41.0,41 -626,173.0,173 -627,48.0,48 -628,200.0,200 -629,58.0,58 -630,35.0,35 -631,45.0,45 -632,43.0,43 -633,157.0,157 -634,111.0,111 -635,98.0,98 -636,102.0,102 -637,124.0,124 -638,111.0,111 -639,42.0,42 -640,128.0,128 -641,183.0,183 -642,49.0,49 -643,64.0,64 -644,117.0,117 -645,150.0,150 -646,103.0,103 -647,115.0,115 -648,41.0,41 -649,200.0,200 -650,162.0,162 -651,105.0,105 -652,94.0,94 -653,55.0,55 -654,73.0,73 -655,65.0,65 -656,29.0,29 -657,148.0,148 -658,42.0,42 -659,17.0,17 -660,60.0,60 -661,59.0,59 -662,80.0,80 -663,41.0,41 -664,143.0,143 -665,200.0,200 -666,45.0,45 -667,95.0,95 -668,61.0,61 -669,63.0,63 -670,170.0,170 -671,150.0,150 -672,139.0,139 -673,44.0,44 -674,44.0,44 -675,47.0,47 -676,72.0,72 -677,129.0,129 -678,79.0,79 -679,128.0,128 -680,126.0,126 -681,65.0,65 -682,57.0,57 -683,58.0,58 -684,66.0,66 -685,89.0,89 -686,150.0,150 -687,97.0,97 -688,20.0,20 -689,58.0,58 -690,81.0,81 -691,54.0,54 -692,55.0,55 -693,197.0,197 -694,61.0,61 -695,157.0,157 -696,166.0,166 -697,79.0,79 -698,128.0,128 -699,200.0,200 -700,46.0,46 -701,140.0,140 -702,19.0,19 -703,144.0,144 -704,138.0,138 -705,46.0,46 -706,200.0,200 -707,61.0,61 -708,114.0,114 -709,100.0,100 -710,85.0,85 -711,200.0,200 -712,36.0,36 -713,142.0,142 -714,22.0,22 -715,82.0,82 -716,49.0,49 -717,139.0,139 -718,173.0,173 -719,47.0,47 -720,67.0,67 -721,197.0,197 -722,157.0,157 -723,149.0,149 -724,29.0,29 -725,85.0,85 -726,135.0,135 -727,157.0,157 -728,141.0,141 -729,165.0,165 -730,102.0,102 -731,192.0,192 -732,196.0,196 -733,183.0,183 -734,75.0,75 -735,41.0,41 -736,122.0,122 -737,200.0,200 -738,166.0,166 -739,109.0,109 -740,200.0,200 -741,200.0,200 -742,24.0,24 -743,20.0,20 -744,138.0,138 -745,122.0,122 -746,200.0,200 -747,156.0,156 -748,191.0,191 -749,91.0,91 -750,105.0,105 -751,145.0,145 -752,130.0,130 -753,150.0,150 -754,77.0,77 -755,137.0,137 -756,181.0,181 -757,200.0,200 -758,132.0,132 -759,200.0,200 -760,76.0,76 -761,63.0,63 -762,160.0,160 -763,28.0,28 -764,135.0,135 -765,43.0,43 -766,146.0,146 -767,179.0,179 -768,82.0,82 -769,126.0,126 -770,148.0,148 -771,110.0,110 -772,116.0,116 -773,55.0,55 -774,158.0,158 -775,155.0,155 -776,200.0,200 -777,153.0,153 -778,147.0,147 -779,54.0,54 -780,173.0,173 -781,44.0,44 -782,47.0,47 -783,200.0,200 -784,179.0,179 -785,194.0,194 -786,200.0,200 -787,141.0,141 -788,130.0,130 -789,133.0,133 -790,53.0,53 -791,124.0,124 -792,143.0,143 -793,58.0,58 -794,190.0,190 -795,130.0,130 -796,130.0,130 -797,200.0,200 -798,163.0,163 -799,200.0,200 -800,103.0,103 -801,200.0,200 -802,200.0,200 -803,18.0,18 -804,156.0,156 -805,165.0,165 -806,129.0,129 -807,33.0,33 -808,132.0,132 -809,200.0,200 -810,110.0,110 -811,93.0,93 -812,198.0,198 -813,200.0,200 -814,200.0,200 -815,182.0,182 -816,75.0,75 -817,200.0,200 -818,200.0,200 -819,200.0,200 -820,144.0,144 -821,118.0,118 -822,200.0,200 -823,60.0,60 -824,200.0,200 -825,134.0,134 -826,154.0,154 -827,116.0,116 -828,21.0,21 -829,200.0,200 -830,105.0,105 -831,158.0,158 -832,122.0,122 -833,88.0,88 -834,108.0,108 -835,112.0,112 -836,134.0,134 -837,165.0,165 -838,200.0,200 -839,138.0,138 -840,164.0,164 -841,200.0,200 -842,30.0,30 -843,181.0,181 -844,149.0,149 -845,102.0,102 -846,128.0,128 -847,74.0,74 -848,112.0,112 -849,80.0,80 -850,190.0,190 -851,35.0,35 -852,40.0,40 -853,121.0,121 -854,125.0,125 -855,99.0,99 -856,115.0,115 -857,171.0,171 -858,200.0,200 -859,50.0,50 -860,200.0,200 -861,143.0,143 -862,146.0,146 -863,47.0,47 -864,154.0,154 -865,48.0,48 -866,103.0,103 -867,200.0,200 -868,151.0,151 -869,46.0,46 -870,155.0,155 -871,40.0,40 -872,124.0,124 -873,41.0,41 -874,45.0,45 -875,158.0,158 -876,29.0,29 -877,200.0,200 -878,200.0,200 -879,151.0,151 -880,158.0,158 -881,200.0,200 -882,15.0,15 -883,180.0,180 -884,75.0,75 -885,196.0,196 -886,176.0,176 -887,67.0,67 -888,90.0,90 -889,161.0,161 -890,88.0,88 -891,200.0,200 -892,64.0,64 -893,111.0,111 -894,184.0,184 -895,189.0,189 -896,109.0,109 -897,167.0,167 -898,99.0,99 -899,180.0,180 -900,121.0,121 -901,126.0,126 -902,200.0,200 -903,200.0,200 -904,177.0,177 -905,107.0,107 -906,200.0,200 -907,133.0,133 -908,164.0,164 -909,200.0,200 -910,160.0,160 -911,120.0,120 -912,200.0,200 -913,65.0,65 -914,27.0,27 -915,200.0,200 -916,162.0,162 -917,25.0,25 -918,118.0,118 -919,56.0,56 -920,107.0,107 -921,200.0,200 -922,166.0,166 -923,69.0,69 -924,187.0,187 -925,126.0,126 -926,200.0,200 -927,49.0,49 -928,99.0,99 -929,200.0,200 -930,200.0,200 -931,153.0,153 -932,158.0,158 -933,200.0,200 -934,145.0,145 -935,126.0,126 -936,133.0,133 -937,81.0,81 -938,200.0,200 -939,57.0,57 -940,200.0,200 -941,131.0,131 -942,200.0,200 -943,200.0,200 -944,200.0,200 -945,171.0,171 -946,200.0,200 -947,200.0,200 -948,200.0,200 -949,176.0,176 -950,110.0,110 -951,158.0,158 -952,137.0,137 -953,103.0,103 -954,200.0,200 -955,200.0,200 -956,200.0,200 -957,190.0,190 -958,130.0,130 -959,139.0,139 -960,200.0,200 -961,172.0,172 -962,152.0,152 -963,154.0,154 -964,52.0,52 -965,194.0,194 -966,52.0,52 -967,169.0,169 -968,200.0,200 -969,176.0,176 -970,127.0,127 -971,157.0,157 -972,200.0,200 -973,134.0,134 -974,138.0,138 -975,133.0,133 -976,170.0,170 -977,159.0,159 -978,88.0,88 -979,141.0,141 -980,117.0,117 -981,157.0,157 -982,145.0,145 -983,200.0,200 -984,129.0,129 -985,155.0,155 -986,83.0,83 -987,152.0,152 -988,156.0,156 -989,200.0,200 -990,135.0,135 -991,75.0,75 -992,138.0,138 -993,83.0,83 -994,200.0,200 -995,128.0,128 -996,122.0,122 -997,200.0,200 -998,34.0,34 -999,161.0,161 -1000,143.0,143 -1001,200.0,200 -1002,103.0,103 -1003,168.0,168 -1004,200.0,200 -1005,200.0,200 -1006,167.0,167 -1007,200.0,200 -1008,76.0,76 -1009,101.0,101 -1010,153.0,153 -1011,113.0,113 -1012,109.0,109 -1013,188.0,188 -1014,122.0,122 -1015,181.0,181 -1016,166.0,166 -1017,189.0,189 -1018,200.0,200 -1019,187.0,187 -1020,116.0,116 -1021,200.0,200 -1022,108.0,108 -1023,18.0,18 -1024,158.0,158 -1025,200.0,200 -1026,43.0,43 -1027,200.0,200 -1028,199.0,199 -1029,200.0,200 -1030,133.0,133 -1031,171.0,171 -1032,200.0,200 -1033,200.0,200 -1034,200.0,200 -1035,156.0,156 -1036,52.0,52 -1037,200.0,200 -1038,121.0,121 -1039,188.0,188 -1040,167.0,167 -1041,200.0,200 -1042,124.0,124 -1043,102.0,102 -1044,161.0,161 -1045,200.0,200 -1046,200.0,200 -1047,135.0,135 -1048,200.0,200 -1049,80.0,80 -1050,200.0,200 -1051,66.0,66 -1052,200.0,200 -1053,200.0,200 -1054,112.0,112 -1055,195.0,195 -1056,200.0,200 -1057,170.0,170 -1058,194.0,194 -1059,200.0,200 -1060,200.0,200 -1061,59.0,59 -1062,75.0,75 -1063,200.0,200 -1064,200.0,200 -1065,97.0,97 -1066,171.0,171 -1067,30.0,30 -1068,200.0,200 -1069,101.0,101 -1070,124.0,124 -1071,136.0,136 -1072,184.0,184 -1073,149.0,149 -1074,137.0,137 -1075,167.0,167 -1076,136.0,136 -1077,200.0,200 -1078,139.0,139 -1079,85.0,85 -1080,137.0,137 -1081,161.0,161 -1082,81.0,81 -1083,200.0,200 -1084,200.0,200 -1085,200.0,200 -1086,200.0,200 -1087,87.0,87 -1088,174.0,174 -1089,200.0,200 -1090,128.0,128 -1091,200.0,200 -1092,200.0,200 -1093,200.0,200 -1094,120.0,120 -1095,200.0,200 -1096,131.0,131 -1097,200.0,200 -1098,200.0,200 -1099,200.0,200 -1100,146.0,146 -1101,200.0,200 -1102,200.0,200 -1103,200.0,200 -1104,80.0,80 -1105,200.0,200 -1106,172.0,172 -1107,143.0,143 -1108,200.0,200 -1109,200.0,200 -1110,181.0,181 -1111,189.0,189 -1112,133.0,133 -1113,200.0,200 -1114,111.0,111 -1115,200.0,200 -1116,200.0,200 -1117,200.0,200 -1118,192.0,192 -1119,200.0,200 -1120,200.0,200 -1121,200.0,200 -1122,144.0,144 -1123,27.0,27 -1124,200.0,200 -1125,198.0,198 -1126,186.0,186 -1127,80.0,80 -1128,200.0,200 -1129,169.0,169 -1130,48.0,48 -1131,198.0,198 -1132,162.0,162 -1133,58.0,58 -1134,200.0,200 -1135,200.0,200 -1136,189.0,189 -1137,200.0,200 -1138,117.0,117 -1139,200.0,200 -1140,200.0,200 -1141,150.0,150 -1142,163.0,163 -1143,161.0,161 -1144,200.0,200 -1145,113.0,113 -1146,181.0,181 -1147,193.0,193 -1148,98.0,98 -1149,200.0,200 -1150,22.0,22 -1151,125.0,125 -1152,200.0,200 -1153,200.0,200 -1154,200.0,200 -1155,67.0,67 -1156,186.0,186 -1157,189.0,189 -1158,186.0,186 -1159,156.0,156 -1160,200.0,200 -1161,200.0,200 -1162,116.0,116 -1163,77.0,77 -1164,148.0,148 -1165,111.0,111 -1166,68.0,68 -1167,140.0,140 -1168,114.0,114 -1169,200.0,200 -1170,173.0,173 -1171,97.0,97 -1172,166.0,166 -1173,154.0,154 -1174,200.0,200 -1175,200.0,200 -1176,129.0,129 -1177,111.0,111 -1178,200.0,200 -1179,85.0,85 -1180,71.0,71 -1181,200.0,200 -1182,158.0,158 -1183,130.0,130 -1184,161.0,161 -1185,188.0,188 -1186,124.0,124 -1187,190.0,190 -1188,157.0,157 -1189,188.0,188 -1190,194.0,194 -1191,173.0,173 -1192,123.0,123 -1193,200.0,200 -1194,123.0,123 -1195,200.0,200 -1196,200.0,200 -1197,114.0,114 -1198,45.0,45 -1199,144.0,144 -1200,107.0,107 -1201,184.0,184 -1202,121.0,121 -1203,200.0,200 -1204,50.0,50 -1205,123.0,123 -1206,73.0,73 -1207,142.0,142 -1208,38.0,38 -1209,129.0,129 -1210,123.0,123 -1211,149.0,149 -1212,97.0,97 -1213,40.0,40 -1214,177.0,177 -1215,200.0,200 -1216,166.0,166 -1217,106.0,106 -1218,114.0,114 -1219,53.0,53 -1220,162.0,162 -1221,181.0,181 -1222,128.0,128 -1223,155.0,155 -1224,180.0,180 -1225,139.0,139 -1226,99.0,99 -1227,95.0,95 -1228,159.0,159 -1229,30.0,30 -1230,67.0,67 -1231,127.0,127 -1232,33.0,33 -1233,80.0,80 -1234,200.0,200 -1235,200.0,200 -1236,200.0,200 -1237,117.0,117 -1238,128.0,128 -1239,47.0,47 -1240,134.0,134 -1241,129.0,129 -1242,135.0,135 -1243,200.0,200 -1244,200.0,200 -1245,101.0,101 -1246,35.0,35 -1247,73.0,73 -1248,95.0,95 -1249,125.0,125 -1250,200.0,200 -1251,155.0,155 -1252,48.0,48 -1253,200.0,200 -1254,153.0,153 -1255,173.0,173 -1256,128.0,128 -1257,200.0,200 -1258,200.0,200 -1259,196.0,196 -1260,50.0,50 -1261,193.0,193 -1262,200.0,200 -1263,200.0,200 -1264,200.0,200 -1265,200.0,200 -1266,179.0,179 -1267,180.0,180 -1268,200.0,200 -1269,200.0,200 -1270,200.0,200 -1271,120.0,120 -1272,200.0,200 -1273,60.0,60 -1274,99.0,99 -1275,178.0,178 -1276,157.0,157 -1277,200.0,200 -1278,177.0,177 -1279,200.0,200 -1280,200.0,200 -1281,200.0,200 -1282,200.0,200 -1283,200.0,200 -1284,200.0,200 -1285,200.0,200 -1286,97.0,97 -1287,167.0,167 -1288,183.0,183 -1289,200.0,200 -1290,61.0,61 -1291,192.0,192 -1292,200.0,200 -1293,137.0,137 -1294,200.0,200 -1295,200.0,200 -1296,200.0,200 -1297,200.0,200 -1298,200.0,200 -1299,200.0,200 -1300,103.0,103 -1301,142.0,142 -1302,200.0,200 -1303,47.0,47 -1304,189.0,189 -1305,41.0,41 -1306,200.0,200 -1307,200.0,200 -1308,132.0,132 -1309,154.0,154 -1310,95.0,95 -1311,200.0,200 -1312,200.0,200 -1313,200.0,200 -1314,71.0,71 -1315,200.0,200 -1316,170.0,170 -1317,121.0,121 -1318,200.0,200 -1319,127.0,127 -1320,200.0,200 -1321,120.0,120 -1322,200.0,200 -1323,200.0,200 -1324,161.0,161 -1325,37.0,37 -1326,200.0,200 -1327,200.0,200 -1328,200.0,200 -1329,49.0,49 -1330,118.0,118 -1331,200.0,200 -1332,167.0,167 -1333,200.0,200 -1334,99.0,99 -1335,137.0,137 -1336,200.0,200 -1337,41.0,41 -1338,200.0,200 -1339,200.0,200 -1340,97.0,97 -1341,34.0,34 -1342,40.0,40 -1343,197.0,197 -1344,51.0,51 -1345,200.0,200 -1346,156.0,156 -1347,200.0,200 -1348,75.0,75 -1349,118.0,118 -1350,200.0,200 -1351,73.0,73 -1352,200.0,200 -1353,133.0,133 -1354,200.0,200 -1355,200.0,200 -1356,162.0,162 -1357,37.0,37 -1358,130.0,130 -1359,123.0,123 -1360,200.0,200 -1361,99.0,99 -1362,200.0,200 -1363,46.0,46 -1364,200.0,200 -1365,190.0,190 -1366,34.0,34 -1367,37.0,37 -1368,200.0,200 -1369,200.0,200 -1370,131.0,131 -1371,200.0,200 -1372,200.0,200 -1373,158.0,158 -1374,175.0,175 -1375,134.0,134 -1376,100.0,100 -1377,200.0,200 -1378,200.0,200 -1379,123.0,123 -1380,200.0,200 -1381,200.0,200 -1382,200.0,200 -1383,116.0,116 -1384,200.0,200 -1385,88.0,88 -1386,200.0,200 -1387,200.0,200 -1388,147.0,147 -1389,200.0,200 -1390,200.0,200 -1391,84.0,84 -1392,200.0,200 -1393,184.0,184 -1394,200.0,200 -1395,179.0,179 -1396,200.0,200 -1397,200.0,200 -1398,130.0,130 -1399,29.0,29 -1400,200.0,200 -1401,200.0,200 -1402,200.0,200 -1403,200.0,200 -1404,195.0,195 -1405,118.0,118 -1406,200.0,200 -1407,200.0,200 -1408,200.0,200 -1409,154.0,154 -1410,185.0,185 -1411,200.0,200 -1412,152.0,152 -1413,200.0,200 -1414,200.0,200 -1415,200.0,200 -1416,200.0,200 -1417,31.0,31 -1418,200.0,200 -1419,134.0,134 -1420,172.0,172 -1421,112.0,112 -1422,153.0,153 -1423,199.0,199 -1424,200.0,200 -1425,200.0,200 -1426,200.0,200 -1427,200.0,200 -1428,166.0,166 -1429,200.0,200 -1430,200.0,200 -1431,199.0,199 -1432,195.0,195 -1433,174.0,174 -1434,46.0,46 -1435,174.0,174 -1436,23.0,23 -1437,157.0,157 -1438,200.0,200 -1439,170.0,170 -1440,92.0,92 -1441,200.0,200 -1442,200.0,200 -1443,72.0,72 -1444,200.0,200 -1445,200.0,200 -1446,200.0,200 -1447,118.0,118 -1448,119.0,119 -1449,109.0,109 -1450,101.0,101 -1451,32.0,32 -1452,197.0,197 -1453,154.0,154 -1454,138.0,138 -1455,141.0,141 -1456,141.0,141 -1457,200.0,200 -1458,90.0,90 -1459,200.0,200 -1460,122.0,122 -1461,144.0,144 -1462,155.0,155 -1463,200.0,200 -1464,160.0,160 -1465,129.0,129 -1466,200.0,200 -1467,112.0,112 -1468,132.0,132 -1469,144.0,144 -1470,184.0,184 -1471,200.0,200 -1472,26.0,26 -1473,200.0,200 -1474,26.0,26 -1475,128.0,128 -1476,200.0,200 -1477,173.0,173 -1478,145.0,145 -1479,128.0,128 -1480,118.0,118 -1481,50.0,50 -1482,184.0,184 -1483,166.0,166 -1484,142.0,142 -1485,104.0,104 -1486,180.0,180 -1487,200.0,200 -1488,200.0,200 -1489,200.0,200 -1490,123.0,123 -1491,200.0,200 -1492,140.0,140 -1493,200.0,200 -1494,200.0,200 -1495,200.0,200 -1496,200.0,200 -1497,117.0,117 -1498,13.0,13 -1499,200.0,200 -1500,127.0,127 -1501,200.0,200 -1502,200.0,200 -1503,200.0,200 -1504,200.0,200 -1505,200.0,200 -1506,200.0,200 -1507,77.0,77 -1508,152.0,152 -1509,38.0,38 -1510,125.0,125 -1511,154.0,154 -1512,142.0,142 -1513,120.0,120 -1514,200.0,200 -1515,191.0,191 -1516,21.0,21 -1517,101.0,101 -1518,191.0,191 -1519,170.0,170 -1520,200.0,200 -1521,30.0,30 -1522,191.0,191 -1523,200.0,200 -1524,200.0,200 -1525,200.0,200 -1526,135.0,135 -1527,200.0,200 -1528,185.0,185 -1529,123.0,123 -1530,156.0,156 -1531,200.0,200 -1532,140.0,140 -1533,200.0,200 -1534,136.0,136 -1535,139.0,139 -1536,200.0,200 -1537,169.0,169 -1538,200.0,200 -1539,200.0,200 -1540,103.0,103 -1541,91.0,91 -1542,200.0,200 -1543,200.0,200 -1544,65.0,65 -1545,200.0,200 -1546,169.0,169 -1547,59.0,59 -1548,175.0,175 -1549,200.0,200 -1550,200.0,200 -1551,189.0,189 -1552,200.0,200 -1553,200.0,200 -1554,151.0,151 -1555,108.0,108 -1556,146.0,146 -1557,200.0,200 -1558,198.0,198 -1559,119.0,119 -1560,105.0,105 -1561,175.0,175 -1562,200.0,200 -1563,136.0,136 -1564,200.0,200 -1565,86.0,86 -1566,200.0,200 -1567,200.0,200 -1568,200.0,200 -1569,124.0,124 -1570,200.0,200 -1571,122.0,122 -1572,200.0,200 -1573,200.0,200 -1574,47.0,47 -1575,200.0,200 -1576,194.0,194 -1577,200.0,200 -1578,121.0,121 -1579,200.0,200 -1580,200.0,200 -1581,190.0,190 -1582,200.0,200 -1583,200.0,200 -1584,200.0,200 -1585,145.0,145 -1586,121.0,121 -1587,198.0,198 -1588,200.0,200 -1589,200.0,200 -1590,130.0,130 -1591,185.0,185 -1592,193.0,193 -1593,200.0,200 -1594,200.0,200 -1595,200.0,200 -1596,200.0,200 -1597,168.0,168 -1598,200.0,200 -1599,200.0,200 diff --git a/projects/codes/A2C/task0.py b/projects/codes/A2C/task0.py new file mode 100644 index 0000000..4a3208a --- /dev/null +++ b/projects/codes/A2C/task0.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 01:19:43 +LastEditor: JiangJi +LastEditTime: 2022-11-01 01:21:06 +Discription: +''' +import sys,os +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path + +import gym +from common.utils import all_seed,merge_class_attrs +from common.launcher import Launcher +from common.memories import PGReplay +from common.models import ActorSoftmax,Critic +from envs.register import register_env +from a2c import A2C +from config.config import GeneralConfigA2C,AlgoConfigA2C + +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigA2C()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigA2C()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=True) # create env + if cfg.seed !=0: # set random seed + all_seed(env,seed = cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + models = {'Actor':ActorSoftmax(n_states,n_actions, hidden_dim = cfg.actor_hidden_dim),'Critic':Critic(n_states,1,hidden_dim=cfg.critic_hidden_dim)} + memories = {'ACMemory':PGReplay()} + agent = A2C(models,memories,cfg) + for k,v in models.items(): + logger.info(f"{k} model name: {type(v).__name__}") + for k,v in memories.items(): + logger.info(f"{k} memory name: {type(v).__name__}") + logger.info(f"agent name: {type(agent).__name__}") + return env,agent + def train_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + ep_entropy = 0 # entropy per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.sample_action(state) # sample action + next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions + agent.memory.push((agent.value,agent.log_prob,reward)) # save transitions + state = next_state # update state + ep_reward += reward + ep_entropy += agent.entropy + ep_step += 1 + if terminated: + break + agent.update(next_state,ep_entropy) # update agent + return agent,ep_reward,ep_step + def test_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.predict_action(state) # predict action + next_state, reward, terminated, truncated , info = env.step(action) + state = next_state + ep_reward += reward + ep_step += 1 + if terminated: + break + return agent,ep_reward,ep_step + # def train(self,cfg,env,agent,logger): + # logger.info("Start training!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.train_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 # step per episode + # ep_entropy = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # action = agent.sample_action(state) # sample action + # next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions + # agent.memory.push((agent.value,agent.log_prob,reward)) # save transitions + # state = next_state # update state + # ep_reward += reward + # ep_entropy += agent.entropy + # ep_step += 1 + # if terminated: + # break + # agent.update(next_state,ep_entropy) # update agent + # rewards.append(ep_reward) + # steps.append(ep_step) + # logger.info(f"Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step}") + # logger.info("Finish training!") + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + # def test(self,cfg,env,agent,logger): + # logger.info("Start testing!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.test_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # action = agent.predict_action(state) # predict action + # next_state, reward, terminated, truncated , info = env.step(action) + # state = next_state + # ep_reward += reward + # ep_step += 1 + # if terminated: + # break + # rewards.append(ep_reward) + # steps.append(ep_step) + # logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step}") + # logger.info("Finish testing!") + # env.close() + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + +if __name__ == "__main__": + main = Main() + main.run() + + + + diff --git a/projects/codes/A2C/task1.py b/projects/codes/A2C/task1.py new file mode 100644 index 0000000..ff7c86f --- /dev/null +++ b/projects/codes/A2C/task1.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 01:19:43 +LastEditor: JiangJi +LastEditTime: 2022-11-01 01:21:12 +Discription: continuous action space +''' +import sys,os +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path + +import gym +from common.utils import all_seed,merge_class_attrs +from common.launcher import Launcher +from common.memories import PGReplay +from common.models import ActorSoftmaxTanh,Critic +from envs.register import register_env +from a2c import A2C +from config.config import GeneralConfigA2C,AlgoConfigA2C + +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigA2C()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigA2C()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=True) # create env + if cfg.seed !=0: # set random seed + all_seed(env,seed = cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + models = {'Actor':ActorSoftmaxTanh(n_states,n_actions, hidden_dim = cfg.actor_hidden_dim),'Critic':Critic(n_states,1,hidden_dim=cfg.critic_hidden_dim)} + memories = {'ACMemory':PGReplay()} + agent = A2C(models,memories,cfg) + for k,v in models.items(): + logger.info(f"{k} model name: {type(v).__name__}") + for k,v in memories.items(): + logger.info(f"{k} memory name: {type(v).__name__}") + logger.info(f"agent name: {type(agent).__name__}") + return env,agent + def train_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + ep_entropy = 0 # entropy per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.sample_action(state) # sample action + next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions + agent.memory.push((agent.value,agent.log_prob,reward)) # save transitions + state = next_state # update state + ep_reward += reward + ep_entropy += agent.entropy + ep_step += 1 + if terminated: + break + agent.update(next_state,ep_entropy) # update agent + return agent,ep_reward,ep_step + def test_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.predict_action(state) # predict action + next_state, reward, terminated, truncated , info = env.step(action) + state = next_state + ep_reward += reward + ep_step += 1 + if terminated: + break + return agent,ep_reward,ep_step + # def train(self,cfg,env,agent,logger): + # logger.info("Start training!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.train_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 # step per episode + # ep_entropy = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # action = agent.sample_action(state) # sample action + # next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions + # agent.memory.push((agent.value,agent.log_prob,reward)) # save transitions + # state = next_state # update state + # ep_reward += reward + # ep_entropy += agent.entropy + # ep_step += 1 + # if terminated: + # break + # agent.update(next_state,ep_entropy) # update agent + # rewards.append(ep_reward) + # steps.append(ep_step) + # logger.info(f"Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step}") + # logger.info("Finish training!") + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + # def test(self,cfg,env,agent,logger): + # logger.info("Start testing!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.test_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # action = agent.predict_action(state) # predict action + # next_state, reward, terminated, truncated , info = env.step(action) + # state = next_state + # ep_reward += reward + # ep_step += 1 + # if terminated: + # break + # rewards.append(ep_reward) + # steps.append(ep_step) + # logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step}") + # logger.info("Finish testing!") + # env.close() + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + +if __name__ == "__main__": + main = Main() + main.run() + + + + diff --git a/projects/codes/A2C/task2.py b/projects/codes/A2C/task2.py new file mode 100644 index 0000000..96c1cc2 --- /dev/null +++ b/projects/codes/A2C/task2.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 01:19:43 +LastEditor: JiangJi +LastEditTime: 2022-11-01 00:08:22 +Discription: the only difference from task0.py is that the actor here we use ActorSoftmaxTanh instead of ActorSoftmax with ReLU +''' +import sys,os +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path + +import gym +import torch +import numpy as np +from common.utils import all_seed,merge_class_attrs +from common.launcher import Launcher +from common.memories import PGReplay +from common.models import ActorNormal,Critic +from envs.register import register_env +from a2c import A2C +from config.config import GeneralConfigA2C,AlgoConfigA2C + +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigA2C()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigA2C()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=True) # create env + if cfg.seed !=0: # set random seed + all_seed(env,seed = cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + try: + n_actions = env.action_space.n # action dimension + except AttributeError: + n_actions = env.action_space.shape[0] + logger.info(f"action bound: {abs(env.action_space.low.item())}") + setattr(cfg, 'action_bound', abs(env.action_space.low.item())) + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + models = {'Actor':ActorNormal(n_states,n_actions, hidden_dim = cfg.actor_hidden_dim),'Critic':Critic(n_states,1,hidden_dim=cfg.critic_hidden_dim)} + memories = {'ACMemory':PGReplay()} + agent = A2C(models,memories,cfg) + for k,v in models.items(): + logger.info(f"{k} model name: {type(v).__name__}") + for k,v in memories.items(): + logger.info(f"{k} memory name: {type(v).__name__}") + logger.info(f"agent name: {type(agent).__name__}") + return env,agent + def train_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + ep_entropy = 0 # entropy per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.sample_action(state) # sample action + next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions + agent.memory.push((agent.value,agent.log_prob,reward)) # save transitions + state = next_state # update state + ep_reward += reward + ep_entropy += agent.entropy + ep_step += 1 + if terminated: + break + agent.update(next_state,ep_entropy) # update agent + return agent,ep_reward,ep_step + def test_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.predict_action(state) # predict action + next_state, reward, terminated, truncated , info = env.step(action) + state = next_state + ep_reward += reward + ep_step += 1 + if terminated: + break + return agent,ep_reward,ep_step + # def train(self,cfg,env,agent,logger): + # logger.info("Start training!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.train_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 # step per episode + # ep_entropy = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # action = agent.sample_action(state) # sample action + # next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions + # agent.memory.push((agent.value,agent.log_prob,reward)) # save transitions + # state = next_state # update state + # ep_reward += reward + # ep_entropy += agent.entropy + # ep_step += 1 + # if terminated: + # break + # agent.update(next_state,ep_entropy) # update agent + # rewards.append(ep_reward) + # steps.append(ep_step) + # logger.info(f"Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step}") + # logger.info("Finish training!") + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + # def test(self,cfg,env,agent,logger): + # logger.info("Start testing!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.test_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # action = agent.predict_action(state) # predict action + # next_state, reward, terminated, truncated , info = env.step(action) + # state = next_state + # ep_reward += reward + # ep_step += 1 + # if terminated: + # break + # rewards.append(ep_reward) + # steps.append(ep_step) + # logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step}") + # logger.info("Finish testing!") + # env.close() + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + +if __name__ == "__main__": + main = Main() + main.run() + + + + diff --git a/projects/codes/DDPG/ddpg.py b/projects/codes/DDPG/ddpg.py index 93894e3..246966b 100644 --- a/projects/codes/DDPG/ddpg.py +++ b/projects/codes/DDPG/ddpg.py @@ -5,7 +5,7 @@ @Email: johnjim0816@gmail.com @Date: 2020-06-09 20:25:52 @LastEditor: John -LastEditTime: 2022-06-09 19:04:44 +LastEditTime: 2022-09-27 15:43:21 @Discription: @Environment: python 3.7.7 ''' @@ -14,96 +14,45 @@ import numpy as np import torch import torch.nn as nn import torch.optim as optim -import torch.nn.functional as F -class ReplayBuffer: - def __init__(self, capacity): - self.capacity = capacity # 经验回放的容量 - self.buffer = [] # 缓冲区 - self.position = 0 - - def push(self, state, action, reward, next_state, done): - ''' 缓冲区是一个队列,容量超出时去掉开始存入的转移(transition) - ''' - if len(self.buffer) < self.capacity: - self.buffer.append(None) - self.buffer[self.position] = (state, action, reward, next_state, done) - self.position = (self.position + 1) % self.capacity - - def sample(self, batch_size): - batch = random.sample(self.buffer, batch_size) # 随机采出小批量转移 - state, action, reward, next_state, done = zip(*batch) # 解压成状态,动作等 - return state, action, reward, next_state, done - - def __len__(self): - ''' 返回当前存储的量 - ''' - return len(self.buffer) -class Actor(nn.Module): - def __init__(self, n_states, n_actions, hidden_dim, init_w=3e-3): - super(Actor, self).__init__() - self.linear1 = nn.Linear(n_states, hidden_dim) - self.linear2 = nn.Linear(hidden_dim, hidden_dim) - self.linear3 = nn.Linear(hidden_dim, n_actions) - - self.linear3.weight.data.uniform_(-init_w, init_w) - self.linear3.bias.data.uniform_(-init_w, init_w) - - def forward(self, x): - x = F.relu(self.linear1(x)) - x = F.relu(self.linear2(x)) - x = torch.tanh(self.linear3(x)) - return x -class Critic(nn.Module): - def __init__(self, n_states, n_actions, hidden_dim, init_w=3e-3): - super(Critic, self).__init__() - - self.linear1 = nn.Linear(n_states + n_actions, hidden_dim) - self.linear2 = nn.Linear(hidden_dim, hidden_dim) - self.linear3 = nn.Linear(hidden_dim, 1) - # 随机初始化为较小的值 - self.linear3.weight.data.uniform_(-init_w, init_w) - self.linear3.bias.data.uniform_(-init_w, init_w) - - def forward(self, state, action): - # 按维数1拼接 - x = torch.cat([state, action], 1) - x = F.relu(self.linear1(x)) - x = F.relu(self.linear2(x)) - x = self.linear3(x) - return x -class DDPG: - def __init__(self, n_states, n_actions, cfg): - self.device = torch.device(cfg.device) - self.critic = Critic(n_states, n_actions, cfg.hidden_dim).to(self.device) - self.actor = Actor(n_states, n_actions, cfg.hidden_dim).to(self.device) - self.target_critic = Critic(n_states, n_actions, cfg.hidden_dim).to(self.device) - self.target_actor = Actor(n_states, n_actions, cfg.hidden_dim).to(self.device) - # 复制参数到目标网络 +class DDPG: + def __init__(self, models,memories,cfg): + self.device = torch.device(cfg['device']) + self.critic = models['critic'].to(self.device) + self.target_critic = models['critic'].to(self.device) + self.actor = models['actor'].to(self.device) + self.target_actor = models['actor'].to(self.device) + # copy weights from critic to target_critic for target_param, param in zip(self.target_critic.parameters(), self.critic.parameters()): target_param.data.copy_(param.data) + # copy weights from actor to target_actor for target_param, param in zip(self.target_actor.parameters(), self.actor.parameters()): target_param.data.copy_(param.data) + self.critic_optimizer = optim.Adam(self.critic.parameters(), lr=cfg['critic_lr']) + self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=cfg['actor_lr']) + self.memory = memories['memory'] + self.batch_size = cfg['batch_size'] + self.gamma = cfg['gamma'] + self.tau = cfg['tau'] - self.critic_optimizer = optim.Adam( - self.critic.parameters(), lr=cfg.critic_lr) - self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=cfg.actor_lr) - self.memory = ReplayBuffer(cfg.memory_capacity) - self.batch_size = cfg.batch_size - self.soft_tau = cfg.soft_tau # 软更新参数 - self.gamma = cfg.gamma - - def choose_action(self, state): + def sample_action(self, state): state = torch.FloatTensor(state).unsqueeze(0).to(self.device) action = self.actor(state) return action.detach().cpu().numpy()[0, 0] + @torch.no_grad() + def predict_action(self, state): + ''' predict action + ''' + state = torch.FloatTensor(state).unsqueeze(0).to(self.device) + action = self.actor(state) + return action.cpu().numpy()[0, 0] def update(self): - if len(self.memory) < self.batch_size: # 当 memory 中不满足一个批量时,不更新策略 + if len(self.memory) < self.batch_size: # when memory size is less than batch size, return return - # 从经验回放中(replay memory)中随机采样一个批量的转移(transition) + # sample a random minibatch of N transitions from R state, action, reward, next_state, done = self.memory.sample(self.batch_size) - # 转变为张量 + # convert to tensor state = torch.FloatTensor(np.array(state)).to(self.device) next_state = torch.FloatTensor(np.array(next_state)).to(self.device) action = torch.FloatTensor(np.array(action)).to(self.device) @@ -126,19 +75,22 @@ class DDPG: self.critic_optimizer.zero_grad() value_loss.backward() self.critic_optimizer.step() - # 软更新 + # soft update for target_param, param in zip(self.target_critic.parameters(), self.critic.parameters()): target_param.data.copy_( - target_param.data * (1.0 - self.soft_tau) + - param.data * self.soft_tau + target_param.data * (1.0 - self.tau) + + param.data * self.tau ) for target_param, param in zip(self.target_actor.parameters(), self.actor.parameters()): target_param.data.copy_( - target_param.data * (1.0 - self.soft_tau) + - param.data * self.soft_tau + target_param.data * (1.0 - self.tau) + + param.data * self.tau ) - def save(self,path): - torch.save(self.actor.state_dict(), path+'checkpoint.pt') + def save_model(self,path): + from pathlib import Path + # create path + Path(path).mkdir(parents=True, exist_ok=True) + torch.save(self.actor.state_dict(), f"{path}/actor_checkpoint.pt") - def load(self,path): - self.actor.load_state_dict(torch.load(path+'checkpoint.pt')) \ No newline at end of file + def load_model(self,path): + self.actor.load_state_dict(torch.load(f"{path}/actor_checkpoint.pt")) \ No newline at end of file diff --git a/projects/codes/DDPG/main.py b/projects/codes/DDPG/main.py new file mode 100644 index 0000000..8da5d29 --- /dev/null +++ b/projects/codes/DDPG/main.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +@Author: John +@Email: johnjim0816@gmail.com +@Date: 2020-06-11 20:58:21 +@LastEditor: John +LastEditTime: 2022-09-27 15:50:12 +@Discription: +@Environment: python 3.7.7 +''' +import sys,os +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add to system path + +import datetime +import gym +import torch +import argparse +import torch.nn as nn +import torch.nn.functional as F +from env import NormalizedActions,OUNoise +from ddpg import DDPG +from common.utils import all_seed +from common.memories import ReplayBufferQue +from common.launcher import Launcher +from envs.register import register_env + +class Actor(nn.Module): + def __init__(self, n_states, n_actions, hidden_dim, init_w=3e-3): + super(Actor, self).__init__() + self.linear1 = nn.Linear(n_states, hidden_dim) + self.linear2 = nn.Linear(hidden_dim, hidden_dim) + self.linear3 = nn.Linear(hidden_dim, n_actions) + + self.linear3.weight.data.uniform_(-init_w, init_w) + self.linear3.bias.data.uniform_(-init_w, init_w) + + def forward(self, x): + x = F.relu(self.linear1(x)) + x = F.relu(self.linear2(x)) + x = torch.tanh(self.linear3(x)) + return x +class Critic(nn.Module): + def __init__(self, n_states, n_actions, hidden_dim, init_w=3e-3): + super(Critic, self).__init__() + + self.linear1 = nn.Linear(n_states + n_actions, hidden_dim) + self.linear2 = nn.Linear(hidden_dim, hidden_dim) + self.linear3 = nn.Linear(hidden_dim, 1) + # 随机初始化为较小的值 + self.linear3.weight.data.uniform_(-init_w, init_w) + self.linear3.bias.data.uniform_(-init_w, init_w) + + def forward(self, state, action): + # 按维数1拼接 + x = torch.cat([state, action], 1) + x = F.relu(self.linear1(x)) + x = F.relu(self.linear2(x)) + x = self.linear3(x) + return x +class Main(Launcher): + def get_args(self): + """ hyperparameters + """ + curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # obtain current time + parser = argparse.ArgumentParser(description="hyperparameters") + parser.add_argument('--algo_name',default='DDPG',type=str,help="name of algorithm") + parser.add_argument('--env_name',default='Pendulum-v1',type=str,help="name of environment") + parser.add_argument('--train_eps',default=300,type=int,help="episodes of training") + parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") + parser.add_argument('--max_steps',default=100000,type=int,help="steps per episode, much larger value can simulate infinite steps") + parser.add_argument('--gamma',default=0.99,type=float,help="discounted factor") + parser.add_argument('--critic_lr',default=1e-3,type=float,help="learning rate of critic") + parser.add_argument('--actor_lr',default=1e-4,type=float,help="learning rate of actor") + parser.add_argument('--memory_capacity',default=8000,type=int,help="memory capacity") + parser.add_argument('--batch_size',default=128,type=int) + parser.add_argument('--target_update',default=2,type=int) + parser.add_argument('--tau',default=1e-2,type=float) + parser.add_argument('--critic_hidden_dim',default=256,type=int) + parser.add_argument('--actor_hidden_dim',default=256,type=int) + parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") + parser.add_argument('--seed',default=1,type=int,help="random seed") + parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") + parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") + args = parser.parse_args() + default_args = {'result_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/results/", + 'model_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/models/", + } + args = {**vars(args),**default_args} # type(dict) + return args + + def env_agent_config(self,cfg): + register_env(cfg['env_name']) + env = gym.make(cfg['env_name']) + env = NormalizedActions(env) # decorate with action noise + if cfg['seed'] !=0: # set random seed + all_seed(env,seed=cfg["seed"]) + n_states = env.observation_space.shape[0] + n_actions = env.action_space.shape[0] + print(f"n_states: {n_states}, n_actions: {n_actions}") + cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters + models = {"actor":Actor(n_states,n_actions,hidden_dim=cfg['actor_hidden_dim']),"critic":Critic(n_states,n_actions,hidden_dim=cfg['critic_hidden_dim'])} + memories = {"memory":ReplayBufferQue(cfg['memory_capacity'])} + agent = DDPG(models,memories,cfg) + return env,agent + def train(self,cfg, env, agent): + print('Start training!') + ou_noise = OUNoise(env.action_space) # noise of action + rewards = [] # record rewards for all episodes + for i_ep in range(cfg['train_eps']): + state = env.reset() + ou_noise.reset() + ep_reward = 0 + for i_step in range(cfg['max_steps']): + action = agent.sample_action(state) + action = ou_noise.get_action(action, i_step+1) + next_state, reward, done, _ = env.step(action) + ep_reward += reward + agent.memory.push((state, action, reward, next_state, done)) + agent.update() + state = next_state + if done: + break + if (i_ep+1)%10 == 0: + print(f"Env:{i_ep+1}/{cfg['train_eps']}, Reward:{ep_reward:.2f}") + rewards.append(ep_reward) + print('Finish training!') + return {'rewards':rewards} + + def test(self,cfg, env, agent): + print('Start testing!') + rewards = [] # record rewards for all episodes + for i_ep in range(cfg['test_eps']): + state = env.reset() + ep_reward = 0 + for i_step in range(cfg['max_steps']): + action = agent.predict_action(state) + next_state, reward, done, _ = env.step(action) + ep_reward += reward + state = next_state + if done: + break + rewards.append(ep_reward) + print(f"Episode:{i_ep+1}/{cfg['test_eps']}, Reward:{ep_reward:.1f}") + print('Finish testing!') + return {'rewards':rewards} +if __name__ == "__main__": + main = Main() + main.run() + diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/models/checkpoint.pt b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/models/checkpoint.pt deleted file mode 100644 index f245d72..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/models/checkpoint.pt and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/params.json b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/params.json deleted file mode 100644 index 7d22454..0000000 --- a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/params.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "algo_name": "DDPG", - "env_name": "Pendulum-v1", - "train_eps": 300, - "test_eps": 20, - "gamma": 0.99, - "critic_lr": 0.001, - "actor_lr": 0.0001, - "memory_capacity": 8000, - "batch_size": 128, - "target_update": 2, - "soft_tau": 0.01, - "hidden_dim": 256, - "deivce": "cpu", - "result_path": "C:\\Users\\24438\\Desktop\\rl-tutorials/outputs/DDPG/outputs/Pendulum-v1/20220713-225402/results//", - "model_path": "C:\\Users\\24438\\Desktop\\rl-tutorials/outputs/DDPG/outputs/Pendulum-v1/20220713-225402/models/", - "save_fig": true -} \ No newline at end of file diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_ma_rewards.npy b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_ma_rewards.npy deleted file mode 100644 index 5c72032..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_ma_rewards.npy and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_rewards.npy b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_rewards.npy deleted file mode 100644 index 3508874..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_rewards.npy and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_rewards_curve.png b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_rewards_curve.png deleted file mode 100644 index 8d7fbd2..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/test_rewards_curve.png and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_ma_rewards.npy b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_ma_rewards.npy deleted file mode 100644 index c3dd9ad..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_ma_rewards.npy and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_rewards.npy b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_rewards.npy deleted file mode 100644 index 48e4157..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_rewards.npy and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_rewards_curve.png b/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_rewards_curve.png deleted file mode 100644 index ec6038f..0000000 Binary files a/projects/codes/DDPG/outputs/Pendulum-v1/20220713-225402/results/train_rewards_curve.png and /dev/null differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/models/actor_checkpoint.pt b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/models/actor_checkpoint.pt new file mode 100644 index 0000000..e65e7ca Binary files /dev/null and b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/models/actor_checkpoint.pt differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/params.json b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/params.json new file mode 100644 index 0000000..c3825cf --- /dev/null +++ b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/params.json @@ -0,0 +1,25 @@ +{ + "algo_name": "DDPG", + "env_name": "Pendulum-v1", + "train_eps": 300, + "test_eps": 20, + "max_steps": 100000, + "gamma": 0.99, + "critic_lr": 0.001, + "actor_lr": 0.0001, + "memory_capacity": 8000, + "batch_size": 128, + "target_update": 2, + "tau": 0.01, + "critic_hidden_dim": 256, + "actor_hidden_dim": 256, + "device": "cpu", + "seed": 1, + "show_fig": false, + "save_fig": true, + "result_path": "/Users/jj/Desktop/rl-tutorials/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/", + "model_path": "/Users/jj/Desktop/rl-tutorials/codes/DDPG/outputs/Pendulum-v1/20220927-155053/models/", + "n_states": 3, + "n_actions": 1, + "training_time": 358.8142900466919 +} \ No newline at end of file diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/testing_curve.png b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/testing_curve.png new file mode 100644 index 0000000..44e53e2 Binary files /dev/null and b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/testing_curve.png differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/testing_results.csv b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/testing_results.csv new file mode 100644 index 0000000..590c141 --- /dev/null +++ b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/testing_results.csv @@ -0,0 +1,21 @@ +rewards +-116.045416124376 +-126.18022935469217 +-231.46338228458293 +-246.40481094689758 +-304.69493818839186 +-124.39609191913091 +-1.060003582878406 +-114.19659653048288 +-348.9745708742037 +-116.10811133324769 +-117.20146333694844 +-118.66206784602966 +-235.17836229762355 +-356.14054913290624 +-118.38579118156366 +-351.9415915140771 +-114.50877866098972 +-124.775484599685 +-226.47062962476875 +-121.48872909193936 diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/training_curve.png b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/training_curve.png new file mode 100644 index 0000000..b0b95fe Binary files /dev/null and b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/training_curve.png differ diff --git a/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/training_results.csv b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/training_results.csv new file mode 100644 index 0000000..2fa54ec --- /dev/null +++ b/projects/codes/DDPG/outputs/Pendulum-v1/20220927-155053/results/training_results.csv @@ -0,0 +1,301 @@ +rewards +-1557.8518596631177 +-1354.7599369723537 +-1375.5732016629706 +-1493.8609739040871 +-1426.7116204537845 +-1235.7920755027762 +-1339.1647620443073 +-1544.2379906560486 +-1539.6232758780877 +-1549.5690058648204 +-1446.9193195793853 +-1520.2666688767558 +-1525.0116707122581 +-1379.136573640111 +-1532.702831768523 +-1484.7552963941637 +-1359.6699201737677 +-1349.6805649166854 +-1510.869999766432 +-1515.8398785434708 +-1447.4648656578254 +-1537.3822077872178 +-1249.6517039877456 +-1350.0302666965736 +-1529.4363372505607 +-1320.28204807604 +-1502.9248141320654 +-1545.4861772197075 +-1579.928789692619 +-1413.296070504152 +-1242.4673258663781 +-1403.8672028946078 +-1452.7199002523635 +-871.6071114009982 +-1324.1789316121412 +-1313.3348146041249 +-1059.8722927418046 +-1054.232673559123 +-973.8956270782459 +-972.9936641224186 +-972.9477399905655 +-947.0613443333731 +-737.3866328989184 +-958.6068164634295 +-739.6973395350705 +-886.8383108399455 +-775.1430379821574 +-937.3115016337417 +-700.875502951337 +-829.9396339144109 +-271.1629773396998 +-493.5460684734584 +-485.9321719313203 +-858.3735607086766 +-1145.3440084994113 +-1121.1338201339777 +-1191.5640831332366 +-1350.0425368846784 +-249.25438665107953 +-727.9051714734406 +-368.5579316240395 +-392.0611344939354 +-955.3231703741553 +-488.27956192035265 +-362.2734695759137 +-949.5440839122496 +-496.8460016912189 +-726.6871514929877 +-424.48641462866266 +-954.7075428204689 +-608.9650086409792 +-848.6059768900151 +-866.7052398755033 +-856.9846415044439 +-751.0342976129083 +-749.5118249469103 +-509.882299129811 +-506.56154097018043 +-906.0964475820368 +-1318.3941416286855 +-1422.2017011876615 +-1523.1661091894277 +-1209.2850593747999 +-1415.0972750475833 +-1533.2263827605834 +-1405.8345530072663 +-1244.3384723384913 +-1237.4704845061992 +-949.3394417935086 +-981.1855396112669 +-1241.224568444032 +-1033.118364799829 +-1017.2403725619487 +-981.9727804516916 +-853.1877724775591 +-869.0652369861646 +-1069.8265343327998 +-371.73173813891884 +-735.5887912713665 +-1262.050240428957 +-1242.985056062197 +-1191.6867713427482 +-1328.5323118458034 +-1015.5308653784714 +-895.3066515461381 +-994.1114862316568 +-761.4710321387583 +-717.6979056272868 +-782.302146467708 +-640.4913147345328 +-725.6469893076355 +-497.5346232085584 +-1027.1192149202325 +-950.0117149822681 +-956.1343737377374 +-708.9489626669097 +-964.5003064113283 +-611.9111516886613 +-612.3182791021098 +-1100.0047939174613 +-984.9262458612923 +-858.7106075590494 +-842.305917848386 +-745.9043991922597 +-741.2168858394704 +-1143.0750387284456 +-755.5257242325362 +-745.8440029056219 +-387.8717950334138 +-764.6628701051523 +-486.7967495537958 +-485.13357559164814 +-313.5415216767419 +-611.3450529954782 +-611.1570544377465 +-507.6456747676814 +-615.2032627013064 +-242.37988821149764 +-603.85498620892 +-352.2672241055367 +-155.99874664988383 +-615.4003063516313 +-384.9811293551548 +-498.80727354456315 +-407.6898591217813 +-1213.6383844696395 +-1122.2425748913884 +-592.4819308883913 +-478.2046833075051 +-891.0254788311132 +-482.40204115385 +-339.34676196677407 +-582.9985110154428 +-213.38243627478826 +-928.8434951613825 +-1545.5433749195483 +-1179.5016285049896 +-1211.9549773601925 +-1396.8082561792166 +-1318.073128824395 +-597.3837225413702 +-564.7793352410449 +-723.744223659601 +-653.0145534050461 +-847.6138123247009 +-385.62784320332867 +-245.25250602651928 +-117.55094416757835 +-864.0064774069044 +-124.30221387458867 +-244.4014050243669 +-1148.861754008653 +-914.4047868424254 +-765.9394408203351 +-124.05114610943177 +-605.7641303826842 +-616.3595829453579 +-375.5024692962698 +-253.51874076866997 +-240.08405245866714 +-503.96565579077225 +-606.7646526173963 +-502.6512112729435 +-746.404013238678 +-718.8658110051653 +-125.65808359856703 +-247.62256797883364 +-363.69852213666803 +-249.21801061415547 +-491.7724416523124 +-235.37050442527357 +-609.6026403583944 +-236.05731608228092 +-381.19853850450454 +-298.7683201867404 +-127.64145601534942 +-233.4300138495176 +-129.11243486763516 +-390.0092951263507 +-1000.7729892969854 +-249.60445310459787 +-253.02347910759622 +-129.04269174391223 +-360.6321251486308 +-377.26297602576534 +-124.98466986009481 +-245.47913567739212 +-127.0885254550411 +-118.11013006825459 +-128.8682755001942 +-497.3015586531096 +-340.77352433313484 +-514.4945799737978 +-503.24077308842783 +-627.9068157464455 +-511.39396524392146 +-763.8866112068075 +-741.7885082408757 +-617.4945380476306 +-950.3176437519387 +-643.4791402436576 +-511.9377874351982 +-573.6219349516633 +-564.1297823875693 +-242.06399233336583 +-496.4020380325518 +-360.56387982880364 +-495.4590728336022 +-503.7263345016764 +-122.47964616802327 +-254.16543926263168 +-614.5335268729743 +-234.3718017676852 +-301.27514663062874 +-387.64758894986204 +-368.74492411716415 +-364.43559131093593 +-160.6845848115533 +-504.1948947975429 +-246.51676032967683 +-251.5732500220603 +-600.1463819723879 +-247.17476928471288 +-381.924164337607 +-377.4773226068174 +-378.511830774651 +-126.69199895843033 +-365.0506645811703 +-130.45052114802874 +-374.37400288581813 +-502.37678159638887 +-374.43552658473055 +-241.157211525502 +-388.9597456642503 +-249.4412385534861 +-114.71395078439846 +-864.6882327286056 +-626.8144095971478 +-732.9226896140248 +-368.24767905020394 +-369.7425524469132 +-398.07832598184626 +-906.7113918582257 +-252.2343258180765 +-370.4258473086036 +-736.0203154396909 +-609.4605173515027 +-661.1255920773486 +-489.9605291008584 +-364.1671188501402 +-644.4029089587781 +-477.9510457677364 +-128.78294672880136 +-373.74382001694886 +-380.69931133982936 +-372.60275628381805 +-743.0410655515724 +-597.558847789258 +-387.94245652694394 +-725.3939448944484 +-409.1301313430852 +-491.8442467896486 +-123.0638156839621 +-377.9292326597324 +-489.27209762667974 +-255.63227821371257 +-379.5885382060625 +-370.2312967024669 +-250.94061817008688 +-131.2125308195906 +-600.3312016651868 +-130.84444772735733 +-312.6287688438562 +-382.4144610039701 +-259.03558003697265 +-224.92206667096863 +-376.81390821359685 +-382.39993489751646 +-380.25599578593636 +-610.1016672243638 diff --git a/projects/codes/DDPG/task0.py b/projects/codes/DDPG/task0.py deleted file mode 100644 index 20688d3..0000000 --- a/projects/codes/DDPG/task0.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -''' -@Author: John -@Email: johnjim0816@gmail.com -@Date: 2020-06-11 20:58:21 -@LastEditor: John -LastEditTime: 2022-07-21 21:51:34 -@Discription: -@Environment: python 3.7.7 -''' -import sys,os -curr_path = os.path.dirname(os.path.abspath(__file__)) # current path -parent_path = os.path.dirname(curr_path) # parent path -sys.path.append(parent_path) # add to system path - -import datetime -import gym -import torch -import argparse - -from env import NormalizedActions,OUNoise -from ddpg import DDPG -from common.utils import save_results,make_dir -from common.utils import plot_rewards,save_args - -def get_args(): - """ Hyperparameters - """ - curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # Obtain current time - parser = argparse.ArgumentParser(description="hyperparameters") - parser.add_argument('--algo_name',default='DDPG',type=str,help="name of algorithm") - parser.add_argument('--env_name',default='Pendulum-v1',type=str,help="name of environment") - parser.add_argument('--train_eps',default=300,type=int,help="episodes of training") - parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") - parser.add_argument('--gamma',default=0.99,type=float,help="discounted factor") - parser.add_argument('--critic_lr',default=1e-3,type=float,help="learning rate of critic") - parser.add_argument('--actor_lr',default=1e-4,type=float,help="learning rate of actor") - parser.add_argument('--memory_capacity',default=8000,type=int,help="memory capacity") - parser.add_argument('--batch_size',default=128,type=int) - parser.add_argument('--target_update',default=2,type=int) - parser.add_argument('--soft_tau',default=1e-2,type=float) - parser.add_argument('--hidden_dim',default=256,type=int) - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--result_path',default=curr_path + "/outputs/" + parser.parse_args().env_name + \ - '/' + curr_time + '/results/' ) - parser.add_argument('--model_path',default=curr_path + "/outputs/" + parser.parse_args().env_name + \ - '/' + curr_time + '/models/' ) # path to save models - parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") - args = parser.parse_args() - return args - -def env_agent_config(cfg,seed=1): - env = NormalizedActions(gym.make(cfg.env_name)) # 装饰action噪声 - env.seed(seed) # 随机种子 - n_states = env.observation_space.shape[0] - n_actions = env.action_space.shape[0] - agent = DDPG(n_states,n_actions,cfg) - return env,agent -def train(cfg, env, agent): - print('Start training!') - print(f'Env:{cfg.env_name}, Algorithm:{cfg.algo_name}, Device:{cfg.device}') - ou_noise = OUNoise(env.action_space) # noise of action - rewards = [] # 记录所有回合的奖励 - ma_rewards = [] # 记录所有回合的滑动平均奖励 - for i_ep in range(cfg.train_eps): - state = env.reset() - ou_noise.reset() - done = False - ep_reward = 0 - i_step = 0 - while not done: - i_step += 1 - action = agent.choose_action(state) - action = ou_noise.get_action(action, i_step) - next_state, reward, done, _ = env.step(action) - ep_reward += reward - agent.memory.push(state, action, reward, next_state, done) - agent.update() - state = next_state - if (i_ep+1)%10 == 0: - print(f'Env:{i_ep+1}/{cfg.train_eps}, Reward:{ep_reward:.2f}') - rewards.append(ep_reward) - if ma_rewards: - ma_rewards.append(0.9*ma_rewards[-1]+0.1*ep_reward) - else: - ma_rewards.append(ep_reward) - print('Finish training!') - return {'rewards':rewards,'ma_rewards':ma_rewards} - -def test(cfg, env, agent): - print('Start testing') - print(f'Env:{cfg.env_name}, Algorithm:{cfg.algo_name}, Device:{cfg.device}') - rewards = [] # 记录所有回合的奖励 - ma_rewards = [] # 记录所有回合的滑动平均奖励 - for i_ep in range(cfg.test_eps): - state = env.reset() - done = False - ep_reward = 0 - i_step = 0 - while not done: - i_step += 1 - action = agent.choose_action(state) - next_state, reward, done, _ = env.step(action) - ep_reward += reward - state = next_state - rewards.append(ep_reward) - if ma_rewards: - ma_rewards.append(0.9*ma_rewards[-1]+0.1*ep_reward) - else: - ma_rewards.append(ep_reward) - print(f"Epside:{i_ep+1}/{cfg.test_eps}, Reward:{ep_reward:.1f}") - print('Finish testing!') - return {'rewards':rewards,'ma_rewards':ma_rewards} -if __name__ == "__main__": - cfg = get_args() - # training - env,agent = env_agent_config(cfg,seed=1) - res_dic = train(cfg, env, agent) - make_dir(cfg.result_path, cfg.model_path) - save_args(cfg) - agent.save(path=cfg.model_path) - save_results(res_dic, tag='train', - path=cfg.result_path) - plot_rewards(res_dic['rewards'], res_dic['ma_rewards'], cfg, tag="train") - # testing - env,agent = env_agent_config(cfg,seed=10) - agent.load(path=cfg.model_path) - res_dic = test(cfg,env,agent) - save_results(res_dic, tag='test', - path=cfg.result_path) - plot_rewards(res_dic['rewards'], res_dic['ma_rewards'], cfg, tag="test") - diff --git a/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/config.yaml b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/config.yaml new file mode 100644 index 0000000..5e3ad4e --- /dev/null +++ b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/config.yaml @@ -0,0 +1,25 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: CartPole-v1 + eval_eps: 10 + eval_per_episode: 5 + load_checkpoint: true + load_path: Train_CartPole-v1_DQN_20221031-001201 + max_steps: 200 + mode: test + save_fig: true + seed: 0 + show_fig: false + test_eps: 10 + train_eps: 100 +algo_cfg: + batch_size: 64 + buffer_size: 100000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + hidden_dim: 256 + lr: 0.0001 + target_update: 4 diff --git a/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/logs/log.txt b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/logs/log.txt new file mode 100644 index 0000000..44f28cb --- /dev/null +++ b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/logs/log.txt @@ -0,0 +1,14 @@ +2022-10-31 00:13:43 - r - INFO: - n_states: 4, n_actions: 2 +2022-10-31 00:13:44 - r - INFO: - Start testing! +2022-10-31 00:13:44 - r - INFO: - Env: CartPole-v1, Algorithm: DQN, Device: cuda +2022-10-31 00:13:45 - r - INFO: - Episode: 1/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 2/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 3/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 4/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 5/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 6/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 7/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 8/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 9/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Episode: 10/10, Reward: 200.0, Step: 200 +2022-10-31 00:13:45 - r - INFO: - Finish testing! diff --git a/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/models/checkpoint.pt b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/models/checkpoint.pt new file mode 100644 index 0000000..722eb69 Binary files /dev/null and b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/models/checkpoint.pt differ diff --git a/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/results/learning_curve.png b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/results/learning_curve.png new file mode 100644 index 0000000..046009a Binary files /dev/null and b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/results/learning_curve.png differ diff --git a/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/results/res.csv b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/results/res.csv new file mode 100644 index 0000000..cbbcf2e --- /dev/null +++ b/projects/codes/DQN/Test_CartPole-v1_DQN_20221031-001343/results/res.csv @@ -0,0 +1,11 @@ +episodes,rewards,steps +0,200.0,200 +1,200.0,200 +2,200.0,200 +3,200.0,200 +4,200.0,200 +5,200.0,200 +6,200.0,200 +7,200.0,200 +8,200.0,200 +9,200.0,200 diff --git a/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/config.yaml b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/config.yaml new file mode 100644 index 0000000..7416aec --- /dev/null +++ b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/config.yaml @@ -0,0 +1,23 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: Acrobot-v1 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 100000 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 10 + train_eps: 100 +algo_cfg: + batch_size: 128 + buffer_size: 200000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + hidden_dim: 256 + lr: 0.002 + target_update: 4 diff --git a/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/logs/log.txt b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/logs/log.txt new file mode 100644 index 0000000..e745c8c --- /dev/null +++ b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/logs/log.txt @@ -0,0 +1,104 @@ +2022-10-26 09:46:45 - r - INFO: - n_states: 6, n_actions: 3 +2022-10-26 09:46:48 - r - INFO: - Start training! +2022-10-26 09:46:48 - r - INFO: - Env: Acrobot-v1, Algorithm: DQN, Device: cuda +2022-10-26 09:46:50 - r - INFO: - Episode: 1/100, Reward: -861.00: Epislon: 0.178 +2022-10-26 09:46:50 - r - INFO: - Episode: 2/100, Reward: -252.00: Epislon: 0.111 +2022-10-26 09:46:50 - r - INFO: - Episode: 3/100, Reward: -196.00: Epislon: 0.078 +2022-10-26 09:46:51 - r - INFO: - Episode: 4/100, Reward: -390.00: Epislon: 0.041 +2022-10-26 09:46:52 - r - INFO: - Episode: 5/100, Reward: -371.00: Epislon: 0.025 +2022-10-26 09:46:52 - r - INFO: - Episode: 6/100, Reward: -237.00: Epislon: 0.019 +2022-10-26 09:46:52 - r - INFO: - Episode: 7/100, Reward: -227.00: Epislon: 0.016 +2022-10-26 09:46:53 - r - INFO: - Episode: 8/100, Reward: -228.00: Epislon: 0.014 +2022-10-26 09:46:53 - r - INFO: - Episode: 9/100, Reward: -305.00: Epislon: 0.012 +2022-10-26 09:46:54 - r - INFO: - Episode: 10/100, Reward: -234.00: Epislon: 0.011 +2022-10-26 09:46:54 - r - INFO: - Episode: 11/100, Reward: -204.00: Epislon: 0.011 +2022-10-26 09:46:55 - r - INFO: - Episode: 12/100, Reward: -277.00: Epislon: 0.010 +2022-10-26 09:46:55 - r - INFO: - Episode: 13/100, Reward: -148.00: Epislon: 0.010 +2022-10-26 09:46:56 - r - INFO: - Episode: 14/100, Reward: -372.00: Epislon: 0.010 +2022-10-26 09:46:56 - r - INFO: - Episode: 15/100, Reward: -273.00: Epislon: 0.010 +2022-10-26 09:46:56 - r - INFO: - Episode: 16/100, Reward: -105.00: Epislon: 0.010 +2022-10-26 09:46:56 - r - INFO: - Episode: 17/100, Reward: -79.00: Epislon: 0.010 +2022-10-26 09:46:57 - r - INFO: - Episode: 18/100, Reward: -112.00: Epislon: 0.010 +2022-10-26 09:46:57 - r - INFO: - Episode: 19/100, Reward: -276.00: Epislon: 0.010 +2022-10-26 09:46:57 - r - INFO: - Episode: 20/100, Reward: -148.00: Epislon: 0.010 +2022-10-26 09:46:58 - r - INFO: - Episode: 21/100, Reward: -201.00: Epislon: 0.010 +2022-10-26 09:46:58 - r - INFO: - Episode: 22/100, Reward: -173.00: Epislon: 0.010 +2022-10-26 09:46:58 - r - INFO: - Episode: 23/100, Reward: -226.00: Epislon: 0.010 +2022-10-26 09:46:59 - r - INFO: - Episode: 24/100, Reward: -154.00: Epislon: 0.010 +2022-10-26 09:46:59 - r - INFO: - Episode: 25/100, Reward: -269.00: Epislon: 0.010 +2022-10-26 09:46:59 - r - INFO: - Episode: 26/100, Reward: -191.00: Epislon: 0.010 +2022-10-26 09:47:00 - r - INFO: - Episode: 27/100, Reward: -177.00: Epislon: 0.010 +2022-10-26 09:47:00 - r - INFO: - Episode: 28/100, Reward: -209.00: Epislon: 0.010 +2022-10-26 09:47:00 - r - INFO: - Episode: 29/100, Reward: -116.00: Epislon: 0.010 +2022-10-26 09:47:00 - r - INFO: - Episode: 30/100, Reward: -117.00: Epislon: 0.010 +2022-10-26 09:47:01 - r - INFO: - Episode: 31/100, Reward: -121.00: Epislon: 0.010 +2022-10-26 09:47:01 - r - INFO: - Episode: 32/100, Reward: -208.00: Epislon: 0.010 +2022-10-26 09:47:01 - r - INFO: - Episode: 33/100, Reward: -147.00: Epislon: 0.010 +2022-10-26 09:47:02 - r - INFO: - Episode: 34/100, Reward: -104.00: Epislon: 0.010 +2022-10-26 09:47:02 - r - INFO: - Episode: 35/100, Reward: -161.00: Epislon: 0.010 +2022-10-26 09:47:02 - r - INFO: - Episode: 36/100, Reward: -144.00: Epislon: 0.010 +2022-10-26 09:47:02 - r - INFO: - Episode: 37/100, Reward: -131.00: Epislon: 0.010 +2022-10-26 09:47:03 - r - INFO: - Episode: 38/100, Reward: -226.00: Epislon: 0.010 +2022-10-26 09:47:03 - r - INFO: - Episode: 39/100, Reward: -117.00: Epislon: 0.010 +2022-10-26 09:47:03 - r - INFO: - Episode: 40/100, Reward: -344.00: Epislon: 0.010 +2022-10-26 09:47:04 - r - INFO: - Episode: 41/100, Reward: -123.00: Epislon: 0.010 +2022-10-26 09:47:04 - r - INFO: - Episode: 42/100, Reward: -232.00: Epislon: 0.010 +2022-10-26 09:47:04 - r - INFO: - Episode: 43/100, Reward: -190.00: Epislon: 0.010 +2022-10-26 09:47:05 - r - INFO: - Episode: 44/100, Reward: -176.00: Epislon: 0.010 +2022-10-26 09:47:05 - r - INFO: - Episode: 45/100, Reward: -139.00: Epislon: 0.010 +2022-10-26 09:47:06 - r - INFO: - Episode: 46/100, Reward: -410.00: Epislon: 0.010 +2022-10-26 09:47:06 - r - INFO: - Episode: 47/100, Reward: -115.00: Epislon: 0.010 +2022-10-26 09:47:06 - r - INFO: - Episode: 48/100, Reward: -118.00: Epislon: 0.010 +2022-10-26 09:47:06 - r - INFO: - Episode: 49/100, Reward: -113.00: Epislon: 0.010 +2022-10-26 09:47:07 - r - INFO: - Episode: 50/100, Reward: -355.00: Epislon: 0.010 +2022-10-26 09:47:07 - r - INFO: - Episode: 51/100, Reward: -110.00: Epislon: 0.010 +2022-10-26 09:47:07 - r - INFO: - Episode: 52/100, Reward: -148.00: Epislon: 0.010 +2022-10-26 09:47:08 - r - INFO: - Episode: 53/100, Reward: -135.00: Epislon: 0.010 +2022-10-26 09:47:08 - r - INFO: - Episode: 54/100, Reward: -220.00: Epislon: 0.010 +2022-10-26 09:47:08 - r - INFO: - Episode: 55/100, Reward: -157.00: Epislon: 0.010 +2022-10-26 09:47:09 - r - INFO: - Episode: 56/100, Reward: -130.00: Epislon: 0.010 +2022-10-26 09:47:09 - r - INFO: - Episode: 57/100, Reward: -150.00: Epislon: 0.010 +2022-10-26 09:47:09 - r - INFO: - Episode: 58/100, Reward: -254.00: Epislon: 0.010 +2022-10-26 09:47:10 - r - INFO: - Episode: 59/100, Reward: -148.00: Epislon: 0.010 +2022-10-26 09:47:10 - r - INFO: - Episode: 60/100, Reward: -108.00: Epislon: 0.010 +2022-10-26 09:47:10 - r - INFO: - Episode: 61/100, Reward: -152.00: Epislon: 0.010 +2022-10-26 09:47:10 - r - INFO: - Episode: 62/100, Reward: -107.00: Epislon: 0.010 +2022-10-26 09:47:10 - r - INFO: - Episode: 63/100, Reward: -110.00: Epislon: 0.010 +2022-10-26 09:47:11 - r - INFO: - Episode: 64/100, Reward: -266.00: Epislon: 0.010 +2022-10-26 09:47:11 - r - INFO: - Episode: 65/100, Reward: -344.00: Epislon: 0.010 +2022-10-26 09:47:12 - r - INFO: - Episode: 66/100, Reward: -93.00: Epislon: 0.010 +2022-10-26 09:47:12 - r - INFO: - Episode: 67/100, Reward: -113.00: Epislon: 0.010 +2022-10-26 09:47:12 - r - INFO: - Episode: 68/100, Reward: -191.00: Epislon: 0.010 +2022-10-26 09:47:12 - r - INFO: - Episode: 69/100, Reward: -102.00: Epislon: 0.010 +2022-10-26 09:47:13 - r - INFO: - Episode: 70/100, Reward: -187.00: Epislon: 0.010 +2022-10-26 09:47:13 - r - INFO: - Episode: 71/100, Reward: -158.00: Epislon: 0.010 +2022-10-26 09:47:13 - r - INFO: - Episode: 72/100, Reward: -166.00: Epislon: 0.010 +2022-10-26 09:47:14 - r - INFO: - Episode: 73/100, Reward: -202.00: Epislon: 0.010 +2022-10-26 09:47:14 - r - INFO: - Episode: 74/100, Reward: -179.00: Epislon: 0.010 +2022-10-26 09:47:14 - r - INFO: - Episode: 75/100, Reward: -150.00: Epislon: 0.010 +2022-10-26 09:47:14 - r - INFO: - Episode: 76/100, Reward: -170.00: Epislon: 0.010 +2022-10-26 09:47:15 - r - INFO: - Episode: 77/100, Reward: -149.00: Epislon: 0.010 +2022-10-26 09:47:15 - r - INFO: - Episode: 78/100, Reward: -119.00: Epislon: 0.010 +2022-10-26 09:47:15 - r - INFO: - Episode: 79/100, Reward: -115.00: Epislon: 0.010 +2022-10-26 09:47:15 - r - INFO: - Episode: 80/100, Reward: -97.00: Epislon: 0.010 +2022-10-26 09:47:16 - r - INFO: - Episode: 81/100, Reward: -153.00: Epislon: 0.010 +2022-10-26 09:47:16 - r - INFO: - Episode: 82/100, Reward: -97.00: Epislon: 0.010 +2022-10-26 09:47:16 - r - INFO: - Episode: 83/100, Reward: -211.00: Epislon: 0.010 +2022-10-26 09:47:16 - r - INFO: - Episode: 84/100, Reward: -195.00: Epislon: 0.010 +2022-10-26 09:47:17 - r - INFO: - Episode: 85/100, Reward: -125.00: Epislon: 0.010 +2022-10-26 09:47:17 - r - INFO: - Episode: 86/100, Reward: -155.00: Epislon: 0.010 +2022-10-26 09:47:17 - r - INFO: - Episode: 87/100, Reward: -151.00: Epislon: 0.010 +2022-10-26 09:47:18 - r - INFO: - Episode: 88/100, Reward: -194.00: Epislon: 0.010 +2022-10-26 09:47:18 - r - INFO: - Episode: 89/100, Reward: -188.00: Epislon: 0.010 +2022-10-26 09:47:18 - r - INFO: - Episode: 90/100, Reward: -195.00: Epislon: 0.010 +2022-10-26 09:47:19 - r - INFO: - Episode: 91/100, Reward: -141.00: Epislon: 0.010 +2022-10-26 09:47:19 - r - INFO: - Episode: 92/100, Reward: -132.00: Epislon: 0.010 +2022-10-26 09:47:19 - r - INFO: - Episode: 93/100, Reward: -127.00: Epislon: 0.010 +2022-10-26 09:47:19 - r - INFO: - Episode: 94/100, Reward: -195.00: Epislon: 0.010 +2022-10-26 09:47:20 - r - INFO: - Episode: 95/100, Reward: -152.00: Epislon: 0.010 +2022-10-26 09:47:20 - r - INFO: - Episode: 96/100, Reward: -145.00: Epislon: 0.010 +2022-10-26 09:47:20 - r - INFO: - Episode: 97/100, Reward: -123.00: Epislon: 0.010 +2022-10-26 09:47:20 - r - INFO: - Episode: 98/100, Reward: -176.00: Epislon: 0.010 +2022-10-26 09:47:21 - r - INFO: - Episode: 99/100, Reward: -180.00: Epislon: 0.010 +2022-10-26 09:47:21 - r - INFO: - Episode: 100/100, Reward: -124.00: Epislon: 0.010 +2022-10-26 09:47:21 - r - INFO: - Finish training! diff --git a/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/models/checkpoint.pt b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/models/checkpoint.pt new file mode 100644 index 0000000..5448aca Binary files /dev/null and b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/models/checkpoint.pt differ diff --git a/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/results/learning_curve.png b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/results/learning_curve.png new file mode 100644 index 0000000..7f1054d Binary files /dev/null and b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/results/learning_curve.png differ diff --git a/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/results/res.csv b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/results/res.csv new file mode 100644 index 0000000..1758be2 --- /dev/null +++ b/projects/codes/DQN/Train_Acrobot-v1_DQN_20221026-094645/results/res.csv @@ -0,0 +1,101 @@ +episodes,rewards,steps +0,-861.0,862 +1,-252.0,253 +2,-196.0,197 +3,-390.0,391 +4,-371.0,372 +5,-237.0,238 +6,-227.0,228 +7,-228.0,229 +8,-305.0,306 +9,-234.0,235 +10,-204.0,205 +11,-277.0,278 +12,-148.0,149 +13,-372.0,373 +14,-273.0,274 +15,-105.0,106 +16,-79.0,80 +17,-112.0,113 +18,-276.0,277 +19,-148.0,149 +20,-201.0,202 +21,-173.0,174 +22,-226.0,227 +23,-154.0,155 +24,-269.0,270 +25,-191.0,192 +26,-177.0,178 +27,-209.0,210 +28,-116.0,117 +29,-117.0,118 +30,-121.0,122 +31,-208.0,209 +32,-147.0,148 +33,-104.0,105 +34,-161.0,162 +35,-144.0,145 +36,-131.0,132 +37,-226.0,227 +38,-117.0,118 +39,-344.0,345 +40,-123.0,124 +41,-232.0,233 +42,-190.0,191 +43,-176.0,177 +44,-139.0,140 +45,-410.0,411 +46,-115.0,116 +47,-118.0,119 +48,-113.0,114 +49,-355.0,356 +50,-110.0,111 +51,-148.0,149 +52,-135.0,136 +53,-220.0,221 +54,-157.0,158 +55,-130.0,131 +56,-150.0,151 +57,-254.0,255 +58,-148.0,149 +59,-108.0,109 +60,-152.0,153 +61,-107.0,108 +62,-110.0,111 +63,-266.0,267 +64,-344.0,345 +65,-93.0,94 +66,-113.0,114 +67,-191.0,192 +68,-102.0,103 +69,-187.0,188 +70,-158.0,159 +71,-166.0,167 +72,-202.0,203 +73,-179.0,180 +74,-150.0,151 +75,-170.0,171 +76,-149.0,150 +77,-119.0,120 +78,-115.0,116 +79,-97.0,98 +80,-153.0,154 +81,-97.0,98 +82,-211.0,212 +83,-195.0,196 +84,-125.0,126 +85,-155.0,156 +86,-151.0,152 +87,-194.0,195 +88,-188.0,189 +89,-195.0,196 +90,-141.0,142 +91,-132.0,133 +92,-127.0,128 +93,-195.0,196 +94,-152.0,153 +95,-145.0,146 +96,-123.0,124 +97,-176.0,177 +98,-180.0,181 +99,-124.0,125 diff --git a/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/config.yaml b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/config.yaml new file mode 100644 index 0000000..33950ad --- /dev/null +++ b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/config.yaml @@ -0,0 +1,25 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: CartPole-v1 + eval_eps: 10 + eval_per_episode: 5 + load_checkpoint: false + load_path: tasks + max_steps: 200 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 10 + train_eps: 100 +algo_cfg: + batch_size: 64 + buffer_size: 100000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + hidden_dim: 256 + lr: 0.0001 + target_update: 800 diff --git a/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/logs/log.txt b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/logs/log.txt new file mode 100644 index 0000000..5b084be --- /dev/null +++ b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/logs/log.txt @@ -0,0 +1,116 @@ +2022-10-31 00:12:01 - r - INFO: - n_states: 4, n_actions: 2 +2022-10-31 00:12:01 - r - INFO: - Start training! +2022-10-31 00:12:01 - r - INFO: - Env: CartPole-v1, Algorithm: DQN, Device: cuda +2022-10-31 00:12:04 - r - INFO: - Episode: 1/100, Reward: 18.0, Step: 18 +2022-10-31 00:12:04 - r - INFO: - Episode: 2/100, Reward: 35.0, Step: 35 +2022-10-31 00:12:04 - r - INFO: - Episode: 3/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:04 - r - INFO: - Episode: 4/100, Reward: 32.0, Step: 32 +2022-10-31 00:12:04 - r - INFO: - Episode: 5/100, Reward: 16.0, Step: 16 +2022-10-31 00:12:04 - r - INFO: - Current episode 5 has the best eval reward: 15.30 +2022-10-31 00:12:04 - r - INFO: - Episode: 6/100, Reward: 12.0, Step: 12 +2022-10-31 00:12:04 - r - INFO: - Episode: 7/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:04 - r - INFO: - Episode: 8/100, Reward: 15.0, Step: 15 +2022-10-31 00:12:04 - r - INFO: - Episode: 9/100, Reward: 11.0, Step: 11 +2022-10-31 00:12:04 - r - INFO: - Episode: 10/100, Reward: 15.0, Step: 15 +2022-10-31 00:12:04 - r - INFO: - Episode: 11/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:04 - r - INFO: - Episode: 12/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:04 - r - INFO: - Episode: 13/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:04 - r - INFO: - Episode: 14/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:04 - r - INFO: - Episode: 15/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:04 - r - INFO: - Episode: 16/100, Reward: 24.0, Step: 24 +2022-10-31 00:12:04 - r - INFO: - Episode: 17/100, Reward: 8.0, Step: 8 +2022-10-31 00:12:04 - r - INFO: - Episode: 18/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:04 - r - INFO: - Episode: 19/100, Reward: 11.0, Step: 11 +2022-10-31 00:12:04 - r - INFO: - Episode: 20/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:04 - r - INFO: - Episode: 21/100, Reward: 12.0, Step: 12 +2022-10-31 00:12:04 - r - INFO: - Episode: 22/100, Reward: 11.0, Step: 11 +2022-10-31 00:12:04 - r - INFO: - Episode: 23/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:04 - r - INFO: - Episode: 24/100, Reward: 21.0, Step: 21 +2022-10-31 00:12:05 - r - INFO: - Episode: 25/100, Reward: 14.0, Step: 14 +2022-10-31 00:12:05 - r - INFO: - Episode: 26/100, Reward: 12.0, Step: 12 +2022-10-31 00:12:05 - r - INFO: - Episode: 27/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:05 - r - INFO: - Episode: 28/100, Reward: 11.0, Step: 11 +2022-10-31 00:12:05 - r - INFO: - Episode: 29/100, Reward: 12.0, Step: 12 +2022-10-31 00:12:05 - r - INFO: - Episode: 30/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:05 - r - INFO: - Episode: 31/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:05 - r - INFO: - Episode: 32/100, Reward: 13.0, Step: 13 +2022-10-31 00:12:05 - r - INFO: - Episode: 33/100, Reward: 18.0, Step: 18 +2022-10-31 00:12:05 - r - INFO: - Episode: 34/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:05 - r - INFO: - Episode: 35/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:05 - r - INFO: - Episode: 36/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:05 - r - INFO: - Episode: 37/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:05 - r - INFO: - Episode: 38/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:05 - r - INFO: - Episode: 39/100, Reward: 10.0, Step: 10 +2022-10-31 00:12:05 - r - INFO: - Episode: 40/100, Reward: 8.0, Step: 8 +2022-10-31 00:12:06 - r - INFO: - Episode: 41/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:06 - r - INFO: - Episode: 42/100, Reward: 9.0, Step: 9 +2022-10-31 00:12:06 - r - INFO: - Episode: 43/100, Reward: 20.0, Step: 20 +2022-10-31 00:12:06 - r - INFO: - Episode: 44/100, Reward: 16.0, Step: 16 +2022-10-31 00:12:06 - r - INFO: - Episode: 45/100, Reward: 17.0, Step: 17 +2022-10-31 00:12:06 - r - INFO: - Current episode 45 has the best eval reward: 17.50 +2022-10-31 00:12:06 - r - INFO: - Episode: 46/100, Reward: 17.0, Step: 17 +2022-10-31 00:12:06 - r - INFO: - Episode: 47/100, Reward: 17.0, Step: 17 +2022-10-31 00:12:06 - r - INFO: - Episode: 48/100, Reward: 18.0, Step: 18 +2022-10-31 00:12:06 - r - INFO: - Episode: 49/100, Reward: 25.0, Step: 25 +2022-10-31 00:12:06 - r - INFO: - Episode: 50/100, Reward: 31.0, Step: 31 +2022-10-31 00:12:06 - r - INFO: - Current episode 50 has the best eval reward: 24.80 +2022-10-31 00:12:06 - r - INFO: - Episode: 51/100, Reward: 22.0, Step: 22 +2022-10-31 00:12:06 - r - INFO: - Episode: 52/100, Reward: 39.0, Step: 39 +2022-10-31 00:12:06 - r - INFO: - Episode: 53/100, Reward: 36.0, Step: 36 +2022-10-31 00:12:06 - r - INFO: - Episode: 54/100, Reward: 26.0, Step: 26 +2022-10-31 00:12:07 - r - INFO: - Episode: 55/100, Reward: 33.0, Step: 33 +2022-10-31 00:12:07 - r - INFO: - Current episode 55 has the best eval reward: 38.70 +2022-10-31 00:12:07 - r - INFO: - Episode: 56/100, Reward: 56.0, Step: 56 +2022-10-31 00:12:07 - r - INFO: - Episode: 57/100, Reward: 112.0, Step: 112 +2022-10-31 00:12:07 - r - INFO: - Episode: 58/100, Reward: 101.0, Step: 101 +2022-10-31 00:12:08 - r - INFO: - Episode: 59/100, Reward: 69.0, Step: 69 +2022-10-31 00:12:08 - r - INFO: - Episode: 60/100, Reward: 75.0, Step: 75 +2022-10-31 00:12:08 - r - INFO: - Episode: 61/100, Reward: 182.0, Step: 182 +2022-10-31 00:12:09 - r - INFO: - Episode: 62/100, Reward: 52.0, Step: 52 +2022-10-31 00:12:09 - r - INFO: - Episode: 63/100, Reward: 67.0, Step: 67 +2022-10-31 00:12:09 - r - INFO: - Episode: 64/100, Reward: 53.0, Step: 53 +2022-10-31 00:12:09 - r - INFO: - Episode: 65/100, Reward: 119.0, Step: 119 +2022-10-31 00:12:10 - r - INFO: - Current episode 65 has the best eval reward: 171.90 +2022-10-31 00:12:10 - r - INFO: - Episode: 66/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:10 - r - INFO: - Episode: 67/100, Reward: 74.0, Step: 74 +2022-10-31 00:12:11 - r - INFO: - Episode: 68/100, Reward: 138.0, Step: 138 +2022-10-31 00:12:11 - r - INFO: - Episode: 69/100, Reward: 149.0, Step: 149 +2022-10-31 00:12:12 - r - INFO: - Episode: 70/100, Reward: 144.0, Step: 144 +2022-10-31 00:12:12 - r - INFO: - Current episode 70 has the best eval reward: 173.70 +2022-10-31 00:12:13 - r - INFO: - Episode: 71/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:13 - r - INFO: - Episode: 72/100, Reward: 198.0, Step: 198 +2022-10-31 00:12:14 - r - INFO: - Episode: 73/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:14 - r - INFO: - Episode: 74/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:15 - r - INFO: - Episode: 75/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:16 - r - INFO: - Current episode 75 has the best eval reward: 200.00 +2022-10-31 00:12:16 - r - INFO: - Episode: 76/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:17 - r - INFO: - Episode: 77/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:17 - r - INFO: - Episode: 78/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:18 - r - INFO: - Episode: 79/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:19 - r - INFO: - Episode: 80/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:19 - r - INFO: - Current episode 80 has the best eval reward: 200.00 +2022-10-31 00:12:20 - r - INFO: - Episode: 81/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:20 - r - INFO: - Episode: 82/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:21 - r - INFO: - Episode: 83/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:21 - r - INFO: - Episode: 84/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:22 - r - INFO: - Episode: 85/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:23 - r - INFO: - Current episode 85 has the best eval reward: 200.00 +2022-10-31 00:12:23 - r - INFO: - Episode: 86/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:24 - r - INFO: - Episode: 87/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:25 - r - INFO: - Episode: 88/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:25 - r - INFO: - Episode: 89/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:26 - r - INFO: - Episode: 90/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:27 - r - INFO: - Current episode 90 has the best eval reward: 200.00 +2022-10-31 00:12:27 - r - INFO: - Episode: 91/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:28 - r - INFO: - Episode: 92/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:28 - r - INFO: - Episode: 93/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:29 - r - INFO: - Episode: 94/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:29 - r - INFO: - Episode: 95/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:30 - r - INFO: - Current episode 95 has the best eval reward: 200.00 +2022-10-31 00:12:31 - r - INFO: - Episode: 96/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:31 - r - INFO: - Episode: 97/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:32 - r - INFO: - Episode: 98/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:32 - r - INFO: - Episode: 99/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:33 - r - INFO: - Episode: 100/100, Reward: 200.0, Step: 200 +2022-10-31 00:12:33 - r - INFO: - Current episode 100 has the best eval reward: 200.00 +2022-10-31 00:12:33 - r - INFO: - Finish training! diff --git a/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/models/checkpoint.pt b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/models/checkpoint.pt new file mode 100644 index 0000000..722eb69 Binary files /dev/null and b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/models/checkpoint.pt differ diff --git a/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/results/learning_curve.png b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/results/learning_curve.png new file mode 100644 index 0000000..331f645 Binary files /dev/null and b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/results/learning_curve.png differ diff --git a/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/results/res.csv b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/results/res.csv new file mode 100644 index 0000000..3bf53a3 --- /dev/null +++ b/projects/codes/DQN/Train_CartPole-v1_DQN_20221031-001201/results/res.csv @@ -0,0 +1,101 @@ +episodes,rewards,steps +0,18.0,18 +1,35.0,35 +2,13.0,13 +3,32.0,32 +4,16.0,16 +5,12.0,12 +6,13.0,13 +7,15.0,15 +8,11.0,11 +9,15.0,15 +10,9.0,9 +11,13.0,13 +12,13.0,13 +13,10.0,10 +14,9.0,9 +15,24.0,24 +16,8.0,8 +17,10.0,10 +18,11.0,11 +19,13.0,13 +20,12.0,12 +21,11.0,11 +22,9.0,9 +23,21.0,21 +24,14.0,14 +25,12.0,12 +26,9.0,9 +27,11.0,11 +28,12.0,12 +29,13.0,13 +30,10.0,10 +31,13.0,13 +32,18.0,18 +33,9.0,9 +34,10.0,10 +35,9.0,9 +36,10.0,10 +37,10.0,10 +38,10.0,10 +39,8.0,8 +40,9.0,9 +41,9.0,9 +42,20.0,20 +43,16.0,16 +44,17.0,17 +45,17.0,17 +46,17.0,17 +47,18.0,18 +48,25.0,25 +49,31.0,31 +50,22.0,22 +51,39.0,39 +52,36.0,36 +53,26.0,26 +54,33.0,33 +55,56.0,56 +56,112.0,112 +57,101.0,101 +58,69.0,69 +59,75.0,75 +60,182.0,182 +61,52.0,52 +62,67.0,67 +63,53.0,53 +64,119.0,119 +65,200.0,200 +66,74.0,74 +67,138.0,138 +68,149.0,149 +69,144.0,144 +70,200.0,200 +71,198.0,198 +72,200.0,200 +73,200.0,200 +74,200.0,200 +75,200.0,200 +76,200.0,200 +77,200.0,200 +78,200.0,200 +79,200.0,200 +80,200.0,200 +81,200.0,200 +82,200.0,200 +83,200.0,200 +84,200.0,200 +85,200.0,200 +86,200.0,200 +87,200.0,200 +88,200.0,200 +89,200.0,200 +90,200.0,200 +91,200.0,200 +92,200.0,200 +93,200.0,200 +94,200.0,200 +95,200.0,200 +96,200.0,200 +97,200.0,200 +98,200.0,200 +99,200.0,200 diff --git a/projects/codes/DQN/config/Acrobot-v1_DQN_Test.yaml b/projects/codes/DQN/config/Acrobot-v1_DQN_Test.yaml new file mode 100644 index 0000000..d6e8d84 --- /dev/null +++ b/projects/codes/DQN/config/Acrobot-v1_DQN_Test.yaml @@ -0,0 +1,22 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: Acrobot-v1 + mode: test + load_checkpoint: true + load_path: Train_Acrobot-v1_DQN_20221026-094645 + max_steps: 100000 + save_fig: true + seed: 1 + show_fig: false + test_eps: 10 + train_eps: 100 +algo_cfg: + batch_size: 128 + buffer_size: 200000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.002 + target_update: 4 diff --git a/projects/codes/DQN/config/Acrobot-v1_DQN_Train.yaml b/projects/codes/DQN/config/Acrobot-v1_DQN_Train.yaml new file mode 100644 index 0000000..0b18e79 --- /dev/null +++ b/projects/codes/DQN/config/Acrobot-v1_DQN_Train.yaml @@ -0,0 +1,22 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: Acrobot-v1 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 100000 + save_fig: true + seed: 1 + show_fig: false + test_eps: 10 + train_eps: 100 +algo_cfg: + batch_size: 128 + buffer_size: 200000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.002 + target_update: 4 diff --git a/projects/codes/DQN/config/CartPole-v1_DQN_Test.yaml b/projects/codes/DQN/config/CartPole-v1_DQN_Test.yaml new file mode 100644 index 0000000..baa98f0 --- /dev/null +++ b/projects/codes/DQN/config/CartPole-v1_DQN_Test.yaml @@ -0,0 +1,22 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: CartPole-v1 + mode: test + load_checkpoint: true + load_path: Train_CartPole-v1_DQN_20221031-001201 + max_steps: 200 + save_fig: true + seed: 0 + show_fig: false + test_eps: 10 + train_eps: 100 +algo_cfg: + batch_size: 64 + buffer_size: 100000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.0001 + target_update: 4 diff --git a/projects/codes/DQN/config/CartPole-v1_DQN_Train.yaml b/projects/codes/DQN/config/CartPole-v1_DQN_Train.yaml new file mode 100644 index 0000000..14297b5 --- /dev/null +++ b/projects/codes/DQN/config/CartPole-v1_DQN_Train.yaml @@ -0,0 +1,22 @@ +general_cfg: + algo_name: DQN + device: cuda + env_name: CartPole-v1 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 0 + show_fig: false + test_eps: 10 + train_eps: 200 +algo_cfg: + batch_size: 64 + buffer_size: 100000 + epsilon_decay: 500 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.0001 + target_update: 4 diff --git a/projects/codes/DQN/config/config.py b/projects/codes/DQN/config/config.py new file mode 100644 index 0000000..2653c8d --- /dev/null +++ b/projects/codes/DQN/config/config.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 00:37:33 +LastEditor: JiangJi +LastEditTime: 2022-10-31 00:11:57 +Discription: default parameters of DQN +''' +from common.config import GeneralConfig,AlgoConfig +class GeneralConfigDQN(GeneralConfig): + def __init__(self) -> None: + self.env_name = "CartPole-v1" # name of environment + self.algo_name = "DQN" # name of algorithm + self.mode = "train" # train or test + self.seed = 1 # random seed + self.device = "cuda" # device to use + self.train_eps = 100 # number of episodes for training + self.test_eps = 10 # number of episodes for testing + self.max_steps = 200 # max steps for each episode + self.load_checkpoint = False + self.load_path = "tasks" # path to load model + self.show_fig = False # show figure or not + self.save_fig = True # save figure or not + +class AlgoConfigDQN(AlgoConfig): + def __init__(self) -> None: + # set epsilon_start=epsilon_end can obtain fixed epsilon=epsilon_end + self.epsilon_start = 0.95 # epsilon start value + self.epsilon_end = 0.01 # epsilon end value + self.epsilon_decay = 500 # epsilon decay rate + self.hidden_dim = 256 # hidden_dim for MLP + self.gamma = 0.95 # discount factor + self.lr = 0.0001 # learning rate + self.buffer_size = 100000 # size of replay buffer + self.batch_size = 64 # batch size + self.target_update = 800 # target network update frequency per steps diff --git a/projects/codes/DQN/dqn.py b/projects/codes/DQN/dqn.py index fce3a73..761d25f 100644 --- a/projects/codes/DQN/dqn.py +++ b/projects/codes/DQN/dqn.py @@ -5,7 +5,7 @@ @Email: johnjim0816@gmail.com @Date: 2020-06-12 00:50:49 @LastEditor: John -LastEditTime: 2022-08-29 23:30:08 +LastEditTime: 2022-10-31 00:07:19 @Discription: @Environment: python 3.7.7 ''' @@ -22,27 +22,28 @@ import numpy as np class DQN: def __init__(self,model,memory,cfg): - self.n_actions = cfg['n_actions'] - self.device = torch.device(cfg['device']) - self.gamma = cfg['gamma'] + self.n_actions = cfg.n_actions + self.device = torch.device(cfg.device) + self.gamma = cfg.gamma ## e-greedy parameters self.sample_count = 0 # sample count for epsilon decay - self.epsilon = cfg['epsilon_start'] + self.epsilon = cfg.epsilon_start self.sample_count = 0 - self.epsilon_start = cfg['epsilon_start'] - self.epsilon_end = cfg['epsilon_end'] - self.epsilon_decay = cfg['epsilon_decay'] - self.batch_size = cfg['batch_size'] + self.epsilon_start = cfg.epsilon_start + self.epsilon_end = cfg.epsilon_end + self.epsilon_decay = cfg.epsilon_decay + self.batch_size = cfg.batch_size + self.target_update = cfg.target_update self.policy_net = model.to(self.device) self.target_net = model.to(self.device) ## copy parameters from policy net to target net for target_param, param in zip(self.target_net.parameters(),self.policy_net.parameters()): target_param.data.copy_(param.data) # self.target_net.load_state_dict(self.policy_net.state_dict()) # or use this to copy parameters - self.optimizer = optim.Adam(self.policy_net.parameters(), lr=cfg['lr']) + self.optimizer = optim.Adam(self.policy_net.parameters(), lr=cfg.lr) self.memory = memory self.update_flag = False - + def sample_action(self, state): ''' sample action with e-greedy policy ''' @@ -58,6 +59,21 @@ class DQN: else: action = random.randrange(self.n_actions) return action + # @torch.no_grad() + # def sample_action(self, state): + # ''' sample action with e-greedy policy + # ''' + # self.sample_count += 1 + # # epsilon must decay(linear,exponential and etc.) for balancing exploration and exploitation + # self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \ + # math.exp(-1. * self.sample_count / self.epsilon_decay) + # if random.random() > self.epsilon: + # state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0) + # q_values = self.policy_net(state) + # action = q_values.max(1)[1].item() # choose action corresponding to the maximum q value + # else: + # action = random.randrange(self.n_actions) + # return action def predict_action(self,state): ''' predict action ''' @@ -99,14 +115,16 @@ class DQN: for param in self.policy_net.parameters(): param.grad.data.clamp_(-1, 1) self.optimizer.step() + if self.sample_count % self.target_update == 0: # target net update, target_update means "C" in pseucodes + self.target_net.load_state_dict(self.policy_net.state_dict()) - def save_model(self, path): + def save_model(self, fpath): from pathlib import Path # create path - Path(path).mkdir(parents=True, exist_ok=True) - torch.save(self.target_net.state_dict(), f"{path}/checkpoint.pt") + Path(fpath).mkdir(parents=True, exist_ok=True) + torch.save(self.target_net.state_dict(), f"{fpath}/checkpoint.pt") - def load_model(self, path): - self.target_net.load_state_dict(torch.load(f"{path}/checkpoint.pt")) + def load_model(self, fpath): + self.target_net.load_state_dict(torch.load(f"{fpath}/checkpoint.pt")) for target_param, param in zip(self.target_net.parameters(), self.policy_net.parameters()): param.data.copy_(target_param.data) diff --git a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/models/checkpoint.pt b/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/models/checkpoint.pt deleted file mode 100644 index c27c438..0000000 Binary files a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/models/checkpoint.pt and /dev/null differ diff --git a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/params.json b/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/params.json deleted file mode 100644 index 0501731..0000000 --- a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/params.json +++ /dev/null @@ -1 +0,0 @@ -{"algo_name": "DQN", "env_name": "Acrobot-v1", "train_eps": 100, "test_eps": 20, "gamma": 0.95, "epsilon_start": 0.95, "epsilon_end": 0.01, "epsilon_decay": 1500, "lr": 0.002, "memory_capacity": 200000, "batch_size": 128, "target_update": 4, "hidden_dim": 256, "device": "cuda", "seed": 10, "show_fig": false, "save_fig": true, "result_path": "C:\\Users\\jiangji\\Desktop\\rl-tutorials\\codes\\DQN/outputs/Acrobot-v1/20220824-124401/results", "model_path": "C:\\Users\\jiangji\\Desktop\\rl-tutorials\\codes\\DQN/outputs/Acrobot-v1/20220824-124401/models", "n_states": 6, "n_actions": 3} \ No newline at end of file diff --git a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/testing_curve.png b/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/testing_curve.png deleted file mode 100644 index 067e301..0000000 Binary files a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/testing_results.csv b/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/testing_results.csv deleted file mode 100644 index 65499c3..0000000 --- a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/testing_results.csv +++ /dev/null @@ -1,21 +0,0 @@ -episodes,rewards -0,-79.0 -1,-113.0 -2,-81.0 -3,-132.0 -4,-110.0 -5,-114.0 -6,-80.0 -7,-101.0 -8,-78.0 -9,-91.0 -10,-107.0 -11,-87.0 -12,-105.0 -13,-91.0 -14,-128.0 -15,-132.0 -16,-119.0 -17,-77.0 -18,-89.0 -19,-134.0 diff --git a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/training_curve.png b/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/training_curve.png deleted file mode 100644 index 9dbeb09..0000000 Binary files a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/training_curve.png and /dev/null differ diff --git a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/training_results.csv b/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/training_results.csv deleted file mode 100644 index c5afa37..0000000 --- a/projects/codes/DQN/outputs/Acrobot-v1/20220824-124401/results/training_results.csv +++ /dev/null @@ -1,101 +0,0 @@ -episodes,rewards -0,-500.0 -1,-500.0 -2,-500.0 -3,-370.0 -4,-449.0 -5,-500.0 -6,-312.0 -7,-374.0 -8,-180.0 -9,-154.0 -10,-137.0 -11,-185.0 -12,-135.0 -13,-302.0 -14,-146.0 -15,-137.0 -16,-119.0 -17,-149.0 -18,-217.0 -19,-191.0 -20,-157.0 -21,-166.0 -22,-138.0 -23,-135.0 -24,-182.0 -25,-130.0 -26,-175.0 -27,-222.0 -28,-133.0 -29,-108.0 -30,-250.0 -31,-119.0 -32,-135.0 -33,-148.0 -34,-194.0 -35,-194.0 -36,-186.0 -37,-131.0 -38,-185.0 -39,-79.0 -40,-129.0 -41,-271.0 -42,-117.0 -43,-159.0 -44,-156.0 -45,-117.0 -46,-158.0 -47,-153.0 -48,-119.0 -49,-164.0 -50,-134.0 -51,-231.0 -52,-117.0 -53,-119.0 -54,-136.0 -55,-173.0 -56,-202.0 -57,-133.0 -58,-142.0 -59,-169.0 -60,-137.0 -61,-123.0 -62,-205.0 -63,-107.0 -64,-194.0 -65,-150.0 -66,-143.0 -67,-218.0 -68,-145.0 -69,-90.0 -70,-107.0 -71,-169.0 -72,-125.0 -73,-142.0 -74,-145.0 -75,-94.0 -76,-150.0 -77,-134.0 -78,-159.0 -79,-137.0 -80,-146.0 -81,-191.0 -82,-242.0 -83,-117.0 -84,-92.0 -85,-193.0 -86,-239.0 -87,-173.0 -88,-140.0 -89,-157.0 -90,-133.0 -91,-148.0 -92,-87.0 -93,-398.0 -94,-98.0 -95,-121.0 -96,-102.0 -97,-120.0 -98,-195.0 -99,-219.0 diff --git a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/models/checkpoint.pt b/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/models/checkpoint.pt deleted file mode 100644 index db7288b..0000000 Binary files a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/models/checkpoint.pt and /dev/null differ diff --git a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/params.json b/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/params.json deleted file mode 100644 index f57e151..0000000 --- a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/params.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "algo_name": "DQN", - "env_name": "CartPole-v0", - "train_eps": 200, - "test_eps": 20, - "gamma": 0.95, - "epsilon_start": 0.95, - "epsilon_end": 0.01, - "epsilon_decay": 500, - "lr": 0.0001, - "memory_capacity": 100000, - "batch_size": 64, - "target_update": 4, - "hidden_dim": 256, - "device": "cpu", - "seed": 10, - "result_path": "C:\\Users\\jiangji\\Desktop\\rl-tutorials\\codes\\DQN/outputs/CartPole-v0/20220823-173936/results", - "model_path": "C:\\Users\\jiangji\\Desktop\\rl-tutorials\\codes\\DQN/outputs/CartPole-v0/20220823-173936/models", - "show_fig": false, - "save_fig": true -} \ No newline at end of file diff --git a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/testing_curve.png b/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/testing_curve.png deleted file mode 100644 index 43ceb6f..0000000 Binary files a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/training_curve.png b/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/training_curve.png deleted file mode 100644 index 0e7b997..0000000 Binary files a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/training_curve.png and /dev/null differ diff --git a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/training_results.csv b/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/training_results.csv deleted file mode 100644 index 4429b6a..0000000 --- a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/training_results.csv +++ /dev/null @@ -1,201 +0,0 @@ -episodes,rewards -0,38.0 -1,16.0 -2,37.0 -3,15.0 -4,22.0 -5,34.0 -6,20.0 -7,12.0 -8,16.0 -9,14.0 -10,13.0 -11,21.0 -12,14.0 -13,12.0 -14,17.0 -15,12.0 -16,10.0 -17,14.0 -18,10.0 -19,10.0 -20,16.0 -21,9.0 -22,14.0 -23,13.0 -24,10.0 -25,9.0 -26,12.0 -27,12.0 -28,14.0 -29,11.0 -30,9.0 -31,8.0 -32,9.0 -33,11.0 -34,12.0 -35,10.0 -36,11.0 -37,10.0 -38,10.0 -39,18.0 -40,13.0 -41,15.0 -42,10.0 -43,9.0 -44,14.0 -45,14.0 -46,23.0 -47,17.0 -48,15.0 -49,15.0 -50,20.0 -51,28.0 -52,36.0 -53,36.0 -54,23.0 -55,27.0 -56,53.0 -57,19.0 -58,35.0 -59,62.0 -60,57.0 -61,38.0 -62,61.0 -63,65.0 -64,58.0 -65,43.0 -66,67.0 -67,56.0 -68,91.0 -69,128.0 -70,71.0 -71,126.0 -72,100.0 -73,200.0 -74,200.0 -75,200.0 -76,200.0 -77,200.0 -78,200.0 -79,200.0 -80,200.0 -81,200.0 -82,200.0 -83,200.0 -84,200.0 -85,200.0 -86,200.0 -87,200.0 -88,200.0 -89,200.0 -90,200.0 -91,200.0 -92,200.0 -93,200.0 -94,200.0 -95,200.0 -96,200.0 -97,200.0 -98,200.0 -99,200.0 -100,200.0 -101,200.0 -102,200.0 -103,200.0 -104,200.0 -105,200.0 -106,200.0 -107,200.0 -108,200.0 -109,200.0 -110,200.0 -111,200.0 -112,200.0 -113,200.0 -114,200.0 -115,200.0 -116,200.0 -117,200.0 -118,200.0 -119,200.0 -120,200.0 -121,200.0 -122,200.0 -123,200.0 -124,200.0 -125,200.0 -126,200.0 -127,200.0 -128,200.0 -129,200.0 -130,200.0 -131,200.0 -132,200.0 -133,200.0 -134,200.0 -135,200.0 -136,200.0 -137,200.0 -138,200.0 -139,200.0 -140,200.0 -141,200.0 -142,200.0 -143,200.0 -144,200.0 -145,200.0 -146,200.0 -147,200.0 -148,200.0 -149,200.0 -150,200.0 -151,200.0 -152,200.0 -153,200.0 -154,200.0 -155,200.0 -156,200.0 -157,200.0 -158,200.0 -159,200.0 -160,200.0 -161,200.0 -162,200.0 -163,200.0 -164,200.0 -165,200.0 -166,200.0 -167,200.0 -168,200.0 -169,200.0 -170,200.0 -171,200.0 -172,200.0 -173,200.0 -174,200.0 -175,200.0 -176,200.0 -177,200.0 -178,200.0 -179,200.0 -180,200.0 -181,200.0 -182,200.0 -183,200.0 -184,200.0 -185,200.0 -186,200.0 -187,200.0 -188,200.0 -189,200.0 -190,200.0 -191,200.0 -192,200.0 -193,200.0 -194,200.0 -195,200.0 -196,200.0 -197,200.0 -198,200.0 -199,200.0 diff --git a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/models/checkpoint.pt b/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/models/checkpoint.pt deleted file mode 100644 index e357d49..0000000 Binary files a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/models/checkpoint.pt and /dev/null differ diff --git a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/params.json b/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/params.json deleted file mode 100644 index c87e5de..0000000 --- a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/params.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "algo_name": "DQN", - "env_name": "CartPole-v1", - "train_eps": 2000, - "test_eps": 20, - "ep_max_steps": 100000, - "gamma": 0.99, - "epsilon_start": 0.95, - "epsilon_end": 0.01, - "epsilon_decay": 6000, - "lr": 1e-05, - "memory_capacity": 200000, - "batch_size": 64, - "target_update": 4, - "hidden_dim": 256, - "device": "cuda", - "seed": 10, - "show_fig": false, - "save_fig": true, - "result_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\DQN/outputs/CartPole-v1/20220828-214702/results", - "model_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\DQN/outputs/CartPole-v1/20220828-214702/models", - "n_states": 4, - "n_actions": 2 -} \ No newline at end of file diff --git a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/testing_curve.png b/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/testing_curve.png deleted file mode 100644 index f97050f..0000000 Binary files a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/testing_results.csv b/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/testing_results.csv deleted file mode 100644 index bb0b8f6..0000000 --- a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/testing_results.csv +++ /dev/null @@ -1,21 +0,0 @@ -episodes,rewards,steps -0,371.0,371 -1,446.0,446 -2,300.0,300 -3,500.0,500 -4,313.0,313 -5,500.0,500 -6,341.0,341 -7,489.0,489 -8,304.0,304 -9,358.0,358 -10,278.0,278 -11,500.0,500 -12,500.0,500 -13,500.0,500 -14,500.0,500 -15,476.0,476 -16,308.0,308 -17,394.0,394 -18,500.0,500 -19,500.0,500 diff --git a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/training_curve.png b/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/training_curve.png deleted file mode 100644 index a14bb8c..0000000 Binary files a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/training_curve.png and /dev/null differ diff --git a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/training_results.csv b/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/training_results.csv deleted file mode 100644 index 6bfc2ad..0000000 --- a/projects/codes/DQN/outputs/CartPole-v1/20220828-214702/results/training_results.csv +++ /dev/null @@ -1,2001 +0,0 @@ -episodes,rewards,steps -0,38.0,38 -1,16.0,16 -2,28.0,28 -3,10.0,10 -4,18.0,18 -5,10.0,10 -6,8.0,8 -7,19.0,19 -8,18.0,18 -9,32.0,32 -10,12.0,12 -11,14.0,14 -12,16.0,16 -13,20.0,20 -14,33.0,33 -15,24.0,24 -16,28.0,28 -17,33.0,33 -18,31.0,31 -19,14.0,14 -20,10.0,10 -21,19.0,19 -22,16.0,16 -23,19.0,19 -24,11.0,11 -25,23.0,23 -26,20.0,20 -27,26.0,26 -28,16.0,16 -29,16.0,16 -30,11.0,11 -31,13.0,13 -32,16.0,16 -33,42.0,42 -34,15.0,15 -35,38.0,38 -36,16.0,16 -37,46.0,46 -38,28.0,28 -39,60.0,60 -40,32.0,32 -41,9.0,9 -42,23.0,23 -43,19.0,19 -44,12.0,12 -45,17.0,17 -46,27.0,27 -47,22.0,22 -48,26.0,26 -49,11.0,11 -50,15.0,15 -51,9.0,9 -52,24.0,24 -53,29.0,29 -54,11.0,11 -55,16.0,16 -56,23.0,23 -57,14.0,14 -58,11.0,11 -59,16.0,16 -60,24.0,24 -61,27.0,27 -62,11.0,11 -63,20.0,20 -64,14.0,14 -65,11.0,11 -66,15.0,15 -67,16.0,16 -68,13.0,13 -69,28.0,28 -70,14.0,14 -71,10.0,10 -72,28.0,28 -73,20.0,20 -74,13.0,13 -75,11.0,11 -76,27.0,27 -77,15.0,15 -78,14.0,14 -79,14.0,14 -80,10.0,10 -81,11.0,11 -82,14.0,14 -83,13.0,13 -84,15.0,15 -85,13.0,13 -86,10.0,10 -87,11.0,11 -88,11.0,11 -89,13.0,13 -90,14.0,14 -91,25.0,25 -92,14.0,14 -93,14.0,14 -94,19.0,19 -95,18.0,18 -96,9.0,9 -97,9.0,9 -98,11.0,11 -99,19.0,19 -100,10.0,10 -101,40.0,40 -102,10.0,10 -103,13.0,13 -104,13.0,13 -105,18.0,18 -106,13.0,13 -107,11.0,11 -108,11.0,11 -109,18.0,18 -110,20.0,20 -111,10.0,10 -112,24.0,24 -113,9.0,9 -114,10.0,10 -115,13.0,13 -116,21.0,21 -117,12.0,12 -118,14.0,14 -119,10.0,10 -120,10.0,10 -121,16.0,16 -122,10.0,10 -123,18.0,18 -124,13.0,13 -125,17.0,17 -126,14.0,14 -127,12.0,12 -128,16.0,16 -129,11.0,11 -130,15.0,15 -131,10.0,10 -132,13.0,13 -133,17.0,17 -134,9.0,9 -135,34.0,34 -136,23.0,23 -137,14.0,14 -138,17.0,17 -139,13.0,13 -140,27.0,27 -141,15.0,15 -142,16.0,16 -143,15.0,15 -144,11.0,11 -145,12.0,12 -146,9.0,9 -147,30.0,30 -148,12.0,12 -149,12.0,12 -150,13.0,13 -151,14.0,14 -152,17.0,17 -153,10.0,10 -154,15.0,15 -155,10.0,10 -156,14.0,14 -157,22.0,22 -158,12.0,12 -159,11.0,11 -160,34.0,34 -161,11.0,11 -162,12.0,12 -163,18.0,18 -164,9.0,9 -165,17.0,17 -166,16.0,16 -167,10.0,10 -168,17.0,17 -169,11.0,11 -170,21.0,21 -171,15.0,15 -172,17.0,17 -173,11.0,11 -174,23.0,23 -175,10.0,10 -176,25.0,25 -177,12.0,12 -178,10.0,10 -179,16.0,16 -180,14.0,14 -181,21.0,21 -182,11.0,11 -183,12.0,12 -184,11.0,11 -185,10.0,10 -186,11.0,11 -187,17.0,17 -188,10.0,10 -189,14.0,14 -190,11.0,11 -191,12.0,12 -192,9.0,9 -193,11.0,11 -194,11.0,11 -195,16.0,16 -196,15.0,15 -197,10.0,10 -198,9.0,9 -199,17.0,17 -200,12.0,12 -201,9.0,9 -202,11.0,11 -203,9.0,9 -204,9.0,9 -205,16.0,16 -206,15.0,15 -207,13.0,13 -208,11.0,11 -209,13.0,13 -210,17.0,17 -211,8.0,8 -212,8.0,8 -213,12.0,12 -214,15.0,15 -215,13.0,13 -216,14.0,14 -217,11.0,11 -218,14.0,14 -219,13.0,13 -220,12.0,12 -221,9.0,9 -222,10.0,10 -223,10.0,10 -224,11.0,11 -225,9.0,9 -226,16.0,16 -227,23.0,23 -228,13.0,13 -229,16.0,16 -230,9.0,9 -231,12.0,12 -232,11.0,11 -233,10.0,10 -234,13.0,13 -235,15.0,15 -236,12.0,12 -237,11.0,11 -238,9.0,9 -239,11.0,11 -240,11.0,11 -241,11.0,11 -242,12.0,12 -243,8.0,8 -244,8.0,8 -245,10.0,10 -246,12.0,12 -247,12.0,12 -248,9.0,9 -249,12.0,12 -250,13.0,13 -251,11.0,11 -252,12.0,12 -253,10.0,10 -254,10.0,10 -255,11.0,11 -256,17.0,17 -257,11.0,11 -258,14.0,14 -259,12.0,12 -260,10.0,10 -261,11.0,11 -262,16.0,16 -263,13.0,13 -264,13.0,13 -265,15.0,15 -266,11.0,11 -267,8.0,8 -268,13.0,13 -269,15.0,15 -270,11.0,11 -271,9.0,9 -272,10.0,10 -273,11.0,11 -274,11.0,11 -275,9.0,9 -276,18.0,18 -277,13.0,13 -278,11.0,11 -279,14.0,14 -280,12.0,12 -281,16.0,16 -282,10.0,10 -283,12.0,12 -284,13.0,13 -285,9.0,9 -286,14.0,14 -287,26.0,26 -288,9.0,9 -289,10.0,10 -290,12.0,12 -291,13.0,13 -292,8.0,8 -293,13.0,13 -294,12.0,12 -295,11.0,11 -296,14.0,14 -297,10.0,10 -298,11.0,11 -299,12.0,12 -300,9.0,9 -301,11.0,11 -302,11.0,11 -303,15.0,15 -304,11.0,11 -305,11.0,11 -306,13.0,13 -307,8.0,8 -308,9.0,9 -309,10.0,10 -310,12.0,12 -311,13.0,13 -312,9.0,9 -313,15.0,15 -314,11.0,11 -315,12.0,12 -316,12.0,12 -317,15.0,15 -318,13.0,13 -319,8.0,8 -320,16.0,16 -321,9.0,9 -322,11.0,11 -323,12.0,12 -324,16.0,16 -325,9.0,9 -326,13.0,13 -327,13.0,13 -328,15.0,15 -329,12.0,12 -330,12.0,12 -331,8.0,8 -332,11.0,11 -333,15.0,15 -334,12.0,12 -335,11.0,11 -336,13.0,13 -337,13.0,13 -338,16.0,16 -339,11.0,11 -340,8.0,8 -341,10.0,10 -342,14.0,14 -343,18.0,18 -344,11.0,11 -345,10.0,10 -346,11.0,11 -347,11.0,11 -348,20.0,20 -349,14.0,14 -350,10.0,10 -351,14.0,14 -352,9.0,9 -353,9.0,9 -354,12.0,12 -355,9.0,9 -356,10.0,10 -357,9.0,9 -358,10.0,10 -359,10.0,10 -360,22.0,22 -361,11.0,11 -362,12.0,12 -363,11.0,11 -364,8.0,8 -365,24.0,24 -366,11.0,11 -367,10.0,10 -368,10.0,10 -369,10.0,10 -370,10.0,10 -371,9.0,9 -372,9.0,9 -373,21.0,21 -374,10.0,10 -375,12.0,12 -376,14.0,14 -377,15.0,15 -378,10.0,10 -379,17.0,17 -380,8.0,8 -381,14.0,14 -382,11.0,11 -383,9.0,9 -384,10.0,10 -385,9.0,9 -386,15.0,15 -387,11.0,11 -388,17.0,17 -389,12.0,12 -390,11.0,11 -391,15.0,15 -392,10.0,10 -393,13.0,13 -394,12.0,12 -395,10.0,10 -396,12.0,12 -397,9.0,9 -398,14.0,14 -399,9.0,9 -400,13.0,13 -401,10.0,10 -402,13.0,13 -403,16.0,16 -404,9.0,9 -405,8.0,8 -406,11.0,11 -407,9.0,9 -408,15.0,15 -409,12.0,12 -410,15.0,15 -411,15.0,15 -412,15.0,15 -413,14.0,14 -414,12.0,12 -415,11.0,11 -416,14.0,14 -417,12.0,12 -418,14.0,14 -419,11.0,11 -420,8.0,8 -421,9.0,9 -422,13.0,13 -423,13.0,13 -424,8.0,8 -425,10.0,10 -426,10.0,10 -427,15.0,15 -428,14.0,14 -429,9.0,9 -430,12.0,12 -431,13.0,13 -432,12.0,12 -433,10.0,10 -434,14.0,14 -435,11.0,11 -436,12.0,12 -437,14.0,14 -438,10.0,10 -439,12.0,12 -440,9.0,9 -441,15.0,15 -442,12.0,12 -443,10.0,10 -444,8.0,8 -445,12.0,12 -446,14.0,14 -447,12.0,12 -448,9.0,9 -449,10.0,10 -450,13.0,13 -451,9.0,9 -452,10.0,10 -453,9.0,9 -454,11.0,11 -455,10.0,10 -456,18.0,18 -457,16.0,16 -458,10.0,10 -459,11.0,11 -460,15.0,15 -461,12.0,12 -462,11.0,11 -463,12.0,12 -464,11.0,11 -465,10.0,10 -466,12.0,12 -467,10.0,10 -468,12.0,12 -469,15.0,15 -470,11.0,11 -471,10.0,10 -472,12.0,12 -473,9.0,9 -474,13.0,13 -475,11.0,11 -476,15.0,15 -477,10.0,10 -478,11.0,11 -479,13.0,13 -480,10.0,10 -481,10.0,10 -482,10.0,10 -483,10.0,10 -484,15.0,15 -485,11.0,11 -486,12.0,12 -487,16.0,16 -488,10.0,10 -489,16.0,16 -490,11.0,11 -491,9.0,9 -492,9.0,9 -493,18.0,18 -494,10.0,10 -495,9.0,9 -496,40.0,40 -497,21.0,21 -498,10.0,10 -499,36.0,36 -500,37.0,37 -501,22.0,22 -502,30.0,30 -503,23.0,23 -504,35.0,35 -505,48.0,48 -506,32.0,32 -507,21.0,21 -508,28.0,28 -509,29.0,29 -510,10.0,10 -511,27.0,27 -512,20.0,20 -513,23.0,23 -514,24.0,24 -515,21.0,21 -516,25.0,25 -517,20.0,20 -518,15.0,15 -519,23.0,23 -520,14.0,14 -521,18.0,18 -522,18.0,18 -523,18.0,18 -524,18.0,18 -525,20.0,20 -526,13.0,13 -527,21.0,21 -528,20.0,20 -529,17.0,17 -530,17.0,17 -531,17.0,17 -532,20.0,20 -533,15.0,15 -534,17.0,17 -535,17.0,17 -536,16.0,16 -537,16.0,16 -538,14.0,14 -539,21.0,21 -540,22.0,22 -541,14.0,14 -542,20.0,20 -543,25.0,25 -544,18.0,18 -545,22.0,22 -546,21.0,21 -547,20.0,20 -548,23.0,23 -549,20.0,20 -550,20.0,20 -551,25.0,25 -552,18.0,18 -553,14.0,14 -554,16.0,16 -555,16.0,16 -556,15.0,15 -557,26.0,26 -558,18.0,18 -559,20.0,20 -560,27.0,27 -561,18.0,18 -562,20.0,20 -563,20.0,20 -564,19.0,19 -565,26.0,26 -566,21.0,21 -567,25.0,25 -568,24.0,24 -569,24.0,24 -570,24.0,24 -571,17.0,17 -572,28.0,28 -573,20.0,20 -574,22.0,22 -575,16.0,16 -576,22.0,22 -577,14.0,14 -578,27.0,27 -579,29.0,29 -580,19.0,19 -581,22.0,22 -582,29.0,29 -583,29.0,29 -584,23.0,23 -585,22.0,22 -586,21.0,21 -587,18.0,18 -588,28.0,28 -589,29.0,29 -590,23.0,23 -591,23.0,23 -592,20.0,20 -593,32.0,32 -594,38.0,38 -595,29.0,29 -596,25.0,25 -597,22.0,22 -598,37.0,37 -599,20.0,20 -600,17.0,17 -601,22.0,22 -602,23.0,23 -603,28.0,28 -604,31.0,31 -605,23.0,23 -606,26.0,26 -607,22.0,22 -608,27.0,27 -609,32.0,32 -610,33.0,33 -611,27.0,27 -612,23.0,23 -613,38.0,38 -614,26.0,26 -615,27.0,27 -616,30.0,30 -617,22.0,22 -618,27.0,27 -619,38.0,38 -620,34.0,34 -621,39.0,39 -622,24.0,24 -623,29.0,29 -624,26.0,26 -625,30.0,30 -626,33.0,33 -627,34.0,34 -628,27.0,27 -629,26.0,26 -630,27.0,27 -631,37.0,37 -632,38.0,38 -633,46.0,46 -634,48.0,48 -635,56.0,56 -636,39.0,39 -637,18.0,18 -638,63.0,63 -639,51.0,51 -640,45.0,45 -641,27.0,27 -642,56.0,56 -643,32.0,32 -644,49.0,49 -645,40.0,40 -646,59.0,59 -647,52.0,52 -648,36.0,36 -649,43.0,43 -650,54.0,54 -651,59.0,59 -652,58.0,58 -653,61.0,61 -654,66.0,66 -655,38.0,38 -656,33.0,33 -657,96.0,96 -658,82.0,82 -659,56.0,56 -660,42.0,42 -661,38.0,38 -662,48.0,48 -663,83.0,83 -664,33.0,33 -665,72.0,72 -666,41.0,41 -667,57.0,57 -668,54.0,54 -669,69.0,69 -670,63.0,63 -671,81.0,81 -672,69.0,69 -673,65.0,65 -674,55.0,55 -675,64.0,64 -676,54.0,54 -677,93.0,93 -678,47.0,47 -679,84.0,84 -680,46.0,46 -681,63.0,63 -682,51.0,51 -683,64.0,64 -684,58.0,58 -685,72.0,72 -686,35.0,35 -687,59.0,59 -688,124.0,124 -689,64.0,64 -690,59.0,59 -691,77.0,77 -692,55.0,55 -693,63.0,63 -694,100.0,100 -695,100.0,100 -696,58.0,58 -697,85.0,85 -698,50.0,50 -699,57.0,57 -700,59.0,59 -701,72.0,72 -702,200.0,200 -703,118.0,118 -704,63.0,63 -705,125.0,125 -706,80.0,80 -707,49.0,49 -708,52.0,52 -709,71.0,71 -710,68.0,68 -711,71.0,71 -712,60.0,60 -713,58.0,58 -714,192.0,192 -715,57.0,57 -716,93.0,93 -717,107.0,107 -718,59.0,59 -719,71.0,71 -720,81.0,81 -721,76.0,76 -722,98.0,98 -723,95.0,95 -724,99.0,99 -725,132.0,132 -726,99.0,99 -727,58.0,58 -728,95.0,95 -729,79.0,79 -730,70.0,70 -731,76.0,76 -732,58.0,58 -733,174.0,174 -734,58.0,58 -735,178.0,178 -736,92.0,92 -737,114.0,114 -738,101.0,101 -739,59.0,59 -740,171.0,171 -741,179.0,179 -742,85.0,85 -743,115.0,115 -744,74.0,74 -745,99.0,99 -746,174.0,174 -747,124.0,124 -748,101.0,101 -749,106.0,106 -750,75.0,75 -751,70.0,70 -752,139.0,139 -753,76.0,76 -754,86.0,86 -755,82.0,82 -756,51.0,51 -757,78.0,78 -758,67.0,67 -759,72.0,72 -760,83.0,83 -761,58.0,58 -762,109.0,109 -763,62.0,62 -764,74.0,74 -765,83.0,83 -766,111.0,111 -767,67.0,67 -768,57.0,57 -769,59.0,59 -770,112.0,112 -771,197.0,197 -772,111.0,111 -773,90.0,90 -774,111.0,111 -775,81.0,81 -776,72.0,72 -777,80.0,80 -778,130.0,130 -779,156.0,156 -780,100.0,100 -781,85.0,85 -782,66.0,66 -783,76.0,76 -784,105.0,105 -785,57.0,57 -786,201.0,201 -787,176.0,176 -788,175.0,175 -789,198.0,198 -790,73.0,73 -791,79.0,79 -792,59.0,59 -793,55.0,55 -794,84.0,84 -795,131.0,131 -796,67.0,67 -797,199.0,199 -798,94.0,94 -799,97.0,97 -800,94.0,94 -801,185.0,185 -802,98.0,98 -803,136.0,136 -804,141.0,141 -805,81.0,81 -806,77.0,77 -807,100.0,100 -808,99.0,99 -809,133.0,133 -810,154.0,154 -811,74.0,74 -812,79.0,79 -813,94.0,94 -814,168.0,168 -815,338.0,338 -816,64.0,64 -817,112.0,112 -818,69.0,69 -819,143.0,143 -820,170.0,170 -821,170.0,170 -822,77.0,77 -823,83.0,83 -824,104.0,104 -825,152.0,152 -826,198.0,198 -827,159.0,159 -828,235.0,235 -829,76.0,76 -830,201.0,201 -831,289.0,289 -832,113.0,113 -833,294.0,294 -834,74.0,74 -835,416.0,416 -836,194.0,194 -837,85.0,85 -838,170.0,170 -839,208.0,208 -840,177.0,177 -841,83.0,83 -842,82.0,82 -843,183.0,183 -844,90.0,90 -845,398.0,398 -846,244.0,244 -847,99.0,99 -848,310.0,310 -849,195.0,195 -850,183.0,183 -851,162.0,162 -852,115.0,115 -853,82.0,82 -854,233.0,233 -855,102.0,102 -856,262.0,262 -857,300.0,300 -858,245.0,245 -859,299.0,299 -860,150.0,150 -861,199.0,199 -862,79.0,79 -863,74.0,74 -864,113.0,113 -865,152.0,152 -866,126.0,126 -867,68.0,68 -868,185.0,185 -869,156.0,156 -870,63.0,63 -871,121.0,121 -872,83.0,83 -873,72.0,72 -874,337.0,337 -875,179.0,179 -876,325.0,325 -877,115.0,115 -878,217.0,217 -879,74.0,74 -880,90.0,90 -881,218.0,218 -882,82.0,82 -883,173.0,173 -884,106.0,106 -885,83.0,83 -886,68.0,68 -887,173.0,173 -888,159.0,159 -889,57.0,57 -890,80.0,80 -891,302.0,302 -892,71.0,71 -893,59.0,59 -894,153.0,153 -895,129.0,129 -896,63.0,63 -897,147.0,147 -898,82.0,82 -899,186.0,186 -900,74.0,74 -901,81.0,81 -902,61.0,61 -903,88.0,88 -904,101.0,101 -905,60.0,60 -906,154.0,154 -907,202.0,202 -908,96.0,96 -909,81.0,81 -910,91.0,91 -911,77.0,77 -912,63.0,63 -913,154.0,154 -914,57.0,57 -915,86.0,86 -916,84.0,84 -917,66.0,66 -918,141.0,141 -919,88.0,88 -920,89.0,89 -921,49.0,49 -922,97.0,97 -923,50.0,50 -924,211.0,211 -925,69.0,69 -926,278.0,278 -927,75.0,75 -928,60.0,60 -929,57.0,57 -930,200.0,200 -931,101.0,101 -932,70.0,70 -933,93.0,93 -934,61.0,61 -935,80.0,80 -936,94.0,94 -937,53.0,53 -938,223.0,223 -939,142.0,142 -940,74.0,74 -941,60.0,60 -942,75.0,75 -943,78.0,78 -944,81.0,81 -945,51.0,51 -946,215.0,215 -947,64.0,64 -948,70.0,70 -949,85.0,85 -950,102.0,102 -951,48.0,48 -952,69.0,69 -953,65.0,65 -954,70.0,70 -955,174.0,174 -956,46.0,46 -957,75.0,75 -958,75.0,75 -959,62.0,62 -960,71.0,71 -961,67.0,67 -962,48.0,48 -963,64.0,64 -964,58.0,58 -965,64.0,64 -966,82.0,82 -967,70.0,70 -968,68.0,68 -969,48.0,48 -970,48.0,48 -971,53.0,53 -972,80.0,80 -973,46.0,46 -974,101.0,101 -975,303.0,303 -976,59.0,59 -977,212.0,212 -978,64.0,64 -979,76.0,76 -980,69.0,69 -981,241.0,241 -982,46.0,46 -983,45.0,45 -984,124.0,124 -985,99.0,99 -986,210.0,210 -987,67.0,67 -988,78.0,78 -989,58.0,58 -990,54.0,54 -991,63.0,63 -992,37.0,37 -993,46.0,46 -994,63.0,63 -995,48.0,48 -996,70.0,70 -997,58.0,58 -998,88.0,88 -999,62.0,62 -1000,173.0,173 -1001,99.0,99 -1002,47.0,47 -1003,47.0,47 -1004,74.0,74 -1005,101.0,101 -1006,42.0,42 -1007,46.0,46 -1008,61.0,61 -1009,42.0,42 -1010,48.0,48 -1011,60.0,60 -1012,42.0,42 -1013,53.0,53 -1014,54.0,54 -1015,62.0,62 -1016,98.0,98 -1017,50.0,50 -1018,39.0,39 -1019,60.0,60 -1020,52.0,52 -1021,46.0,46 -1022,68.0,68 -1023,40.0,40 -1024,41.0,41 -1025,54.0,54 -1026,66.0,66 -1027,112.0,112 -1028,55.0,55 -1029,46.0,46 -1030,72.0,72 -1031,54.0,54 -1032,51.0,51 -1033,43.0,43 -1034,66.0,66 -1035,59.0,59 -1036,57.0,57 -1037,68.0,68 -1038,63.0,63 -1039,38.0,38 -1040,48.0,48 -1041,58.0,58 -1042,58.0,58 -1043,116.0,116 -1044,52.0,52 -1045,180.0,180 -1046,91.0,91 -1047,292.0,292 -1048,65.0,65 -1049,46.0,46 -1050,40.0,40 -1051,192.0,192 -1052,46.0,46 -1053,52.0,52 -1054,50.0,50 -1055,37.0,37 -1056,136.0,136 -1057,46.0,46 -1058,35.0,35 -1059,89.0,89 -1060,34.0,34 -1061,101.0,101 -1062,102.0,102 -1063,166.0,166 -1064,62.0,62 -1065,40.0,40 -1066,37.0,37 -1067,45.0,45 -1068,45.0,45 -1069,48.0,48 -1070,67.0,67 -1071,87.0,87 -1072,51.0,51 -1073,103.0,103 -1074,46.0,46 -1075,52.0,52 -1076,40.0,40 -1077,47.0,47 -1078,49.0,49 -1079,35.0,35 -1080,46.0,46 -1081,38.0,38 -1082,36.0,36 -1083,219.0,219 -1084,57.0,57 -1085,39.0,39 -1086,48.0,48 -1087,37.0,37 -1088,46.0,46 -1089,37.0,37 -1090,65.0,65 -1091,39.0,39 -1092,44.0,44 -1093,85.0,85 -1094,50.0,50 -1095,39.0,39 -1096,57.0,57 -1097,221.0,221 -1098,35.0,35 -1099,59.0,59 -1100,46.0,46 -1101,38.0,38 -1102,37.0,37 -1103,62.0,62 -1104,59.0,59 -1105,46.0,46 -1106,40.0,40 -1107,74.0,74 -1108,58.0,58 -1109,37.0,37 -1110,56.0,56 -1111,52.0,52 -1112,45.0,45 -1113,76.0,76 -1114,54.0,54 -1115,37.0,37 -1116,41.0,41 -1117,47.0,47 -1118,56.0,56 -1119,39.0,39 -1120,37.0,37 -1121,42.0,42 -1122,59.0,59 -1123,38.0,38 -1124,49.0,49 -1125,49.0,49 -1126,130.0,130 -1127,52.0,52 -1128,45.0,45 -1129,43.0,43 -1130,57.0,57 -1131,37.0,37 -1132,43.0,43 -1133,60.0,60 -1134,58.0,58 -1135,57.0,57 -1136,35.0,35 -1137,57.0,57 -1138,154.0,154 -1139,39.0,39 -1140,48.0,48 -1141,78.0,78 -1142,58.0,58 -1143,70.0,70 -1144,52.0,52 -1145,53.0,53 -1146,58.0,58 -1147,40.0,40 -1148,74.0,74 -1149,39.0,39 -1150,69.0,69 -1151,78.0,78 -1152,34.0,34 -1153,44.0,44 -1154,45.0,45 -1155,173.0,173 -1156,190.0,190 -1157,47.0,47 -1158,36.0,36 -1159,52.0,52 -1160,44.0,44 -1161,50.0,50 -1162,96.0,96 -1163,88.0,88 -1164,38.0,38 -1165,44.0,44 -1166,102.0,102 -1167,49.0,49 -1168,46.0,46 -1169,68.0,68 -1170,46.0,46 -1171,50.0,50 -1172,58.0,58 -1173,46.0,46 -1174,50.0,50 -1175,40.0,40 -1176,44.0,44 -1177,75.0,75 -1178,109.0,109 -1179,51.0,51 -1180,44.0,44 -1181,42.0,42 -1182,41.0,41 -1183,62.0,62 -1184,48.0,48 -1185,60.0,60 -1186,52.0,52 -1187,73.0,73 -1188,39.0,39 -1189,42.0,42 -1190,89.0,89 -1191,64.0,64 -1192,40.0,40 -1193,42.0,42 -1194,59.0,59 -1195,48.0,48 -1196,45.0,45 -1197,48.0,48 -1198,171.0,171 -1199,77.0,77 -1200,97.0,97 -1201,43.0,43 -1202,86.0,86 -1203,62.0,62 -1204,67.0,67 -1205,86.0,86 -1206,77.0,77 -1207,88.0,88 -1208,73.0,73 -1209,80.0,80 -1210,94.0,94 -1211,71.0,71 -1212,96.0,96 -1213,65.0,65 -1214,61.0,61 -1215,63.0,63 -1216,72.0,72 -1217,78.0,78 -1218,92.0,92 -1219,64.0,64 -1220,76.0,76 -1221,69.0,69 -1222,86.0,86 -1223,93.0,93 -1224,70.0,70 -1225,67.0,67 -1226,89.0,89 -1227,72.0,72 -1228,106.0,106 -1229,76.0,76 -1230,218.0,218 -1231,64.0,64 -1232,224.0,224 -1233,68.0,68 -1234,217.0,217 -1235,216.0,216 -1236,205.0,205 -1237,234.0,234 -1238,196.0,196 -1239,217.0,217 -1240,213.0,213 -1241,247.0,247 -1242,295.0,295 -1243,197.0,197 -1244,212.0,212 -1245,196.0,196 -1246,226.0,226 -1247,228.0,228 -1248,240.0,240 -1249,189.0,189 -1250,190.0,190 -1251,242.0,242 -1252,204.0,204 -1253,201.0,201 -1254,189.0,189 -1255,225.0,225 -1256,212.0,212 -1257,198.0,198 -1258,284.0,284 -1259,197.0,197 -1260,194.0,194 -1261,230.0,230 -1262,200.0,200 -1263,207.0,207 -1264,207.0,207 -1265,233.0,233 -1266,213.0,213 -1267,275.0,275 -1268,201.0,201 -1269,201.0,201 -1270,202.0,202 -1271,264.0,264 -1272,212.0,212 -1273,490.0,490 -1274,222.0,222 -1275,244.0,244 -1276,500.0,500 -1277,244.0,244 -1278,246.0,246 -1279,237.0,237 -1280,210.0,210 -1281,274.0,274 -1282,258.0,258 -1283,405.0,405 -1284,216.0,216 -1285,500.0,500 -1286,218.0,218 -1287,361.0,361 -1288,262.0,262 -1289,500.0,500 -1290,194.0,194 -1291,361.0,361 -1292,194.0,194 -1293,229.0,229 -1294,361.0,361 -1295,270.0,270 -1296,297.0,297 -1297,225.0,225 -1298,214.0,214 -1299,256.0,256 -1300,330.0,330 -1301,347.0,347 -1302,372.0,372 -1303,183.0,183 -1304,300.0,300 -1305,313.0,313 -1306,227.0,227 -1307,307.0,307 -1308,296.0,296 -1309,212.0,212 -1310,244.0,244 -1311,206.0,206 -1312,262.0,262 -1313,274.0,274 -1314,225.0,225 -1315,209.0,209 -1316,272.0,272 -1317,213.0,213 -1318,262.0,262 -1319,214.0,214 -1320,224.0,224 -1321,368.0,368 -1322,264.0,264 -1323,243.0,243 -1324,299.0,299 -1325,210.0,210 -1326,310.0,310 -1327,252.0,252 -1328,201.0,201 -1329,193.0,193 -1330,220.0,220 -1331,224.0,224 -1332,203.0,203 -1333,268.0,268 -1334,288.0,288 -1335,330.0,330 -1336,331.0,331 -1337,249.0,249 -1338,222.0,222 -1339,237.0,237 -1340,204.0,204 -1341,329.0,329 -1342,232.0,232 -1343,175.0,175 -1344,251.0,251 -1345,259.0,259 -1346,220.0,220 -1347,246.0,246 -1348,215.0,215 -1349,257.0,257 -1350,350.0,350 -1351,269.0,269 -1352,266.0,266 -1353,220.0,220 -1354,276.0,276 -1355,281.0,281 -1356,200.0,200 -1357,274.0,274 -1358,260.0,260 -1359,393.0,393 -1360,240.0,240 -1361,197.0,197 -1362,273.0,273 -1363,220.0,220 -1364,228.0,228 -1365,337.0,337 -1366,203.0,203 -1367,500.0,500 -1368,214.0,214 -1369,271.0,271 -1370,211.0,211 -1371,264.0,264 -1372,338.0,338 -1373,298.0,298 -1374,358.0,358 -1375,454.0,454 -1376,317.0,317 -1377,283.0,283 -1378,441.0,441 -1379,343.0,343 -1380,270.0,270 -1381,263.0,263 -1382,405.0,405 -1383,255.0,255 -1384,500.0,500 -1385,389.0,389 -1386,212.0,212 -1387,339.0,339 -1388,225.0,225 -1389,500.0,500 -1390,467.0,467 -1391,237.0,237 -1392,257.0,257 -1393,352.0,352 -1394,264.0,264 -1395,452.0,452 -1396,388.0,388 -1397,447.0,447 -1398,258.0,258 -1399,269.0,269 -1400,264.0,264 -1401,238.0,238 -1402,258.0,258 -1403,433.0,433 -1404,500.0,500 -1405,298.0,298 -1406,500.0,500 -1407,287.0,287 -1408,329.0,329 -1409,500.0,500 -1410,424.0,424 -1411,239.0,239 -1412,350.0,350 -1413,287.0,287 -1414,388.0,388 -1415,498.0,498 -1416,454.0,454 -1417,351.0,351 -1418,277.0,277 -1419,256.0,256 -1420,339.0,339 -1421,338.0,338 -1422,339.0,339 -1423,292.0,292 -1424,500.0,500 -1425,264.0,264 -1426,381.0,381 -1427,320.0,320 -1428,500.0,500 -1429,388.0,388 -1430,500.0,500 -1431,500.0,500 -1432,500.0,500 -1433,309.0,309 -1434,470.0,470 -1435,496.0,496 -1436,326.0,326 -1437,500.0,500 -1438,500.0,500 -1439,284.0,284 -1440,309.0,309 -1441,349.0,349 -1442,245.0,245 -1443,407.0,407 -1444,305.0,305 -1445,233.0,233 -1446,469.0,469 -1447,304.0,304 -1448,303.0,303 -1449,500.0,500 -1450,257.0,257 -1451,336.0,336 -1452,500.0,500 -1453,440.0,440 -1454,500.0,500 -1455,500.0,500 -1456,317.0,317 -1457,500.0,500 -1458,475.0,475 -1459,395.0,395 -1460,331.0,331 -1461,374.0,374 -1462,500.0,500 -1463,246.0,246 -1464,355.0,355 -1465,500.0,500 -1466,500.0,500 -1467,260.0,260 -1468,500.0,500 -1469,437.0,437 -1470,500.0,500 -1471,367.0,367 -1472,388.0,388 -1473,239.0,239 -1474,493.0,493 -1475,322.0,322 -1476,500.0,500 -1477,416.0,416 -1478,403.0,403 -1479,500.0,500 -1480,355.0,355 -1481,500.0,500 -1482,437.0,437 -1483,433.0,433 -1484,500.0,500 -1485,246.0,246 -1486,364.0,364 -1487,255.0,255 -1488,500.0,500 -1489,443.0,443 -1490,500.0,500 -1491,287.0,287 -1492,402.0,402 -1493,500.0,500 -1494,499.0,499 -1495,500.0,500 -1496,248.0,248 -1497,266.0,266 -1498,500.0,500 -1499,338.0,338 -1500,395.0,395 -1501,304.0,304 -1502,433.0,433 -1503,351.0,351 -1504,230.0,230 -1505,352.0,352 -1506,500.0,500 -1507,265.0,265 -1508,500.0,500 -1509,244.0,244 -1510,392.0,392 -1511,467.0,467 -1512,353.0,353 -1513,500.0,500 -1514,473.0,473 -1515,246.0,246 -1516,336.0,336 -1517,317.0,317 -1518,325.0,325 -1519,481.0,481 -1520,374.0,374 -1521,231.0,231 -1522,500.0,500 -1523,234.0,234 -1524,290.0,290 -1525,297.0,297 -1526,299.0,299 -1527,364.0,364 -1528,326.0,326 -1529,482.0,482 -1530,233.0,233 -1531,500.0,500 -1532,264.0,264 -1533,314.0,314 -1534,500.0,500 -1535,433.0,433 -1536,415.0,415 -1537,288.0,288 -1538,458.0,458 -1539,308.0,308 -1540,500.0,500 -1541,459.0,459 -1542,273.0,273 -1543,500.0,500 -1544,500.0,500 -1545,470.0,470 -1546,364.0,364 -1547,425.0,425 -1548,374.0,374 -1549,399.0,399 -1550,500.0,500 -1551,500.0,500 -1552,500.0,500 -1553,497.0,497 -1554,272.0,272 -1555,268.0,268 -1556,292.0,292 -1557,500.0,500 -1558,281.0,281 -1559,272.0,272 -1560,411.0,411 -1561,500.0,500 -1562,430.0,430 -1563,415.0,415 -1564,500.0,500 -1565,464.0,464 -1566,436.0,436 -1567,500.0,500 -1568,344.0,344 -1569,395.0,395 -1570,385.0,385 -1571,232.0,232 -1572,260.0,260 -1573,499.0,499 -1574,411.0,411 -1575,500.0,500 -1576,290.0,290 -1577,321.0,321 -1578,481.0,481 -1579,473.0,473 -1580,301.0,301 -1581,404.0,404 -1582,410.0,410 -1583,437.0,437 -1584,311.0,311 -1585,500.0,500 -1586,231.0,231 -1587,376.0,376 -1588,359.0,359 -1589,276.0,276 -1590,457.0,457 -1591,500.0,500 -1592,318.0,318 -1593,500.0,500 -1594,309.0,309 -1595,481.0,481 -1596,274.0,274 -1597,331.0,331 -1598,500.0,500 -1599,259.0,259 -1600,500.0,500 -1601,291.0,291 -1602,499.0,499 -1603,256.0,256 -1604,266.0,266 -1605,500.0,500 -1606,325.0,325 -1607,359.0,359 -1608,274.0,274 -1609,357.0,357 -1610,465.0,465 -1611,500.0,500 -1612,435.0,435 -1613,268.0,268 -1614,251.0,251 -1615,252.0,252 -1616,275.0,275 -1617,284.0,284 -1618,416.0,416 -1619,229.0,229 -1620,500.0,500 -1621,265.0,265 -1622,354.0,354 -1623,251.0,251 -1624,381.0,381 -1625,279.0,279 -1626,267.0,267 -1627,232.0,232 -1628,365.0,365 -1629,500.0,500 -1630,489.0,489 -1631,500.0,500 -1632,243.0,243 -1633,253.0,253 -1634,334.0,334 -1635,500.0,500 -1636,280.0,280 -1637,268.0,268 -1638,356.0,356 -1639,500.0,500 -1640,253.0,253 -1641,244.0,244 -1642,237.0,237 -1643,421.0,421 -1644,247.0,247 -1645,378.0,378 -1646,252.0,252 -1647,282.0,282 -1648,247.0,247 -1649,289.0,289 -1650,226.0,226 -1651,289.0,289 -1652,480.0,480 -1653,500.0,500 -1654,270.0,270 -1655,309.0,309 -1656,292.0,292 -1657,272.0,272 -1658,233.0,233 -1659,261.0,261 -1660,500.0,500 -1661,316.0,316 -1662,310.0,310 -1663,276.0,276 -1664,315.0,315 -1665,267.0,267 -1666,420.0,420 -1667,320.0,320 -1668,500.0,500 -1669,370.0,370 -1670,500.0,500 -1671,246.0,246 -1672,296.0,296 -1673,256.0,256 -1674,281.0,281 -1675,327.0,327 -1676,242.0,242 -1677,393.0,393 -1678,332.0,332 -1679,288.0,288 -1680,250.0,250 -1681,391.0,391 -1682,296.0,296 -1683,490.0,490 -1684,224.0,224 -1685,369.0,369 -1686,311.0,311 -1687,335.0,335 -1688,227.0,227 -1689,500.0,500 -1690,242.0,242 -1691,363.0,363 -1692,284.0,284 -1693,254.0,254 -1694,386.0,386 -1695,353.0,353 -1696,443.0,443 -1697,500.0,500 -1698,253.0,253 -1699,293.0,293 -1700,500.0,500 -1701,259.0,259 -1702,254.0,254 -1703,343.0,343 -1704,313.0,313 -1705,253.0,253 -1706,409.0,409 -1707,474.0,474 -1708,226.0,226 -1709,325.0,325 -1710,441.0,441 -1711,252.0,252 -1712,430.0,430 -1713,287.0,287 -1714,318.0,318 -1715,323.0,323 -1716,268.0,268 -1717,288.0,288 -1718,292.0,292 -1719,323.0,323 -1720,291.0,291 -1721,399.0,399 -1722,263.0,263 -1723,385.0,385 -1724,229.0,229 -1725,282.0,282 -1726,347.0,347 -1727,257.0,257 -1728,264.0,264 -1729,282.0,282 -1730,402.0,402 -1731,328.0,328 -1732,227.0,227 -1733,272.0,272 -1734,462.0,462 -1735,236.0,236 -1736,302.0,302 -1737,275.0,275 -1738,280.0,280 -1739,331.0,331 -1740,352.0,352 -1741,500.0,500 -1742,389.0,389 -1743,303.0,303 -1744,398.0,398 -1745,359.0,359 -1746,436.0,436 -1747,233.0,233 -1748,295.0,295 -1749,234.0,234 -1750,290.0,290 -1751,261.0,261 -1752,248.0,248 -1753,263.0,263 -1754,368.0,368 -1755,500.0,500 -1756,276.0,276 -1757,243.0,243 -1758,500.0,500 -1759,289.0,289 -1760,500.0,500 -1761,275.0,275 -1762,297.0,297 -1763,250.0,250 -1764,405.0,405 -1765,261.0,261 -1766,239.0,239 -1767,351.0,351 -1768,301.0,301 -1769,384.0,384 -1770,240.0,240 -1771,258.0,258 -1772,258.0,258 -1773,249.0,249 -1774,254.0,254 -1775,374.0,374 -1776,347.0,347 -1777,377.0,377 -1778,263.0,263 -1779,229.0,229 -1780,292.0,292 -1781,259.0,259 -1782,259.0,259 -1783,260.0,260 -1784,267.0,267 -1785,256.0,256 -1786,306.0,306 -1787,238.0,238 -1788,257.0,257 -1789,252.0,252 -1790,293.0,293 -1791,273.0,273 -1792,308.0,308 -1793,291.0,291 -1794,342.0,342 -1795,273.0,273 -1796,257.0,257 -1797,221.0,221 -1798,276.0,276 -1799,279.0,279 -1800,269.0,269 -1801,291.0,291 -1802,359.0,359 -1803,431.0,431 -1804,375.0,375 -1805,298.0,298 -1806,253.0,253 -1807,276.0,276 -1808,258.0,258 -1809,242.0,242 -1810,397.0,397 -1811,394.0,394 -1812,323.0,323 -1813,257.0,257 -1814,343.0,343 -1815,287.0,287 -1816,372.0,372 -1817,294.0,294 -1818,261.0,261 -1819,270.0,270 -1820,284.0,284 -1821,247.0,247 -1822,372.0,372 -1823,292.0,292 -1824,357.0,357 -1825,247.0,247 -1826,355.0,355 -1827,447.0,447 -1828,251.0,251 -1829,375.0,375 -1830,262.0,262 -1831,340.0,340 -1832,243.0,243 -1833,261.0,261 -1834,247.0,247 -1835,499.0,499 -1836,242.0,242 -1837,237.0,237 -1838,255.0,255 -1839,320.0,320 -1840,216.0,216 -1841,356.0,356 -1842,261.0,261 -1843,247.0,247 -1844,229.0,229 -1845,238.0,238 -1846,233.0,233 -1847,232.0,232 -1848,234.0,234 -1849,391.0,391 -1850,273.0,273 -1851,438.0,438 -1852,402.0,402 -1853,394.0,394 -1854,287.0,287 -1855,230.0,230 -1856,251.0,251 -1857,278.0,278 -1858,378.0,378 -1859,249.0,249 -1860,271.0,271 -1861,296.0,296 -1862,256.0,256 -1863,270.0,270 -1864,500.0,500 -1865,385.0,385 -1866,284.0,284 -1867,248.0,248 -1868,283.0,283 -1869,246.0,246 -1870,339.0,339 -1871,415.0,415 -1872,276.0,276 -1873,275.0,275 -1874,457.0,457 -1875,500.0,500 -1876,281.0,281 -1877,324.0,324 -1878,414.0,414 -1879,314.0,314 -1880,449.0,449 -1881,281.0,281 -1882,368.0,368 -1883,322.0,322 -1884,235.0,235 -1885,337.0,337 -1886,500.0,500 -1887,311.0,311 -1888,347.0,347 -1889,365.0,365 -1890,272.0,272 -1891,342.0,342 -1892,379.0,379 -1893,247.0,247 -1894,321.0,321 -1895,403.0,403 -1896,464.0,464 -1897,330.0,330 -1898,361.0,361 -1899,500.0,500 -1900,433.0,433 -1901,500.0,500 -1902,293.0,293 -1903,386.0,386 -1904,283.0,283 -1905,366.0,366 -1906,278.0,278 -1907,279.0,279 -1908,415.0,415 -1909,480.0,480 -1910,500.0,500 -1911,353.0,353 -1912,500.0,500 -1913,269.0,269 -1914,500.0,500 -1915,385.0,385 -1916,246.0,246 -1917,481.0,481 -1918,500.0,500 -1919,462.0,462 -1920,373.0,373 -1921,500.0,500 -1922,272.0,272 -1923,500.0,500 -1924,495.0,495 -1925,500.0,500 -1926,295.0,295 -1927,249.0,249 -1928,256.0,256 -1929,500.0,500 -1930,317.0,317 -1931,500.0,500 -1932,317.0,317 -1933,258.0,258 -1934,380.0,380 -1935,402.0,402 -1936,500.0,500 -1937,319.0,319 -1938,319.0,319 -1939,500.0,500 -1940,447.0,447 -1941,500.0,500 -1942,459.0,459 -1943,500.0,500 -1944,299.0,299 -1945,290.0,290 -1946,318.0,318 -1947,500.0,500 -1948,500.0,500 -1949,500.0,500 -1950,500.0,500 -1951,478.0,478 -1952,500.0,500 -1953,500.0,500 -1954,330.0,330 -1955,366.0,366 -1956,500.0,500 -1957,283.0,283 -1958,300.0,300 -1959,292.0,292 -1960,270.0,270 -1961,500.0,500 -1962,474.0,474 -1963,328.0,328 -1964,389.0,389 -1965,500.0,500 -1966,493.0,493 -1967,357.0,357 -1968,500.0,500 -1969,500.0,500 -1970,500.0,500 -1971,320.0,320 -1972,385.0,385 -1973,500.0,500 -1974,422.0,422 -1975,405.0,405 -1976,500.0,500 -1977,363.0,363 -1978,329.0,329 -1979,309.0,309 -1980,500.0,500 -1981,500.0,500 -1982,277.0,277 -1983,461.0,461 -1984,262.0,262 -1985,500.0,500 -1986,500.0,500 -1987,370.0,370 -1988,500.0,500 -1989,255.0,255 -1990,449.0,449 -1991,361.0,361 -1992,319.0,319 -1993,382.0,382 -1994,363.0,363 -1995,500.0,500 -1996,336.0,336 -1997,500.0,500 -1998,500.0,500 -1999,500.0,500 diff --git a/projects/codes/DQN/task0.py b/projects/codes/DQN/task0.py new file mode 100644 index 0000000..e69ed45 --- /dev/null +++ b/projects/codes/DQN/task0.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-12 11:09:54 +LastEditor: JiangJi +LastEditTime: 2022-10-31 00:13:31 +Discription: CartPole-v1,Acrobot-v1 +''' +import sys,os +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add to system path +import gym +from common.utils import all_seed,merge_class_attrs +from common.models import MLP +from common.memories import ReplayBuffer +from common.launcher import Launcher +from envs.register import register_env +from dqn import DQN +from config.config import GeneralConfigDQN,AlgoConfigDQN +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigDQN()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigDQN()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=True) # create env + if cfg.seed !=0: # set random seed + all_seed(env,seed=cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + # cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters + model = MLP(n_states,n_actions,hidden_dim=cfg.hidden_dim) + memory = ReplayBuffer(cfg.buffer_size) # replay buffer + agent = DQN(model,memory,cfg) # create agent + return env, agent + def train_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + ep_step += 1 + action = agent.sample_action(state) # sample action + next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions under new_step_api of OpenAI Gym + agent.memory.push(state, action, reward, + next_state, terminated) # save transitions + agent.update() # update agent + state = next_state # update next state for env + ep_reward += reward # + if terminated: + break + return agent,ep_reward,ep_step + def test_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + ep_step += 1 + action = agent.predict_action(state) # sample action + next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions under new_step_api of OpenAI Gym + state = next_state # update next state for env + ep_reward += reward # + if terminated: + break + return agent,ep_reward,ep_step + # def train(self,env, agent,cfg,logger): + # ''' 训练 + # ''' + # logger.info("Start training!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.train_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # ep_step += 1 + # action = agent.sample_action(state) # sample action + # next_state, reward, terminated, truncated , info = env.step(action) # update env and return transitions under new_step_api of OpenAI Gym + # agent.memory.push(state, action, reward, + # next_state, terminated) # save transitions + # state = next_state # update next state for env + # agent.update() # update agent + # ep_reward += reward # + # if terminated: + # break + # if (i_ep + 1) % cfg.target_update == 0: # target net update, target_update means "C" in pseucodes + # agent.target_net.load_state_dict(agent.policy_net.state_dict()) + # steps.append(ep_step) + # rewards.append(ep_reward) + # logger.info(f'Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.2f}: Epislon: {agent.epsilon:.3f}') + # logger.info("Finish training!") + # env.close() + # res_dic = {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + # return res_dic + + # def test(self,cfg, env, agent,logger): + # logger.info("Start testing!") + # logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + # rewards = [] # record rewards for all episodes + # steps = [] # record steps for all episodes + # for i_ep in range(cfg.test_eps): + # ep_reward = 0 # reward per episode + # ep_step = 0 + # state = env.reset() # reset and obtain initial state + # for _ in range(cfg.max_steps): + # ep_step+=1 + # action = agent.predict_action(state) # predict action + # next_state, reward, terminated, _, _ = env.step(action) + # state = next_state + # ep_reward += reward + # if terminated: + # break + # steps.append(ep_step) + # rewards.append(ep_reward) + # logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.2f}") + # logger.info("Finish testing!") + # env.close() + # return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + + +if __name__ == "__main__": + main = Main() + main.run() + diff --git a/projects/codes/DQN/main.py b/projects/codes/DQN/task1.py similarity index 54% rename from projects/codes/DQN/main.py rename to projects/codes/DQN/task1.py index 651a98e..590d0c2 100644 --- a/projects/codes/DQN/main.py +++ b/projects/codes/DQN/task1.py @@ -1,3 +1,13 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-24 08:21:31 +LastEditor: JiangJi +LastEditTime: 2022-10-26 09:50:49 +Discription: Not finished +''' import sys,os os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." curr_path = os.path.dirname(os.path.abspath(__file__)) # current path @@ -15,6 +25,73 @@ from common.memories import ReplayBuffer from common.launcher import Launcher from envs.register import register_env from dqn import DQN +import torch.nn as nn +import torch.nn.functional as F +import torchvision.transforms as T +from PIL import Image +resize = T.Compose([T.ToPILImage(), + T.Resize(40, interpolation=Image.CUBIC), + T.ToTensor()]) + +# xvfb-run -s "-screen 0 640x480x24" python main1.py +def get_cart_location(env,screen_width): + world_width = env.x_threshold * 2 + scale = screen_width / world_width + return int(env.state[0] * scale + screen_width / 2.0) # MIDDLE OF CART + +def get_screen(env): + # Returned screen requested by gym is 400x600x3, but is sometimes larger + # such as 800x1200x3. Transpose it into torch order (CHW). + screen = env.render().transpose((2, 0, 1)) + # Cart is in the lower half, so strip off the top and bottom of the screen + _, screen_height, screen_width = screen.shape + screen = screen[:, int(screen_height*0.4):int(screen_height * 0.8)] + view_width = int(screen_width * 0.6) + cart_location = get_cart_location(env,screen_width) + if cart_location < view_width // 2: + slice_range = slice(view_width) + elif cart_location > (screen_width - view_width // 2): + slice_range = slice(-view_width, None) + else: + slice_range = slice(cart_location - view_width // 2, + cart_location + view_width // 2) + # Strip off the edges, so that we have a square image centered on a cart + screen = screen[:, :, slice_range] + # Convert to float, rescale, convert to torch tensor + # (this doesn't require a copy) + screen = np.ascontiguousarray(screen, dtype=np.float32) / 255 + screen = torch.from_numpy(screen) + # Resize, and add a batch dimension (BCHW) + return resize(screen) + + +class CNN(nn.Module): + + def __init__(self, h, w, outputs): + super(CNN, self).__init__() + self.conv1 = nn.Conv2d(3, 16, kernel_size=5, stride=2) + self.bn1 = nn.BatchNorm2d(16) + self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2) + self.bn2 = nn.BatchNorm2d(32) + self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2) + self.bn3 = nn.BatchNorm2d(32) + + # Number of Linear input connections depends on output of conv2d layers + # and therefore the input image size, so compute it. + def conv2d_size_out(size, kernel_size = 5, stride = 2): + return (size - (kernel_size - 1) - 1) // stride + 1 + convw = conv2d_size_out(conv2d_size_out(conv2d_size_out(w))) + convh = conv2d_size_out(conv2d_size_out(conv2d_size_out(h))) + linear_input_size = convw * convh * 32 + self.head = nn.Linear(linear_input_size, outputs) + + # Called with either one element to determine next action, or a batch + # during optimization. Returns tensor([[left0exp,right0exp]...]). + def forward(self, x): + x = F.relu(self.bn1(self.conv1(x))) + x = F.relu(self.bn2(self.conv2(x))) + x = F.relu(self.bn3(self.conv3(x))) + return self.head(x.view(x.size(0), -1)) class Main(Launcher): def get_args(self): """ hyperparameters @@ -22,20 +99,20 @@ class Main(Launcher): curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # obtain current time parser = argparse.ArgumentParser(description="hyperparameters") parser.add_argument('--algo_name',default='DQN',type=str,help="name of algorithm") - parser.add_argument('--env_name',default='CartPole-v0',type=str,help="name of environment") - parser.add_argument('--train_eps',default=200,type=int,help="episodes of training") + parser.add_argument('--env_name',default='CartPole-v1',type=str,help="name of environment") + parser.add_argument('--train_eps',default=800,type=int,help="episodes of training") parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") parser.add_argument('--ep_max_steps',default = 100000,type=int,help="steps per episode, much larger value can simulate infinite steps") - parser.add_argument('--gamma',default=0.95,type=float,help="discounted factor") + parser.add_argument('--gamma',default=0.999,type=float,help="discounted factor") parser.add_argument('--epsilon_start',default=0.95,type=float,help="initial value of epsilon") parser.add_argument('--epsilon_end',default=0.01,type=float,help="final value of epsilon") parser.add_argument('--epsilon_decay',default=500,type=int,help="decay rate of epsilon, the higher value, the slower decay") parser.add_argument('--lr',default=0.0001,type=float,help="learning rate") parser.add_argument('--memory_capacity',default=100000,type=int,help="memory capacity") - parser.add_argument('--batch_size',default=64,type=int) + parser.add_argument('--batch_size',default=128,type=int) parser.add_argument('--target_update',default=4,type=int) parser.add_argument('--hidden_dim',default=256,type=int) - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") + parser.add_argument('--device',default='cuda',type=str,help="cpu or cuda") parser.add_argument('--seed',default=10,type=int,help="seed") parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") @@ -48,11 +125,10 @@ class Main(Launcher): args = {**vars(args)} # type(dict) return args - def env_agent_config(cfg): + def env_agent_config(self,cfg): ''' create env and agent ''' - register_env(cfg['env_name']) - env = gym.make(cfg['env_name']) + env = gym.make('CartPole-v1', new_step_api=True, render_mode='single_rgb_array').unwrapped if cfg['seed'] !=0: # set random seed all_seed(env,seed=cfg["seed"]) try: # state dimension @@ -62,12 +138,15 @@ class Main(Launcher): n_actions = env.action_space.n # action dimension print(f"n_states: {n_states}, n_actions: {n_actions}") cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters - model = MLP(n_states,n_actions,hidden_dim=cfg["hidden_dim"]) + env.reset() + init_screen = get_screen(env) + _, screen_height, screen_width = init_screen.shape + model = CNN(screen_height, screen_width, n_actions) memory = ReplayBuffer(cfg["memory_capacity"]) # replay buffer agent = DQN(model,memory,cfg) # create agent return env, agent - def train(cfg, env, agent): + def train(self,cfg, env, agent): ''' 训练 ''' print("Start training!") @@ -78,12 +157,18 @@ class Main(Launcher): ep_reward = 0 # reward per episode ep_step = 0 state = env.reset() # reset and obtain initial state + last_screen = get_screen(env) + current_screen = get_screen(env) + state = current_screen - last_screen for _ in range(cfg['ep_max_steps']): ep_step += 1 action = agent.sample_action(state) # sample action - next_state, reward, done, _ = env.step(action) # update env and return transitions - agent.memory.push(state, action, reward, - next_state, done) # save transitions + _, reward, done, _,_ = env.step(action) # update env and return transitions + last_screen = current_screen + current_screen = get_screen(env) + next_state = current_screen - last_screen + agent.memory.push(state.cpu().numpy(), action, reward, + next_state.cpu().numpy(), done) # save transitions state = next_state # update next state for env agent.update() # update agent ep_reward += reward # @@ -94,13 +179,13 @@ class Main(Launcher): steps.append(ep_step) rewards.append(ep_reward) if (i_ep + 1) % 10 == 0: - print(f'Episode: {i_ep+1}/{cfg["train_eps"]}, Reward: {ep_reward:.2f}: Epislon: {agent.epsilon:.3f}') + print(f'Episode: {i_ep+1}/{cfg["train_eps"]}, Reward: {ep_reward:.2f}, step: {ep_step:d}, Epislon: {agent.epsilon:.3f}') print("Finish training!") env.close() res_dic = {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} return res_dic - def test(cfg, env, agent): + def test(self,cfg, env, agent): print("Start testing!") print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") rewards = [] # record rewards for all episodes @@ -109,10 +194,16 @@ class Main(Launcher): ep_reward = 0 # reward per episode ep_step = 0 state = env.reset() # reset and obtain initial state + last_screen = get_screen(env) + current_screen = get_screen(env) + state = current_screen - last_screen for _ in range(cfg['ep_max_steps']): ep_step+=1 action = agent.predict_action(state) # predict action - next_state, reward, done, _ = env.step(action) + _, reward, done, _,_ = env.step(action) + last_screen = current_screen + current_screen = get_screen(env) + next_state = current_screen - last_screen state = next_state ep_reward += reward if done: diff --git a/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/config.yaml b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/config.yaml new file mode 100644 index 0000000..326f84e --- /dev/null +++ b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: FirstVisitMC + device: cpu + env_name: Racetrack-v0 + eval_eps: 10 + eval_per_episode: 5 + load_checkpoint: false + load_path: tasks + max_steps: 200 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 200 +algo_cfg: + epsilon: 0.15 + gamma: 0.9 + lr: 0.1 diff --git a/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/logs/log.txt b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/logs/log.txt new file mode 100644 index 0000000..993059b --- /dev/null +++ b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/logs/log.txt @@ -0,0 +1,210 @@ +2022-11-06 01:05:04 - r - INFO: - n_states: 4, n_actions: 9 +2022-11-06 01:05:04 - r - INFO: - Start training! +2022-11-06 01:05:04 - r - INFO: - Env: Racetrack-v0, Algorithm: FirstVisitMC, Device: cpu +2022-11-06 01:05:40 - r - INFO: - Episode: 1/200, Reward: -760.000, Step: 200 +2022-11-06 01:05:58 - r - INFO: - Episode: 2/200, Reward: -560.000, Step: 200 +2022-11-06 01:05:59 - r - INFO: - Episode: 3/200, Reward: -156.000, Step: 66 +2022-11-06 01:06:17 - r - INFO: - Episode: 4/200, Reward: -500.000, Step: 200 +2022-11-06 01:06:38 - r - INFO: - Episode: 5/200, Reward: -600.000, Step: 200 +2022-11-06 01:06:38 - r - INFO: - Current episode 5 has the best eval reward: -208.000 +2022-11-06 01:06:52 - r - INFO: - Episode: 6/200, Reward: -350.000, Step: 200 +2022-11-06 01:07:07 - r - INFO: - Episode: 7/200, Reward: -430.000, Step: 200 +2022-11-06 01:07:10 - r - INFO: - Episode: 8/200, Reward: -206.000, Step: 96 +2022-11-06 01:07:31 - r - INFO: - Episode: 9/200, Reward: -460.000, Step: 200 +2022-11-06 01:07:45 - r - INFO: - Episode: 10/200, Reward: -410.000, Step: 200 +2022-11-06 01:07:45 - r - INFO: - Current episode 10 has the best eval reward: -204.000 +2022-11-06 01:07:58 - r - INFO: - Episode: 11/200, Reward: -400.000, Step: 200 +2022-11-06 01:08:08 - r - INFO: - Episode: 12/200, Reward: -380.000, Step: 200 +2022-11-06 01:08:09 - r - INFO: - Episode: 13/200, Reward: -155.000, Step: 75 +2022-11-06 01:08:24 - r - INFO: - Episode: 14/200, Reward: -400.000, Step: 200 +2022-11-06 01:08:37 - r - INFO: - Episode: 15/200, Reward: -350.000, Step: 200 +2022-11-06 01:08:37 - r - INFO: - Current episode 15 has the best eval reward: -203.000 +2022-11-06 01:08:51 - r - INFO: - Episode: 16/200, Reward: -400.000, Step: 200 +2022-11-06 01:09:05 - r - INFO: - Episode: 17/200, Reward: -360.000, Step: 200 +2022-11-06 01:09:23 - r - INFO: - Episode: 18/200, Reward: -420.000, Step: 200 +2022-11-06 01:09:37 - r - INFO: - Episode: 19/200, Reward: -430.000, Step: 200 +2022-11-06 01:09:48 - r - INFO: - Episode: 20/200, Reward: -360.000, Step: 200 +2022-11-06 01:09:48 - r - INFO: - Current episode 20 has the best eval reward: -187.300 +2022-11-06 01:10:08 - r - INFO: - Episode: 21/200, Reward: -420.000, Step: 200 +2022-11-06 01:10:19 - r - INFO: - Episode: 22/200, Reward: -390.000, Step: 200 +2022-11-06 01:10:19 - r - INFO: - Episode: 23/200, Reward: -59.000, Step: 49 +2022-11-06 01:10:33 - r - INFO: - Episode: 24/200, Reward: -390.000, Step: 200 +2022-11-06 01:10:33 - r - INFO: - Episode: 25/200, Reward: 2.000, Step: 8 +2022-11-06 01:10:36 - r - INFO: - Episode: 26/200, Reward: -217.000, Step: 117 +2022-11-06 01:10:43 - r - INFO: - Episode: 27/200, Reward: -287.000, Step: 167 +2022-11-06 01:10:47 - r - INFO: - Episode: 28/200, Reward: -248.000, Step: 118 +2022-11-06 01:11:04 - r - INFO: - Episode: 29/200, Reward: -370.000, Step: 200 +2022-11-06 01:11:19 - r - INFO: - Episode: 30/200, Reward: -390.000, Step: 200 +2022-11-06 01:11:32 - r - INFO: - Episode: 31/200, Reward: -370.000, Step: 200 +2022-11-06 01:11:39 - r - INFO: - Episode: 32/200, Reward: -360.000, Step: 200 +2022-11-06 01:11:57 - r - INFO: - Episode: 33/200, Reward: -420.000, Step: 200 +2022-11-06 01:12:16 - r - INFO: - Episode: 34/200, Reward: -430.000, Step: 200 +2022-11-06 01:12:34 - r - INFO: - Episode: 35/200, Reward: -430.000, Step: 200 +2022-11-06 01:12:55 - r - INFO: - Episode: 36/200, Reward: -430.000, Step: 200 +2022-11-06 01:13:09 - r - INFO: - Episode: 37/200, Reward: -380.000, Step: 200 +2022-11-06 01:13:27 - r - INFO: - Episode: 38/200, Reward: -420.000, Step: 200 +2022-11-06 01:13:40 - r - INFO: - Episode: 39/200, Reward: -350.000, Step: 200 +2022-11-06 01:13:55 - r - INFO: - Episode: 40/200, Reward: -370.000, Step: 200 +2022-11-06 01:14:09 - r - INFO: - Episode: 41/200, Reward: -400.000, Step: 200 +2022-11-06 01:14:26 - r - INFO: - Episode: 42/200, Reward: -410.000, Step: 200 +2022-11-06 01:14:40 - r - INFO: - Episode: 43/200, Reward: -360.000, Step: 200 +2022-11-06 01:14:40 - r - INFO: - Episode: 44/200, Reward: -16.000, Step: 16 +2022-11-06 01:14:40 - r - INFO: - Episode: 45/200, Reward: -23.000, Step: 13 +2022-11-06 01:14:52 - r - INFO: - Episode: 46/200, Reward: -390.000, Step: 200 +2022-11-06 01:15:08 - r - INFO: - Episode: 47/200, Reward: -390.000, Step: 200 +2022-11-06 01:15:09 - r - INFO: - Episode: 48/200, Reward: -109.000, Step: 79 +2022-11-06 01:15:22 - r - INFO: - Episode: 49/200, Reward: -300.000, Step: 200 +2022-11-06 01:15:39 - r - INFO: - Episode: 50/200, Reward: -370.000, Step: 200 +2022-11-06 01:15:55 - r - INFO: - Episode: 51/200, Reward: -460.000, Step: 200 +2022-11-06 01:16:11 - r - INFO: - Episode: 52/200, Reward: -350.000, Step: 200 +2022-11-06 01:16:23 - r - INFO: - Episode: 53/200, Reward: -320.000, Step: 200 +2022-11-06 01:16:32 - r - INFO: - Episode: 54/200, Reward: -310.000, Step: 200 +2022-11-06 01:16:47 - r - INFO: - Episode: 55/200, Reward: -390.000, Step: 200 +2022-11-06 01:17:01 - r - INFO: - Episode: 56/200, Reward: -370.000, Step: 200 +2022-11-06 01:17:19 - r - INFO: - Episode: 57/200, Reward: -390.000, Step: 200 +2022-11-06 01:17:34 - r - INFO: - Episode: 58/200, Reward: -350.000, Step: 200 +2022-11-06 01:17:35 - r - INFO: - Episode: 59/200, Reward: -123.000, Step: 73 +2022-11-06 01:17:39 - r - INFO: - Episode: 60/200, Reward: -204.000, Step: 124 +2022-11-06 01:17:40 - r - INFO: - Episode: 61/200, Reward: -39.000, Step: 29 +2022-11-06 01:17:41 - r - INFO: - Episode: 62/200, Reward: -155.000, Step: 85 +2022-11-06 01:17:42 - r - INFO: - Episode: 63/200, Reward: -108.000, Step: 58 +2022-11-06 01:17:49 - r - INFO: - Episode: 64/200, Reward: -249.000, Step: 169 +2022-11-06 01:17:51 - r - INFO: - Episode: 65/200, Reward: -170.000, Step: 100 +2022-11-06 01:17:51 - r - INFO: - Current episode 65 has the best eval reward: -181.800 +2022-11-06 01:17:51 - r - INFO: - Episode: 66/200, Reward: 1.000, Step: 9 +2022-11-06 01:17:51 - r - INFO: - Episode: 67/200, Reward: -23.000, Step: 23 +2022-11-06 01:17:52 - r - INFO: - Episode: 68/200, Reward: -104.000, Step: 74 +2022-11-06 01:17:56 - r - INFO: - Episode: 69/200, Reward: -223.000, Step: 123 +2022-11-06 01:18:11 - r - INFO: - Episode: 70/200, Reward: -350.000, Step: 200 +2022-11-06 01:18:13 - r - INFO: - Episode: 71/200, Reward: -124.000, Step: 104 +2022-11-06 01:18:13 - r - INFO: - Episode: 72/200, Reward: -20.000, Step: 20 +2022-11-06 01:18:26 - r - INFO: - Episode: 73/200, Reward: -360.000, Step: 200 +2022-11-06 01:18:26 - r - INFO: - Episode: 74/200, Reward: -67.000, Step: 37 +2022-11-06 01:18:40 - r - INFO: - Episode: 75/200, Reward: -360.000, Step: 200 +2022-11-06 01:18:41 - r - INFO: - Episode: 76/200, Reward: -71.000, Step: 41 +2022-11-06 01:18:41 - r - INFO: - Episode: 77/200, Reward: -23.000, Step: 23 +2022-11-06 01:18:41 - r - INFO: - Episode: 78/200, Reward: -41.000, Step: 21 +2022-11-06 01:18:41 - r - INFO: - Episode: 79/200, Reward: -1.000, Step: 11 +2022-11-06 01:18:50 - r - INFO: - Episode: 80/200, Reward: -270.000, Step: 200 +2022-11-06 01:18:50 - r - INFO: - Current episode 80 has the best eval reward: -163.100 +2022-11-06 01:19:02 - r - INFO: - Episode: 81/200, Reward: -330.000, Step: 200 +2022-11-06 01:19:10 - r - INFO: - Episode: 82/200, Reward: -290.000, Step: 200 +2022-11-06 01:19:11 - r - INFO: - Episode: 83/200, Reward: -2.000, Step: 12 +2022-11-06 01:19:25 - r - INFO: - Episode: 84/200, Reward: -300.000, Step: 200 +2022-11-06 01:19:37 - r - INFO: - Episode: 85/200, Reward: -380.000, Step: 200 +2022-11-06 01:19:37 - r - INFO: - Episode: 86/200, Reward: -47.000, Step: 37 +2022-11-06 01:19:53 - r - INFO: - Episode: 87/200, Reward: -350.000, Step: 200 +2022-11-06 01:20:04 - r - INFO: - Episode: 88/200, Reward: -308.000, Step: 188 +2022-11-06 01:20:21 - r - INFO: - Episode: 89/200, Reward: -370.000, Step: 200 +2022-11-06 01:20:27 - r - INFO: - Episode: 90/200, Reward: -214.000, Step: 154 +2022-11-06 01:20:43 - r - INFO: - Episode: 91/200, Reward: -290.000, Step: 200 +2022-11-06 01:21:00 - r - INFO: - Episode: 92/200, Reward: -370.000, Step: 200 +2022-11-06 01:21:01 - r - INFO: - Episode: 93/200, Reward: -32.000, Step: 22 +2022-11-06 01:21:21 - r - INFO: - Episode: 94/200, Reward: -400.000, Step: 200 +2022-11-06 01:21:25 - r - INFO: - Episode: 95/200, Reward: -217.000, Step: 127 +2022-11-06 01:21:41 - r - INFO: - Episode: 96/200, Reward: -330.000, Step: 200 +2022-11-06 01:21:55 - r - INFO: - Episode: 97/200, Reward: -380.000, Step: 200 +2022-11-06 01:22:16 - r - INFO: - Episode: 98/200, Reward: -320.000, Step: 200 +2022-11-06 01:22:32 - r - INFO: - Episode: 99/200, Reward: -300.000, Step: 200 +2022-11-06 01:22:46 - r - INFO: - Episode: 100/200, Reward: -350.000, Step: 200 +2022-11-06 01:23:00 - r - INFO: - Episode: 101/200, Reward: -400.000, Step: 200 +2022-11-06 01:23:11 - r - INFO: - Episode: 102/200, Reward: -330.000, Step: 200 +2022-11-06 01:23:29 - r - INFO: - Episode: 103/200, Reward: -360.000, Step: 200 +2022-11-06 01:23:45 - r - INFO: - Episode: 104/200, Reward: -380.000, Step: 200 +2022-11-06 01:24:06 - r - INFO: - Episode: 105/200, Reward: -400.000, Step: 200 +2022-11-06 01:24:16 - r - INFO: - Episode: 106/200, Reward: -290.000, Step: 200 +2022-11-06 01:24:19 - r - INFO: - Episode: 107/200, Reward: -203.000, Step: 103 +2022-11-06 01:24:19 - r - INFO: - Episode: 108/200, Reward: -74.000, Step: 54 +2022-11-06 01:24:36 - r - INFO: - Episode: 109/200, Reward: -330.000, Step: 200 +2022-11-06 01:24:54 - r - INFO: - Episode: 110/200, Reward: -380.000, Step: 200 +2022-11-06 01:25:03 - r - INFO: - Episode: 111/200, Reward: -263.000, Step: 173 +2022-11-06 01:25:20 - r - INFO: - Episode: 112/200, Reward: -290.000, Step: 200 +2022-11-06 01:25:34 - r - INFO: - Episode: 113/200, Reward: -340.000, Step: 200 +2022-11-06 01:25:34 - r - INFO: - Episode: 114/200, Reward: -86.000, Step: 66 +2022-11-06 01:25:50 - r - INFO: - Episode: 115/200, Reward: -340.000, Step: 200 +2022-11-06 01:25:52 - r - INFO: - Episode: 116/200, Reward: -160.000, Step: 110 +2022-11-06 01:26:07 - r - INFO: - Episode: 117/200, Reward: -340.000, Step: 200 +2022-11-06 01:26:15 - r - INFO: - Episode: 118/200, Reward: -320.000, Step: 200 +2022-11-06 01:26:29 - r - INFO: - Episode: 119/200, Reward: -320.000, Step: 200 +2022-11-06 01:26:43 - r - INFO: - Episode: 120/200, Reward: -360.000, Step: 200 +2022-11-06 01:26:56 - r - INFO: - Episode: 121/200, Reward: -330.000, Step: 200 +2022-11-06 01:27:09 - r - INFO: - Episode: 122/200, Reward: -350.000, Step: 200 +2022-11-06 01:27:25 - r - INFO: - Episode: 123/200, Reward: -300.000, Step: 200 +2022-11-06 01:27:38 - r - INFO: - Episode: 124/200, Reward: -320.000, Step: 200 +2022-11-06 01:27:39 - r - INFO: - Episode: 125/200, Reward: -70.000, Step: 40 +2022-11-06 01:27:39 - r - INFO: - Episode: 126/200, Reward: -59.000, Step: 39 +2022-11-06 01:27:55 - r - INFO: - Episode: 127/200, Reward: -340.000, Step: 200 +2022-11-06 01:27:56 - r - INFO: - Episode: 128/200, Reward: -87.000, Step: 77 +2022-11-06 01:28:13 - r - INFO: - Episode: 129/200, Reward: -330.000, Step: 200 +2022-11-06 01:28:22 - r - INFO: - Episode: 130/200, Reward: -260.000, Step: 200 +2022-11-06 01:28:38 - r - INFO: - Episode: 131/200, Reward: -290.000, Step: 200 +2022-11-06 01:28:57 - r - INFO: - Episode: 132/200, Reward: -330.000, Step: 200 +2022-11-06 01:29:07 - r - INFO: - Episode: 133/200, Reward: -340.000, Step: 200 +2022-11-06 01:29:08 - r - INFO: - Episode: 134/200, Reward: -78.000, Step: 48 +2022-11-06 01:29:23 - r - INFO: - Episode: 135/200, Reward: -390.000, Step: 200 +2022-11-06 01:29:33 - r - INFO: - Episode: 136/200, Reward: -320.000, Step: 200 +2022-11-06 01:29:51 - r - INFO: - Episode: 137/200, Reward: -360.000, Step: 200 +2022-11-06 01:30:06 - r - INFO: - Episode: 138/200, Reward: -340.000, Step: 200 +2022-11-06 01:30:10 - r - INFO: - Episode: 139/200, Reward: -185.000, Step: 115 +2022-11-06 01:30:26 - r - INFO: - Episode: 140/200, Reward: -340.000, Step: 200 +2022-11-06 01:30:43 - r - INFO: - Episode: 141/200, Reward: -250.000, Step: 200 +2022-11-06 01:30:57 - r - INFO: - Episode: 142/200, Reward: -347.000, Step: 197 +2022-11-06 01:31:11 - r - INFO: - Episode: 143/200, Reward: -320.000, Step: 200 +2022-11-06 01:31:25 - r - INFO: - Episode: 144/200, Reward: -330.000, Step: 200 +2022-11-06 01:31:37 - r - INFO: - Episode: 145/200, Reward: -270.000, Step: 200 +2022-11-06 01:31:55 - r - INFO: - Episode: 146/200, Reward: -380.000, Step: 200 +2022-11-06 01:32:10 - r - INFO: - Episode: 147/200, Reward: -320.000, Step: 200 +2022-11-06 01:32:27 - r - INFO: - Episode: 148/200, Reward: -340.000, Step: 200 +2022-11-06 01:32:38 - r - INFO: - Episode: 149/200, Reward: -310.000, Step: 200 +2022-11-06 01:32:57 - r - INFO: - Episode: 150/200, Reward: -290.000, Step: 200 +2022-11-06 01:33:10 - r - INFO: - Episode: 151/200, Reward: -380.000, Step: 200 +2022-11-06 01:33:21 - r - INFO: - Episode: 152/200, Reward: -281.000, Step: 181 +2022-11-06 01:33:21 - r - INFO: - Episode: 153/200, Reward: -30.000, Step: 30 +2022-11-06 01:33:33 - r - INFO: - Episode: 154/200, Reward: -280.000, Step: 200 +2022-11-06 01:33:45 - r - INFO: - Episode: 155/200, Reward: -300.000, Step: 200 +2022-11-06 01:33:59 - r - INFO: - Episode: 156/200, Reward: -300.000, Step: 200 +2022-11-06 01:34:10 - r - INFO: - Episode: 157/200, Reward: -300.000, Step: 200 +2022-11-06 01:34:28 - r - INFO: - Episode: 158/200, Reward: -370.000, Step: 200 +2022-11-06 01:34:45 - r - INFO: - Episode: 159/200, Reward: -320.000, Step: 200 +2022-11-06 01:34:52 - r - INFO: - Episode: 160/200, Reward: -250.000, Step: 200 +2022-11-06 01:35:04 - r - INFO: - Episode: 161/200, Reward: -370.000, Step: 200 +2022-11-06 01:35:16 - r - INFO: - Episode: 162/200, Reward: -290.000, Step: 200 +2022-11-06 01:35:31 - r - INFO: - Episode: 163/200, Reward: -320.000, Step: 200 +2022-11-06 01:35:41 - r - INFO: - Episode: 164/200, Reward: -290.000, Step: 200 +2022-11-06 01:35:41 - r - INFO: - Episode: 165/200, Reward: -44.000, Step: 44 +2022-11-06 01:35:53 - r - INFO: - Episode: 166/200, Reward: -216.000, Step: 196 +2022-11-06 01:36:06 - r - INFO: - Episode: 167/200, Reward: -340.000, Step: 200 +2022-11-06 01:36:23 - r - INFO: - Episode: 168/200, Reward: -360.000, Step: 200 +2022-11-06 01:36:38 - r - INFO: - Episode: 169/200, Reward: -310.000, Step: 200 +2022-11-06 01:36:51 - r - INFO: - Episode: 170/200, Reward: -320.000, Step: 200 +2022-11-06 01:37:08 - r - INFO: - Episode: 171/200, Reward: -280.000, Step: 200 +2022-11-06 01:37:17 - r - INFO: - Episode: 172/200, Reward: -290.000, Step: 200 +2022-11-06 01:37:33 - r - INFO: - Episode: 173/200, Reward: -280.000, Step: 200 +2022-11-06 01:37:45 - r - INFO: - Episode: 174/200, Reward: -300.000, Step: 200 +2022-11-06 01:38:02 - r - INFO: - Episode: 175/200, Reward: -350.000, Step: 200 +2022-11-06 01:38:17 - r - INFO: - Episode: 176/200, Reward: -320.000, Step: 200 +2022-11-06 01:38:31 - r - INFO: - Episode: 177/200, Reward: -320.000, Step: 200 +2022-11-06 01:38:47 - r - INFO: - Episode: 178/200, Reward: -320.000, Step: 200 +2022-11-06 01:39:03 - r - INFO: - Episode: 179/200, Reward: -300.000, Step: 200 +2022-11-06 01:39:04 - r - INFO: - Episode: 180/200, Reward: -117.000, Step: 87 +2022-11-06 01:39:06 - r - INFO: - Episode: 181/200, Reward: -158.000, Step: 88 +2022-11-06 01:39:23 - r - INFO: - Episode: 182/200, Reward: -300.000, Step: 200 +2022-11-06 01:39:34 - r - INFO: - Episode: 183/200, Reward: -290.000, Step: 200 +2022-11-06 01:39:51 - r - INFO: - Episode: 184/200, Reward: -350.000, Step: 200 +2022-11-06 01:40:09 - r - INFO: - Episode: 185/200, Reward: -310.000, Step: 200 +2022-11-06 01:40:10 - r - INFO: - Episode: 186/200, Reward: -58.000, Step: 38 +2022-11-06 01:40:26 - r - INFO: - Episode: 187/200, Reward: -290.000, Step: 200 +2022-11-06 01:40:42 - r - INFO: - Episode: 188/200, Reward: -310.000, Step: 200 +2022-11-06 01:40:57 - r - INFO: - Episode: 189/200, Reward: -350.000, Step: 200 +2022-11-06 01:41:12 - r - INFO: - Episode: 190/200, Reward: -300.000, Step: 200 +2022-11-06 01:41:32 - r - INFO: - Episode: 191/200, Reward: -380.000, Step: 200 +2022-11-06 01:41:37 - r - INFO: - Episode: 192/200, Reward: -230.000, Step: 200 +2022-11-06 01:41:37 - r - INFO: - Episode: 193/200, Reward: -26.000, Step: 26 +2022-11-06 01:41:56 - r - INFO: - Episode: 194/200, Reward: -340.000, Step: 200 +2022-11-06 01:42:09 - r - INFO: - Episode: 195/200, Reward: -280.000, Step: 200 +2022-11-06 01:42:10 - r - INFO: - Episode: 196/200, Reward: -106.000, Step: 66 +2022-11-06 01:42:10 - r - INFO: - Episode: 197/200, Reward: -7.000, Step: 17 +2022-11-06 01:42:20 - r - INFO: - Episode: 198/200, Reward: -248.000, Step: 178 +2022-11-06 01:42:22 - r - INFO: - Episode: 199/200, Reward: -161.000, Step: 101 +2022-11-06 01:42:22 - r - INFO: - Episode: 200/200, Reward: -3.000, Step: 13 +2022-11-06 01:42:22 - r - INFO: - Finish training! diff --git a/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/models/Q_table b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/models/Q_table new file mode 100644 index 0000000..3231a0b Binary files /dev/null and b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/models/Q_table differ diff --git a/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/results/learning_curve.png b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/results/learning_curve.png new file mode 100644 index 0000000..3799635 Binary files /dev/null and b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/results/learning_curve.png differ diff --git a/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/results/res.csv b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/results/res.csv new file mode 100644 index 0000000..214239b --- /dev/null +++ b/projects/codes/MonteCarlo/Train_Racetrack-v0_FirstVisitMC_20221106-010504/results/res.csv @@ -0,0 +1,201 @@ +episodes,rewards,steps +0,-760,200 +1,-560,200 +2,-156,66 +3,-500,200 +4,-600,200 +5,-350,200 +6,-430,200 +7,-206,96 +8,-460,200 +9,-410,200 +10,-400,200 +11,-380,200 +12,-155,75 +13,-400,200 +14,-350,200 +15,-400,200 +16,-360,200 +17,-420,200 +18,-430,200 +19,-360,200 +20,-420,200 +21,-390,200 +22,-59,49 +23,-390,200 +24,2,8 +25,-217,117 +26,-287,167 +27,-248,118 +28,-370,200 +29,-390,200 +30,-370,200 +31,-360,200 +32,-420,200 +33,-430,200 +34,-430,200 +35,-430,200 +36,-380,200 +37,-420,200 +38,-350,200 +39,-370,200 +40,-400,200 +41,-410,200 +42,-360,200 +43,-16,16 +44,-23,13 +45,-390,200 +46,-390,200 +47,-109,79 +48,-300,200 +49,-370,200 +50,-460,200 +51,-350,200 +52,-320,200 +53,-310,200 +54,-390,200 +55,-370,200 +56,-390,200 +57,-350,200 +58,-123,73 +59,-204,124 +60,-39,29 +61,-155,85 +62,-108,58 +63,-249,169 +64,-170,100 +65,1,9 +66,-23,23 +67,-104,74 +68,-223,123 +69,-350,200 +70,-124,104 +71,-20,20 +72,-360,200 +73,-67,37 +74,-360,200 +75,-71,41 +76,-23,23 +77,-41,21 +78,-1,11 +79,-270,200 +80,-330,200 +81,-290,200 +82,-2,12 +83,-300,200 +84,-380,200 +85,-47,37 +86,-350,200 +87,-308,188 +88,-370,200 +89,-214,154 +90,-290,200 +91,-370,200 +92,-32,22 +93,-400,200 +94,-217,127 +95,-330,200 +96,-380,200 +97,-320,200 +98,-300,200 +99,-350,200 +100,-400,200 +101,-330,200 +102,-360,200 +103,-380,200 +104,-400,200 +105,-290,200 +106,-203,103 +107,-74,54 +108,-330,200 +109,-380,200 +110,-263,173 +111,-290,200 +112,-340,200 +113,-86,66 +114,-340,200 +115,-160,110 +116,-340,200 +117,-320,200 +118,-320,200 +119,-360,200 +120,-330,200 +121,-350,200 +122,-300,200 +123,-320,200 +124,-70,40 +125,-59,39 +126,-340,200 +127,-87,77 +128,-330,200 +129,-260,200 +130,-290,200 +131,-330,200 +132,-340,200 +133,-78,48 +134,-390,200 +135,-320,200 +136,-360,200 +137,-340,200 +138,-185,115 +139,-340,200 +140,-250,200 +141,-347,197 +142,-320,200 +143,-330,200 +144,-270,200 +145,-380,200 +146,-320,200 +147,-340,200 +148,-310,200 +149,-290,200 +150,-380,200 +151,-281,181 +152,-30,30 +153,-280,200 +154,-300,200 +155,-300,200 +156,-300,200 +157,-370,200 +158,-320,200 +159,-250,200 +160,-370,200 +161,-290,200 +162,-320,200 +163,-290,200 +164,-44,44 +165,-216,196 +166,-340,200 +167,-360,200 +168,-310,200 +169,-320,200 +170,-280,200 +171,-290,200 +172,-280,200 +173,-300,200 +174,-350,200 +175,-320,200 +176,-320,200 +177,-320,200 +178,-300,200 +179,-117,87 +180,-158,88 +181,-300,200 +182,-290,200 +183,-350,200 +184,-310,200 +185,-58,38 +186,-290,200 +187,-310,200 +188,-350,200 +189,-300,200 +190,-380,200 +191,-230,200 +192,-26,26 +193,-340,200 +194,-280,200 +195,-106,66 +196,-7,17 +197,-248,178 +198,-161,101 +199,-3,13 diff --git a/projects/codes/MonteCarlo/agent.py b/projects/codes/MonteCarlo/agent.py index fe2a287..c426527 100644 --- a/projects/codes/MonteCarlo/agent.py +++ b/projects/codes/MonteCarlo/agent.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2021-03-12 16:14:34 LastEditor: John -LastEditTime: 2022-08-15 18:10:13 +LastEditTime: 2022-11-06 01:04:57 Discription: Environment: ''' @@ -17,15 +17,16 @@ import dill class FisrtVisitMC: ''' On-Policy First-Visit MC Control ''' - def __init__(self,n_actions,cfg): - self.n_actions = n_actions + def __init__(self,cfg): + self.n_actions = cfg.n_actions self.epsilon = cfg.epsilon self.gamma = cfg.gamma - self.Q_table = defaultdict(lambda: np.zeros(n_actions)) + self.Q_table = defaultdict(lambda: np.zeros(cfg.n_actions)) self.returns_sum = defaultdict(float) # 保存return之和 self.returns_count = defaultdict(float) - def sample(self,state): + def sample_action(self,state): + state = str(state) if state in self.Q_table.keys(): best_action = np.argmax(self.Q_table[state]) action_probs = np.ones(self.n_actions, dtype=float) * self.epsilon / self.n_actions @@ -34,7 +35,8 @@ class FisrtVisitMC: else: action = np.random.randint(0,self.n_actions) return action - def predict(self,state): + def predict_action(self,state): + state = str(state) if state in self.Q_table.keys(): best_action = np.argmax(self.Q_table[state]) action_probs = np.ones(self.n_actions, dtype=float) * self.epsilon / self.n_actions @@ -46,19 +48,20 @@ class FisrtVisitMC: def update(self,one_ep_transition): # Find all (state, action) pairs we've visited in this one_ep_transition # We convert each state to a tuple so that we can use it as a dict key - sa_in_episode = set([(tuple(x[0]), x[1]) for x in one_ep_transition]) + sa_in_episode = set([(str(x[0]), x[1]) for x in one_ep_transition]) for state, action in sa_in_episode: sa_pair = (state, action) # Find the first occurence of the (state, action) pair in the one_ep_transition + first_occurence_idx = next(i for i,x in enumerate(one_ep_transition) - if x[0] == state and x[1] == action) + if str(x[0]) == state and x[1] == action) # Sum up all rewards since the first occurance G = sum([x[2]*(self.gamma**i) for i,x in enumerate(one_ep_transition[first_occurence_idx:])]) # Calculate average return for this state over all sampled episodes self.returns_sum[sa_pair] += G self.returns_count[sa_pair] += 1.0 self.Q_table[state][action] = self.returns_sum[sa_pair] / self.returns_count[sa_pair] - def save(self,path=None): + def save_model(self,path=None): '''把 Q表格 的数据保存到文件中 ''' from pathlib import Path @@ -69,7 +72,7 @@ class FisrtVisitMC: pickle_module=dill ) - def load(self, path=None): + def load_model(self, path=None): '''从文件中读取数据到 Q表格 ''' self.Q_table =torch.load(f=path+"Q_table",pickle_module=dill) \ No newline at end of file diff --git a/projects/codes/MonteCarlo/config/config.py b/projects/codes/MonteCarlo/config/config.py new file mode 100644 index 0000000..d255547 --- /dev/null +++ b/projects/codes/MonteCarlo/config/config.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-11-06 00:31:35 +LastEditor: JiangJi +LastEditTime: 2022-11-06 00:45:44 +Discription: parameters of MonteCarlo +''' +from common.config import GeneralConfig,AlgoConfig + +class GeneralConfigMC(GeneralConfig): + def __init__(self) -> None: + self.env_name = "Racetrack-v0" # name of environment + self.algo_name = "FirstVisitMC" # name of algorithm + self.mode = "train" # train or test + self.seed = 1 # random seed + self.device = "cpu" # device to use + self.train_eps = 200 # number of episodes for training + self.test_eps = 20 # number of episodes for testing + self.max_steps = 200 # max steps for each episode + self.load_checkpoint = False + self.load_path = "tasks" # path to load model + self.show_fig = False # show figure or not + self.save_fig = True # save figure or not + +class AlgoConfigMC(AlgoConfig): + def __init__(self) -> None: + self.gamma = 0.90 # discount factor + self.epsilon = 0.15 # epsilon greedy + self.lr = 0.1 # learning rate \ No newline at end of file diff --git a/projects/codes/MonteCarlo/task0.py b/projects/codes/MonteCarlo/task0.py index d6e75bd..4570967 100644 --- a/projects/codes/MonteCarlo/task0.py +++ b/projects/codes/MonteCarlo/task0.py @@ -5,51 +5,82 @@ Author: John Email: johnjim0816@gmail.com Date: 2021-03-11 14:26:44 LastEditor: John -LastEditTime: 2022-08-15 18:12:13 +LastEditTime: 2022-11-06 00:44:56 Discription: Environment: ''' import sys,os -curr_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在绝对路径 -parent_path = os.path.dirname(curr_path) # 父路径 -sys.path.append(parent_path) # 添加路径到系统路径 +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path import datetime -import argparse -from common.utils import save_results,save_args,plot_rewards - +import gym +from envs.wrappers import CliffWalkingWapper +from envs.register import register_env +from common.utils import merge_class_attrs,all_seed +from common.launcher import Launcher from MonteCarlo.agent import FisrtVisitMC -from envs.racetrack import RacetrackEnv +from MonteCarlo.config.config import GeneralConfigMC,AlgoConfigMC + curr_time = datetime.datetime.now().strftime( "%Y%m%d-%H%M%S") # obtain current time - -def get_args(): - """ 超参数 - """ - curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # 获取当前时间 - parser = argparse.ArgumentParser(description="hyperparameters") - parser.add_argument('--algo_name',default='First-Visit MC',type=str,help="name of algorithm") - parser.add_argument('--env_name',default='Racetrack',type=str,help="name of environment") - parser.add_argument('--train_eps',default=200,type=int,help="episodes of training") - parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") - parser.add_argument('--gamma',default=0.9,type=float,help="discounted factor") - parser.add_argument('--epsilon',default=0.15,type=float,help="the probability to select a random action") - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--result_path',default=curr_path + "/outputs/" + parser.parse_args().env_name + \ - '/' + curr_time + '/results/' ) - parser.add_argument('--model_path',default=curr_path + "/outputs/" + parser.parse_args().env_name + \ - '/' + curr_time + '/models/' ) - parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") - parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") - args = parser.parse_args() - return args - -def env_agent_config(cfg,seed=1): - env = RacetrackEnv() - n_actions = env.action_space.n - agent = FisrtVisitMC(n_actions, cfg) - return env,agent +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigMC()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigMC()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=False) # create env + if cfg.env_name == 'CliffWalking-v0': + env = CliffWalkingWapper(env) + if cfg.seed !=0: # set random seed + all_seed(env,seed=cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + agent = FisrtVisitMC(cfg) + return env,agent + def train_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 + state = env.reset() # reset and obtain initial state + one_ep_transition = [] + for _ in range(cfg.max_steps): + ep_step += 1 + action = agent.sample_action(state) # sample action + next_state, reward, terminated, info = env.step(action) # update env and return transitions under new_step_api of OpenAI Gym + one_ep_transition.append((state, action, reward)) # save transitions + agent.update(one_ep_transition) # update agent + state = next_state # update next state for env + ep_reward += reward # + if terminated: + break + return agent,ep_reward,ep_step + def test_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + ep_step += 1 + action = agent.predict_action(state) # sample action + next_state, reward, terminated, info = env.step(action) # update env and return transitions under new_step_api of OpenAI Gym + state = next_state # update next state for env + ep_reward += reward # + if terminated: + break + return agent,ep_reward,ep_step def train(cfg, env, agent): print("开始训练!") @@ -93,18 +124,5 @@ def test(cfg, env, agent): return {'rewards':rewards} if __name__ == "__main__": - cfg = get_args() - # 训练 - env, agent = env_agent_config(cfg) - res_dic = train(cfg, env, agent) - save_args(cfg,path = cfg.result_path) # 保存参数到模型路径上 - agent.save(path = cfg.model_path) # 保存模型 - save_results(res_dic, tag = 'train', path = cfg.result_path) - plot_rewards(res_dic['rewards'], cfg, path = cfg.result_path,tag = "train") - # 测试 - env, agent = env_agent_config(cfg) # 也可以不加,加这一行的是为了避免训练之后环境可能会出现问题,因此新建一个环境用于测试 - agent.load(path = cfg.model_path) # 导入模型 - res_dic = test(cfg, env, agent) - save_results(res_dic, tag='test', - path = cfg.result_path) # 保存结果 - plot_rewards(res_dic['rewards'], cfg, path = cfg.result_path,tag = "test") # 画出结果 + main = Main() + main.run() \ No newline at end of file diff --git a/projects/codes/PPO/config/config.py b/projects/codes/PPO/config/config.py new file mode 100644 index 0000000..b8f9870 --- /dev/null +++ b/projects/codes/PPO/config/config.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 11:30:56 +LastEditor: JiangJi +LastEditTime: 2022-10-31 00:33:15 +Discription: default parameters of PPO +''' +from common.config import GeneralConfig,AlgoConfig + +class GeneralConfigPPO(GeneralConfig): + def __init__(self) -> None: + self.env_name = "CartPole-v0" + self.algo_name = "PPO" + self.seed = 1 + self.device = "cuda" + self.train_eps = 100 # number of episodes for training + self.test_eps = 10 # number of episodes for testing + self.max_steps = 200 # max steps for each episode + +class AlgoConfigPPO(AlgoConfig): + def __init__(self) -> None: + self.gamma = 0.99 # discount factor + self.continuous = False # continuous action space or not + self.policy_clip = 0.2 # clip range of policy + self.n_epochs = 10 # number of epochs + self.gae_lambda = 0.95 # gae lambda + self.actor_lr = 0.0003 # learning rate of actor + self.critic_lr = 0.0003 # learning rate of critic + self.actor_hidden_dim = 256 # + self.critic_hidden_dim = 256 + self.n_epochs = 4 # epochs + self.batch_size = 5 # + self.policy_clip = 0.2 + self.update_fre = 20 # frequency of updating agent diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/models/ppo_actor.pt b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/models/ppo_actor.pt deleted file mode 100644 index 5419b72..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/models/ppo_actor.pt and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/models/ppo_critic.pt b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/models/ppo_critic.pt deleted file mode 100644 index af97c9b..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/models/ppo_critic.pt and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/params.json b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/params.json deleted file mode 100644 index 748044c..0000000 --- a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/params.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "algo_name": "PPO", - "env_name": "CartPole-v0", - "continuous": false, - "train_eps": 200, - "test_eps": 20, - "gamma": 0.99, - "batch_size": 5, - "n_epochs": 4, - "actor_lr": 0.0003, - "critic_lr": 0.0003, - "gae_lambda": 0.95, - "policy_clip": 0.2, - "update_fre": 20, - "hidden_dim": 256, - "device": "cpu", - "result_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\PPO/outputs/CartPole-v0/20220731-233512/results/", - "model_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\PPO/outputs/CartPole-v0/20220731-233512/models/", - "save_fig": true -} \ No newline at end of file diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_ma_rewards.npy b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_ma_rewards.npy deleted file mode 100644 index 14bca8b..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_ma_rewards.npy and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_rewards.npy b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_rewards.npy deleted file mode 100644 index 14bca8b..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_rewards.npy and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_rewards_curve.png b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_rewards_curve.png deleted file mode 100644 index b52cc37..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/test_rewards_curve.png and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_ma_rewards.npy b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_ma_rewards.npy deleted file mode 100644 index 11249ed..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_ma_rewards.npy and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_rewards.npy b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_rewards.npy deleted file mode 100644 index 078b31f..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_rewards.npy and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_rewards_curve.png b/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_rewards_curve.png deleted file mode 100644 index 7a4f892..0000000 Binary files a/projects/codes/PPO/outputs/CartPole-v0/20220731-233512/results/train_rewards_curve.png and /dev/null differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/models/ppo_actor.pt b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/models/ppo_actor.pt new file mode 100644 index 0000000..e7660b4 Binary files /dev/null and b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/models/ppo_actor.pt differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/models/ppo_critic.pt b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/models/ppo_critic.pt new file mode 100644 index 0000000..f0ec0d4 Binary files /dev/null and b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/models/ppo_critic.pt differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/params.json b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/params.json new file mode 100644 index 0000000..15097c6 --- /dev/null +++ b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/params.json @@ -0,0 +1,25 @@ +{ + "algo_name": "PPO", + "env_name": "CartPole-v0", + "continuous": false, + "train_eps": 200, + "test_eps": 20, + "gamma": 0.99, + "batch_size": 5, + "n_epochs": 4, + "actor_lr": 0.0003, + "critic_lr": 0.0003, + "gae_lambda": 0.95, + "policy_clip": 0.2, + "update_fre": 20, + "actor_hidden_dim": 256, + "critic_hidden_dim": 256, + "device": "cpu", + "seed": 10, + "show_fig": false, + "save_fig": true, + "result_path": "c:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\PPO/outputs/CartPole-v0/20220920-213310/results/", + "model_path": "c:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\PPO/outputs/CartPole-v0/20220920-213310/models/", + "n_states": 4, + "n_actions": 2 +} \ No newline at end of file diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/testing_curve.png b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/testing_curve.png new file mode 100644 index 0000000..badf029 Binary files /dev/null and b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/testing_curve.png differ diff --git a/projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/testing_results.csv b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/testing_results.csv similarity index 100% rename from projects/codes/DQN/outputs/CartPole-v0/20220823-173936/results/testing_results.csv rename to projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/testing_results.csv diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/training_curve.png b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/training_curve.png new file mode 100644 index 0000000..1bc6604 Binary files /dev/null and b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/training_curve.png differ diff --git a/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/training_results.csv b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/training_results.csv new file mode 100644 index 0000000..7836df5 --- /dev/null +++ b/projects/codes/PPO/outputs/CartPole-v0/20220920-213310/results/training_results.csv @@ -0,0 +1,201 @@ +episodes,rewards +0,34.0 +1,12.0 +2,47.0 +3,29.0 +4,20.0 +5,23.0 +6,33.0 +7,25.0 +8,11.0 +9,30.0 +10,18.0 +11,16.0 +12,15.0 +13,25.0 +14,33.0 +15,19.0 +16,50.0 +17,23.0 +18,21.0 +19,42.0 +20,60.0 +21,64.0 +22,30.0 +23,31.0 +24,90.0 +25,43.0 +26,54.0 +27,74.0 +28,30.0 +29,82.0 +30,50.0 +31,53.0 +32,25.0 +33,27.0 +34,145.0 +35,118.0 +36,141.0 +37,148.0 +38,200.0 +39,191.0 +40,71.0 +41,105.0 +42,100.0 +43,120.0 +44,80.0 +45,40.0 +46,104.0 +47,39.0 +48,89.0 +49,60.0 +50,30.0 +51,24.0 +52,20.0 +53,23.0 +54,30.0 +55,32.0 +56,20.0 +57,12.0 +58,25.0 +59,25.0 +60,24.0 +61,29.0 +62,200.0 +63,62.0 +64,200.0 +65,58.0 +66,81.0 +67,200.0 +68,52.0 +69,140.0 +70,200.0 +71,74.0 +72,200.0 +73,29.0 +74,124.0 +75,129.0 +76,200.0 +77,194.0 +78,175.0 +79,117.0 +80,200.0 +81,186.0 +82,114.0 +83,200.0 +84,166.0 +85,150.0 +86,135.0 +87,200.0 +88,200.0 +89,133.0 +90,111.0 +91,200.0 +92,90.0 +93,200.0 +94,147.0 +95,30.0 +96,137.0 +97,200.0 +98,200.0 +99,179.0 +100,167.0 +101,186.0 +102,169.0 +103,200.0 +104,200.0 +105,171.0 +106,200.0 +107,181.0 +108,125.0 +109,200.0 +110,200.0 +111,122.0 +112,200.0 +113,124.0 +114,95.0 +115,102.0 +116,118.0 +117,91.0 +118,64.0 +119,124.0 +120,122.0 +121,76.0 +122,68.0 +123,40.0 +124,52.0 +125,51.0 +126,50.0 +127,49.0 +128,37.0 +129,76.0 +130,83.0 +131,76.0 +132,92.0 +133,113.0 +134,94.0 +135,157.0 +136,92.0 +137,200.0 +138,123.0 +139,200.0 +140,200.0 +141,200.0 +142,140.0 +143,200.0 +144,200.0 +145,200.0 +146,200.0 +147,200.0 +148,200.0 +149,200.0 +150,200.0 +151,78.0 +152,200.0 +153,200.0 +154,200.0 +155,200.0 +156,200.0 +157,200.0 +158,200.0 +159,200.0 +160,200.0 +161,200.0 +162,107.0 +163,187.0 +164,200.0 +165,200.0 +166,200.0 +167,200.0 +168,200.0 +169,200.0 +170,200.0 +171,200.0 +172,200.0 +173,200.0 +174,200.0 +175,200.0 +176,200.0 +177,200.0 +178,200.0 +179,200.0 +180,200.0 +181,200.0 +182,200.0 +183,200.0 +184,200.0 +185,200.0 +186,200.0 +187,200.0 +188,200.0 +189,200.0 +190,200.0 +191,200.0 +192,200.0 +193,200.0 +194,200.0 +195,200.0 +196,200.0 +197,200.0 +198,200.0 +199,200.0 diff --git a/projects/codes/PPO/ppo2.py b/projects/codes/PPO/ppo2.py index 13cfab7..5d399b8 100644 --- a/projects/codes/PPO/ppo2.py +++ b/projects/codes/PPO/ppo2.py @@ -1,99 +1,53 @@ #!/usr/bin/env python # coding=utf-8 ''' -Author: John +Author: JiangJi Email: johnjim0816@gmail.com -Date: 2021-03-23 15:17:42 -LastEditor: John -LastEditTime: 2021-12-31 19:38:33 -Discription: -Environment: +Date: 2022-09-26 16:11:36 +LastEditor: JiangJi +LastEditTime: 2022-10-31 00:36:37 +Discription: PPO-clip ''' + import os import numpy as np import torch import torch.optim as optim -import torch.nn as nn from torch.distributions.categorical import Categorical -class PPOMemory: - def __init__(self, batch_size): - self.states = [] - self.probs = [] - self.vals = [] - self.actions = [] - self.rewards = [] - self.dones = [] - self.batch_size = batch_size - def sample(self): - batch_step = np.arange(0, len(self.states), self.batch_size) - indices = np.arange(len(self.states), dtype=np.int64) - np.random.shuffle(indices) - batches = [indices[i:i+self.batch_size] for i in batch_step] - return np.array(self.states),np.array(self.actions),np.array(self.probs),\ - np.array(self.vals),np.array(self.rewards),np.array(self.dones),batches - - def push(self, state, action, probs, vals, reward, done): - self.states.append(state) - self.actions.append(action) - self.probs.append(probs) - self.vals.append(vals) - self.rewards.append(reward) - self.dones.append(done) - def clear(self): - self.states = [] - self.probs = [] - self.actions = [] - self.rewards = [] - self.dones = [] - self.vals = [] -class Actor(nn.Module): - def __init__(self,n_states, n_actions, - hidden_dim): - super(Actor, self).__init__() - self.actor = nn.Sequential( - nn.Linear(n_states, hidden_dim), - nn.ReLU(), - nn.Linear(hidden_dim, hidden_dim), - nn.ReLU(), - nn.Linear(hidden_dim, n_actions), - nn.Softmax(dim=-1) - ) - def forward(self, state): - dist = self.actor(state) - dist = Categorical(dist) - return dist - -class Critic(nn.Module): - def __init__(self, n_states,hidden_dim): - super(Critic, self).__init__() - self.critic = nn.Sequential( - nn.Linear(n_states, hidden_dim), - nn.ReLU(), - nn.Linear(hidden_dim, hidden_dim), - nn.ReLU(), - nn.Linear(hidden_dim, 1) - ) - def forward(self, state): - value = self.critic(state) - return value class PPO: - def __init__(self, n_states, n_actions,cfg): + def __init__(self, models,memory,cfg): self.gamma = cfg.gamma - self.continuous = cfg.continuous + self.continuous = cfg.continuous self.policy_clip = cfg.policy_clip self.n_epochs = cfg.n_epochs + self.batch_size = cfg.batch_size self.gae_lambda = cfg.gae_lambda - self.device = cfg.device - self.actor = Actor(n_states, n_actions,cfg.hidden_dim).to(self.device) - self.critic = Critic(n_states,cfg.hidden_dim).to(self.device) + self.device = torch.device(cfg.device) + self.actor = models['Actor'].to(self.device) + self.critic = models['Critic'].to(self.device) self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=cfg.actor_lr) self.critic_optimizer = optim.Adam(self.critic.parameters(), lr=cfg.critic_lr) - self.memory = PPOMemory(cfg.batch_size) + self.memory = memory self.loss = 0 - def choose_action(self, state): + def sample_action(self, state): + state = np.array([state]) # 先转成数组再转tensor更高效 + state = torch.tensor(state, dtype=torch.float).to(self.device) + probs = self.actor(state) + dist = Categorical(probs) + value = self.critic(state) + action = dist.sample() + probs = torch.squeeze(dist.log_prob(action)).item() + if self.continuous: + action = torch.tanh(action) + else: + action = torch.squeeze(action).item() + value = torch.squeeze(value).item() + return action, probs, value + @torch.no_grad() + def predict_action(self, state): state = np.array([state]) # 先转成数组再转tensor更高效 state = torch.tensor(state, dtype=torch.float).to(self.device) dist = self.actor(state) @@ -148,12 +102,15 @@ class PPO: self.actor_optimizer.step() self.critic_optimizer.step() self.memory.clear() - def save(self,path): + def save_model(self,path): + from pathlib import Path + # create path + Path(path).mkdir(parents=True, exist_ok=True) actor_checkpoint = os.path.join(path, 'ppo_actor.pt') critic_checkpoint= os.path.join(path, 'ppo_critic.pt') torch.save(self.actor.state_dict(), actor_checkpoint) torch.save(self.critic.state_dict(), critic_checkpoint) - def load(self,path): + def load_model(self,path): actor_checkpoint = os.path.join(path, 'ppo_actor.pt') critic_checkpoint= os.path.join(path, 'ppo_critic.pt') self.actor.load_state_dict(torch.load(actor_checkpoint)) diff --git a/projects/codes/PPO/task0.py b/projects/codes/PPO/task0.py index 9cd5063..dbf0e7a 100644 --- a/projects/codes/PPO/task0.py +++ b/projects/codes/PPO/task0.py @@ -1,132 +1,159 @@ import sys,os -curr_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在绝对路径 -parent_path = os.path.dirname(curr_path) # 父路径 -sys.path.append(parent_path) # 添加路径到系统路径 +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path import gym import torch -import numpy as np import datetime +import numpy as np import argparse -from common.utils import plot_rewards,save_args,save_results,make_dir +import torch.nn as nn + + +from common.utils import all_seed,merge_class_attrs +from common.models import ActorSoftmax, Critic +from common.memories import PGReplay +from common.launcher import Launcher +from envs.register import register_env from ppo2 import PPO +from config,config import GeneralConfigPPO,AlgoConfigPPO +class PPOMemory: + def __init__(self, batch_size): + self.states = [] + self.probs = [] + self.vals = [] + self.actions = [] + self.rewards = [] + self.terminateds = [] + self.batch_size = batch_size + def sample(self): + batch_step = np.arange(0, len(self.states), self.batch_size) + indices = np.arange(len(self.states), dtype=np.int64) + np.random.shuffle(indices) + batches = [indices[i:i+self.batch_size] for i in batch_step] + return np.array(self.states),np.array(self.actions),np.array(self.probs),\ + np.array(self.vals),np.array(self.rewards),np.array(self.terminateds),batches + + def push(self, state, action, probs, vals, reward, terminated): + self.states.append(state) + self.actions.append(action) + self.probs.append(probs) + self.vals.append(vals) + self.rewards.append(reward) + self.terminateds.append(terminated) -def get_args(): - """ Hyperparameters - """ - curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # 获取当前时间 - parser = argparse.ArgumentParser(description="hyperparameters") - parser.add_argument('--algo_name',default='PPO',type=str,help="name of algorithm") - parser.add_argument('--env_name',default='CartPole-v0',type=str,help="name of environment") - parser.add_argument('--continuous',default=False,type=bool,help="if PPO is continous") # PPO既可适用于连续动作空间,也可以适用于离散动作空间 - parser.add_argument('--train_eps',default=200,type=int,help="episodes of training") - parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") - parser.add_argument('--gamma',default=0.99,type=float,help="discounted factor") - parser.add_argument('--batch_size',default=5,type=int) # mini-batch SGD中的批量大小 - parser.add_argument('--n_epochs',default=4,type=int) - parser.add_argument('--actor_lr',default=0.0003,type=float,help="learning rate of actor net") - parser.add_argument('--critic_lr',default=0.0003,type=float,help="learning rate of critic net") - parser.add_argument('--gae_lambda',default=0.95,type=float) - parser.add_argument('--policy_clip',default=0.2,type=float) # PPO-clip中的clip参数,一般是0.1~0.2左右 - parser.add_argument('--update_fre',default=20,type=int) - parser.add_argument('--hidden_dim',default=256,type=int) - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--result_path',default=curr_path + "/outputs/" + parser.parse_args().env_name + \ - '/' + curr_time + '/results/' ) - parser.add_argument('--model_path',default=curr_path + "/outputs/" + parser.parse_args().env_name + \ - '/' + curr_time + '/models/' ) # path to save models - parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") - args = parser.parse_args() - return args - -def env_agent_config(cfg,seed = 1): - ''' 创建环境和智能体 - ''' - env = gym.make(cfg.env_name) # 创建环境 - n_states = env.observation_space.shape[0] # 状态维度 - if cfg.continuous: - n_actions = env.action_space.shape[0] # 动作维度 - else: - n_actions = env.action_space.n # 动作维度 - agent = PPO(n_states, n_actions, cfg) # 创建智能体 - if seed !=0: # 设置随机种子 - torch.manual_seed(seed) - env.seed(seed) - np.random.seed(seed) - return env, agent + def clear(self): + self.states = [] + self.probs = [] + self.actions = [] + self.rewards = [] + self.terminateds = [] + self.vals = [] -def train(cfg,env,agent): - print('开始训练!') - print(f'环境:{cfg.env_name}, 算法:{cfg.algo_name}, 设备:{cfg.device}') - rewards = [] # 记录所有回合的奖励 - ma_rewards = [] # 记录所有回合的滑动平均奖励 - steps = 0 - for i_ep in range(cfg.train_eps): + +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigPPO()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigPPO()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=False) # create env + if cfg.seed !=0: # set random seed + all_seed(env,seed=cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + models = {'Actor':ActorSoftmax(n_states,n_actions, hidden_dim = cfg.actor_hidden_dim),'Critic':Critic(n_states,1,hidden_dim=cfg.critic_hidden_dim)} + memory = PGReplay # replay buffer + agent = PPO(models,memory,cfg) # create agent + return env, agent + def train_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode state = env.reset() - done = False - ep_reward = 0 - while not done: - action, prob, val = agent.choose_action(state) - state_, reward, done, _ = env.step(action) - steps += 1 + for _ in range(cfg.max_steps): + action, prob, val = agent.sample_action(state) + next_state, reward, terminated, _ = env.step(action) ep_reward += reward - agent.memory.push(state, action, prob, val, reward, done) - if steps % cfg.update_fre == 0: + ep_step += 1 + agent.memory.push((state, action, prob, val, reward, terminated)) + if ep_step % cfg['update_fre'] == 0: agent.update() - state = state_ - rewards.append(ep_reward) - if ma_rewards: - ma_rewards.append(0.9*ma_rewards[-1]+0.1*ep_reward) - else: - ma_rewards.append(ep_reward) - if (i_ep+1)%10 == 0: - print(f"回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.2f}") - print('完成训练!') - env.close() - res_dic = {'rewards':rewards,'ma_rewards':ma_rewards} - return res_dic - -def test(cfg,env,agent): - print('开始测试!') - print(f'环境:{cfg.env_name}, 算法:{cfg.algo_name}, 设备:{cfg.device}') - rewards = [] # 记录所有回合的奖励 - ma_rewards = [] # 记录所有回合的滑动平均奖励 - for i_ep in range(cfg.test_eps): + state = next_state + if terminated: + break + return agent, ep_reward, ep_step + def test_one_episode(self, env, agent, cfg): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode state = env.reset() - done = False - ep_reward = 0 - while not done: - action, prob, val = agent.choose_action(state) - state_, reward, done, _ = env.step(action) + for _ in range(cfg.max_steps): + action, prob, val = agent.sample_action(state) + next_state, reward, terminated, _ = env.step(action) ep_reward += reward - state = state_ - rewards.append(ep_reward) - if ma_rewards: - ma_rewards.append( - 0.9*ma_rewards[-1]+0.1*ep_reward) - else: - ma_rewards.append(ep_reward) - print('回合:{}/{}, 奖励:{}'.format(i_ep+1, cfg.test_eps, ep_reward)) - print('完成训练!') - env.close() - res_dic = {'rewards':rewards,'ma_rewards':ma_rewards} - return res_dic + ep_step += 1 + state = next_state + if terminated: + break + return agent, ep_reward, ep_step + def train(self,cfg,env,agent): + ''' train agent + ''' + print("Start training!") + print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") + rewards = [] # record rewards for all episodes + steps = 0 + for i_ep in range(cfg['train_eps']): + state = env.reset() + ep_reward = 0 + while True: + action, prob, val = agent.sample_action(state) + next_state, reward, terminated, _ = env.step(action) + steps += 1 + ep_reward += reward + agent.memory.push(state, action, prob, val, reward, terminated) + if steps % cfg['update_fre'] == 0: + agent.update() + state = next_state + if terminated: + break + rewards.append(ep_reward) + if (i_ep+1)%10==0: + print(f"Episode: {i_ep+1}/{cfg['train_eps']}, Reward: {ep_reward:.2f}") + print("Finish training!") + return {'episodes':range(len(rewards)),'rewards':rewards} + def test(self,cfg,env,agent): + ''' test agent + ''' + print("Start testing!") + print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") + rewards = [] # record rewards for all episodes + for i_ep in range(cfg['test_eps']): + state = env.reset() + ep_reward = 0 + while True: + action, prob, val = agent.predict_action(state) + next_state, reward, terminated, _ = env.step(action) + ep_reward += reward + state = next_state + if terminated: + break + rewards.append(ep_reward) + print(f"Episode: {i_ep+1}/{cfg['test_eps']}, Reward: {ep_reward:.2f}") + print("Finish testing!") + return {'episodes':range(len(rewards)),'rewards':rewards} if __name__ == "__main__": - cfg = get_args() - # 训练 - env, agent = env_agent_config(cfg) - res_dic = train(cfg, env, agent) - make_dir(cfg.result_path, cfg.model_path) - save_args(cfg) # 保存参数 - agent.save(path=cfg.model_path) # save model - save_results(res_dic, tag='train', - path=cfg.result_path) - plot_rewards(res_dic['rewards'], res_dic['ma_rewards'], cfg, tag="train") - # 测试 - env, agent = env_agent_config(cfg) - agent.load(path=cfg.model_path) # 导入模型 - res_dic = test(cfg, env, agent) - save_results(res_dic, tag='test', - path=cfg.result_path) # 保存结果 - plot_rewards(res_dic['rewards'], res_dic['ma_rewards'],cfg, tag="test") # 画出结果 \ No newline at end of file + main = Main() + main.run() \ No newline at end of file diff --git a/projects/codes/PPO/task1.py b/projects/codes/PPO/task1.py index 04726cb..d664770 100644 --- a/projects/codes/PPO/task1.py +++ b/projects/codes/PPO/task1.py @@ -1,3 +1,13 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-09-19 14:48:16 +LastEditor: JiangJi +LastEditTime: 2022-10-30 00:45:14 +Discription: +''' import sys,os curr_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在绝对路径 parent_path = os.path.dirname(curr_path) # 父路径 diff --git a/projects/codes/PolicyGradient/pg.py b/projects/codes/PolicyGradient/pg.py index d0b4956..7d84c6e 100644 --- a/projects/codes/PolicyGradient/pg.py +++ b/projects/codes/PolicyGradient/pg.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2020-11-22 23:27:44 LastEditor: John -LastEditTime: 2022-08-27 13:45:26 +LastEditTime: 2022-10-09 21:28:18 Discription: Environment: ''' @@ -31,8 +31,6 @@ class PolicyGradient: state = torch.from_numpy(state).float() state = Variable(state) probs = self.policy_net(state) - print("probs") - print(probs) m = Bernoulli(probs) # 伯努利分布 action = m.sample() diff --git a/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/config.yaml b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/config.yaml new file mode 100644 index 0000000..d9b4258 --- /dev/null +++ b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/config.yaml @@ -0,0 +1,21 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: CliffWalking-v0 + load_checkpoint: true + load_path: Train_CliffWalking-v0_QLearning_20221030-013856 + max_steps: 200 + mode: test + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + batch_size: 64 + buffer_size: 100000 + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/logs/log.txt b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/logs/log.txt new file mode 100644 index 0000000..d89037e --- /dev/null +++ b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/logs/log.txt @@ -0,0 +1,24 @@ +2022-10-30 01:41:51 - r - INFO: - n_states: 48, n_actions: 4 +2022-10-30 01:41:51 - r - INFO: - Start testing! +2022-10-30 01:41:51 - r - INFO: - Env: CliffWalking-v0, Algorithm: QLearning, Device: cpu +2022-10-30 01:41:51 - r - INFO: - Episode: 1/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 2/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 3/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 4/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 5/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 6/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 7/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 8/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 9/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 10/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 11/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 12/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 13/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 14/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 15/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 16/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 17/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 18/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 19/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Episode: 20/20, Steps:13 Reward: -13.00 +2022-10-30 01:41:51 - r - INFO: - Finish testing! diff --git a/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/models/Qleaning_model.pkl b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/models/Qleaning_model.pkl new file mode 100644 index 0000000..2022d46 Binary files /dev/null and b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/models/Qleaning_model.pkl differ diff --git a/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/results/learning_curve.png b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/results/learning_curve.png new file mode 100644 index 0000000..49a7daa Binary files /dev/null and b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/results/learning_curve.png differ diff --git a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/testing_results.csv b/projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/results/res.csv similarity index 100% rename from projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/testing_results.csv rename to projects/codes/QLearning/Test_CliffWalking-v0_QLearning_20221030-014151/results/res.csv diff --git a/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/config.yaml b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/config.yaml new file mode 100644 index 0000000..537c003 --- /dev/null +++ b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: FrozenLakeNoSlippery-v1 + load_checkpoint: true + load_path: Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504 + max_steps: 200 + mode: test + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 2000 + epsilon_end: 0.1 + epsilon_start: 0.7 + gamma: 0.95 + lr: 0.9 diff --git a/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/logs/log.txt b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/logs/log.txt new file mode 100644 index 0000000..d972a0c --- /dev/null +++ b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/logs/log.txt @@ -0,0 +1,24 @@ +2022-10-30 01:45:52 - r - INFO: - n_states: 16, n_actions: 4 +2022-10-30 01:45:52 - r - INFO: - Start testing! +2022-10-30 01:45:52 - r - INFO: - Env: FrozenLakeNoSlippery-v1, Algorithm: QLearning, Device: cpu +2022-10-30 01:45:52 - r - INFO: - Episode: 1/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 2/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 3/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 4/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 5/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 6/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 7/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 8/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 9/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 10/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 11/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 12/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 13/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 14/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 15/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 16/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 17/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 18/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 19/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Episode: 20/20, Steps:6 Reward: 1.00 +2022-10-30 01:45:52 - r - INFO: - Finish testing! diff --git a/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/models/Qleaning_model.pkl b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/models/Qleaning_model.pkl new file mode 100644 index 0000000..41a5a05 Binary files /dev/null and b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/models/Qleaning_model.pkl differ diff --git a/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/results/learning_curve.png b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/results/learning_curve.png new file mode 100644 index 0000000..60eeac6 Binary files /dev/null and b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/results/learning_curve.png differ diff --git a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/testing_results.csv b/projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/results/res.csv similarity index 100% rename from projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/testing_results.csv rename to projects/codes/QLearning/Test_FrozenLakeNoSlippery-v1_QLearning_20221030-014552/results/res.csv diff --git a/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/config.yaml b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/config.yaml new file mode 100644 index 0000000..42d7573 --- /dev/null +++ b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: Racetrack-v0 + load_checkpoint: true + load_path: Train_Racetrack-v0_QLearning_20221030-014833 + max_steps: 200 + mode: test + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.9 + lr: 0.1 diff --git a/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/logs/log.txt b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/logs/log.txt new file mode 100644 index 0000000..f36fac9 --- /dev/null +++ b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/logs/log.txt @@ -0,0 +1,24 @@ +2022-10-30 01:49:58 - r - INFO: - n_states: 4, n_actions: 9 +2022-10-30 01:49:58 - r - INFO: - Start testing! +2022-10-30 01:49:58 - r - INFO: - Env: Racetrack-v0, Algorithm: QLearning, Device: cpu +2022-10-30 01:49:58 - r - INFO: - Episode: 1/20, Steps:14 Reward: -4.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 2/20, Steps:8 Reward: 2.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 3/20, Steps:6 Reward: 4.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 4/20, Steps:22 Reward: -12.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 5/20, Steps:15 Reward: -15.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 6/20, Steps:6 Reward: 4.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 7/20, Steps:5 Reward: 5.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 8/20, Steps:8 Reward: 2.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 9/20, Steps:15 Reward: -5.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 10/20, Steps:8 Reward: 2.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 11/20, Steps:5 Reward: 5.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 12/20, Steps:15 Reward: -5.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 13/20, Steps:6 Reward: 4.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 14/20, Steps:31 Reward: -51.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 15/20, Steps:13 Reward: -13.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 16/20, Steps:7 Reward: 3.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 17/20, Steps:6 Reward: 4.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 18/20, Steps:5 Reward: 5.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 19/20, Steps:17 Reward: -17.00 +2022-10-30 01:49:58 - r - INFO: - Episode: 20/20, Steps:15 Reward: -5.00 +2022-10-30 01:49:58 - r - INFO: - Finish testing! diff --git a/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/models/Qleaning_model.pkl b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/models/Qleaning_model.pkl new file mode 100644 index 0000000..1f458e1 Binary files /dev/null and b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/models/Qleaning_model.pkl differ diff --git a/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/results/learning_curve.png b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/results/learning_curve.png new file mode 100644 index 0000000..869b2c9 Binary files /dev/null and b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/results/learning_curve.png differ diff --git a/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/results/res.csv b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/results/res.csv new file mode 100644 index 0000000..cf33c86 --- /dev/null +++ b/projects/codes/QLearning/Test_Racetrack-v0_QLearning_20221030-014958/results/res.csv @@ -0,0 +1,21 @@ +episodes,rewards,steps +0,-4,14 +1,2,8 +2,4,6 +3,-12,22 +4,-15,15 +5,4,6 +6,5,5 +7,2,8 +8,-5,15 +9,2,8 +10,5,5 +11,-5,15 +12,4,6 +13,-51,31 +14,-13,13 +15,3,7 +16,4,6 +17,5,5 +18,-17,17 +19,-5,15 diff --git a/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/config.yaml b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/config.yaml new file mode 100644 index 0000000..7610f6c --- /dev/null +++ b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: CliffWalking-v0 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/logs/log.txt b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/logs/log.txt new file mode 100644 index 0000000..d42935f --- /dev/null +++ b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/logs/log.txt @@ -0,0 +1,804 @@ +2022-10-30 01:49:16 - r - INFO: - n_states: 48, n_actions: 4 +2022-10-30 01:49:16 - r - INFO: - Start training! +2022-10-30 01:49:16 - r - INFO: - Env: CliffWalking-v0, Algorithm: QLearning, Device: cpu +2022-10-30 01:49:16 - r - INFO: - Episode: 1/800, Reward: -1586.00: Epislon: 0.493 +2022-10-30 01:49:16 - r - INFO: - Episode: 2/800, Reward: -1091.00: Epislon: 0.258 +2022-10-30 01:49:16 - r - INFO: - Episode: 3/800, Reward: -596.00: Epislon: 0.137 +2022-10-30 01:49:16 - r - INFO: - Episode: 4/800, Reward: -497.00: Epislon: 0.075 +2022-10-30 01:49:16 - r - INFO: - Episode: 5/800, Reward: -398.00: Epislon: 0.044 +2022-10-30 01:49:16 - r - INFO: - Episode: 6/800, Reward: -362.00: Epislon: 0.029 +2022-10-30 01:49:16 - r - INFO: - Episode: 7/800, Reward: -179.00: Epislon: 0.021 +2022-10-30 01:49:16 - r - INFO: - Episode: 8/800, Reward: -398.00: Epislon: 0.015 +2022-10-30 01:49:16 - r - INFO: - Episode: 9/800, Reward: -79.00: Epislon: 0.014 +2022-10-30 01:49:16 - r - INFO: - Episode: 10/800, Reward: -141.00: Epislon: 0.013 +2022-10-30 01:49:16 - r - INFO: - Episode: 11/800, Reward: -143.00: Epislon: 0.012 +2022-10-30 01:49:16 - r - INFO: - Episode: 12/800, Reward: -134.00: Epislon: 0.011 +2022-10-30 01:49:16 - r - INFO: - Episode: 13/800, Reward: -299.00: Epislon: 0.011 +2022-10-30 01:49:16 - r - INFO: - Episode: 14/800, Reward: -102.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 15/800, Reward: -61.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 16/800, Reward: -136.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 17/800, Reward: -176.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 18/800, Reward: -98.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 19/800, Reward: -92.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 20/800, Reward: -110.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 21/800, Reward: -67.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 22/800, Reward: -136.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 23/800, Reward: -98.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 24/800, Reward: -164.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 25/800, Reward: -65.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 26/800, Reward: -98.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 27/800, Reward: -33.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 28/800, Reward: -161.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 29/800, Reward: -72.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 30/800, Reward: -73.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 31/800, Reward: -116.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 32/800, Reward: -50.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 33/800, Reward: -66.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 34/800, Reward: -123.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 35/800, Reward: -40.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 36/800, Reward: -100.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 37/800, Reward: -56.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 38/800, Reward: -101.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 39/800, Reward: -55.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 40/800, Reward: -84.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 41/800, Reward: -68.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 42/800, Reward: -33.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 43/800, Reward: -113.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 44/800, Reward: -72.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 45/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 46/800, Reward: -84.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 47/800, Reward: -45.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 48/800, Reward: -86.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 49/800, Reward: -57.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 50/800, Reward: -92.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 51/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 52/800, Reward: -76.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 53/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 54/800, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 55/800, Reward: -88.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 56/800, Reward: -40.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 57/800, Reward: -55.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 58/800, Reward: -69.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 59/800, Reward: -51.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 60/800, Reward: -69.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 61/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 62/800, Reward: -84.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 63/800, Reward: -38.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 64/800, Reward: -56.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 65/800, Reward: -58.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 66/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 67/800, Reward: -64.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 68/800, Reward: -38.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 69/800, Reward: -53.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 70/800, Reward: -70.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 71/800, Reward: -40.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 72/800, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 73/800, Reward: -71.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 74/800, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 75/800, Reward: -32.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 76/800, Reward: -70.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 77/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 78/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 79/800, Reward: -73.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 80/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 81/800, Reward: -67.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 82/800, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 83/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 84/800, Reward: -64.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 85/800, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 86/800, Reward: -61.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 87/800, Reward: -33.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 88/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 89/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 90/800, Reward: -86.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 91/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 92/800, Reward: -53.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 93/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 94/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 95/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 96/800, Reward: -45.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 97/800, Reward: -43.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 98/800, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 99/800, Reward: -37.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 100/800, Reward: -43.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 101/800, Reward: -46.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 102/800, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 103/800, Reward: -32.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 104/800, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 105/800, Reward: -37.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 106/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 107/800, Reward: -38.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 108/800, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 109/800, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 110/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 111/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 112/800, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 113/800, Reward: -63.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 114/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 115/800, Reward: -52.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 116/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 117/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 118/800, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 119/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 120/800, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 121/800, Reward: -48.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 122/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 123/800, Reward: -40.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 124/800, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 125/800, Reward: -23.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 126/800, Reward: -35.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 127/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 128/800, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 129/800, Reward: -33.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 130/800, Reward: -32.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 131/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 132/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 133/800, Reward: -43.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 134/800, Reward: -51.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 135/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 136/800, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 137/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 138/800, Reward: -42.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 139/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 140/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 141/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 142/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 143/800, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 144/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 145/800, Reward: -42.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 146/800, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 147/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 148/800, Reward: -42.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 149/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 150/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 151/800, Reward: -32.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 152/800, Reward: -20.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 153/800, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 154/800, Reward: -20.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 155/800, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 156/800, Reward: -20.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 157/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 158/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 159/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 160/800, Reward: -38.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 161/800, Reward: -34.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 162/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 163/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 164/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 165/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 166/800, Reward: -34.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 167/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 168/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 169/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 170/800, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 171/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 172/800, Reward: -20.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 173/800, Reward: -58.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 174/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 175/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 176/800, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 177/800, Reward: -125.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 178/800, Reward: -156.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 179/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 180/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 181/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 182/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 183/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 184/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 185/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 186/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 187/800, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 188/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 189/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 190/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 191/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 192/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 193/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 194/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 195/800, Reward: -35.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 196/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 197/800, Reward: -134.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 198/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 199/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 200/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 201/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 202/800, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 203/800, Reward: -23.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 204/800, Reward: -23.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 205/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 206/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 207/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 208/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 209/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 210/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 211/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 212/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 213/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 214/800, Reward: -133.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 215/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 216/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 217/800, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 218/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 219/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 220/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 221/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 222/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 223/800, Reward: -143.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 224/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 225/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 226/800, Reward: -23.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 227/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 228/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 229/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 230/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 231/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 232/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 233/800, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 234/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 235/800, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 236/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 237/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 238/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 239/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 240/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 241/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 242/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 243/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 244/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 245/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 246/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 247/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 248/800, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 249/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 250/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 251/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 252/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 253/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 254/800, Reward: -23.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 255/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 256/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 257/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 258/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 259/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 260/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 261/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 262/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 263/800, Reward: -34.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 264/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 265/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 266/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 267/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 268/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 269/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 270/800, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 271/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 272/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 273/800, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 274/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 275/800, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 276/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 277/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 278/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 279/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 280/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 281/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 282/800, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 283/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 284/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 285/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 286/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 287/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 288/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 289/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 290/800, Reward: -24.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 291/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 292/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 293/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 294/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 295/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 296/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 297/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 298/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 299/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 300/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 301/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 302/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 303/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 304/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 305/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 306/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 307/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 308/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 309/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 310/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 311/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 312/800, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 313/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 314/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 315/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 316/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 317/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 318/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 319/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 320/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 321/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 322/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 323/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 324/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 325/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 326/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 327/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 328/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 329/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 330/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 331/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 332/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 333/800, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 334/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 335/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 336/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 337/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 338/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 339/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 340/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 341/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 342/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 343/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 344/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 345/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 346/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 347/800, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 348/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 349/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 350/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 351/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 352/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 353/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 354/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 355/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 356/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 357/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 358/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 359/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 360/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 361/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 362/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 363/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 364/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 365/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 366/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 367/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 368/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 369/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 370/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 371/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 372/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 373/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 374/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 375/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 376/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 377/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 378/800, Reward: -123.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 379/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 380/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 381/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 382/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 383/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 384/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 385/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 386/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 387/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 388/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 389/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 390/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 391/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 392/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 393/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 394/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 395/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 396/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 397/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 398/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 399/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 400/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 401/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 402/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 403/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 404/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 405/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 406/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 407/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 408/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 409/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 410/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 411/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 412/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 413/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 414/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 415/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 416/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 417/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 418/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 419/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 420/800, Reward: -113.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 421/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 422/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 423/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 424/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 425/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 426/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 427/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 428/800, Reward: -115.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 429/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 430/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 431/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 432/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 433/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 434/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 435/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 436/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 437/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 438/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 439/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 440/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 441/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 442/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 443/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 444/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 445/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 446/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 447/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 448/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 449/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 450/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 451/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 452/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 453/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 454/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 455/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 456/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 457/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 458/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 459/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 460/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 461/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 462/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 463/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 464/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 465/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 466/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 467/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 468/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 469/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 470/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 471/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 472/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 473/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 474/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 475/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 476/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 477/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 478/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 479/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 480/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 481/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 482/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 483/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 484/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 485/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 486/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 487/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 488/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 489/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 490/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 491/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 492/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 493/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 494/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 495/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 496/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 497/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 498/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 499/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 500/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 501/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 502/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 503/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 504/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 505/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 506/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 507/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 508/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 509/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 510/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 511/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 512/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 513/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 514/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 515/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 516/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 517/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 518/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 519/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 520/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 521/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 522/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 523/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 524/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 525/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 526/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 527/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 528/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 529/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 530/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 531/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 532/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 533/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 534/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 535/800, Reward: -122.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 536/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 537/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 538/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 539/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 540/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 541/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 542/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 543/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 544/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 545/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 546/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 547/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 548/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 549/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 550/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 551/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 552/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 553/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 554/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 555/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 556/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 557/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 558/800, Reward: -115.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 559/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 560/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 561/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 562/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 563/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 564/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 565/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 566/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 567/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 568/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 569/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 570/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 571/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 572/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 573/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 574/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 575/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 576/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 577/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 578/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 579/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 580/800, Reward: -122.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 581/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 582/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 583/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 584/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 585/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 586/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 587/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 588/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 589/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 590/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 591/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 592/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 593/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 594/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 595/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 596/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 597/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 598/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 599/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 600/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 601/800, Reward: -122.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 602/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 603/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 604/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 605/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 606/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 607/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 608/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 609/800, Reward: -116.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 610/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 611/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 612/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 613/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 614/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 615/800, Reward: -115.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 616/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 617/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 618/800, Reward: -122.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 619/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 620/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 621/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 622/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 623/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 624/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 625/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 626/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 627/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 628/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 629/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 630/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 631/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 632/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 633/800, Reward: -116.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 634/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 635/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 636/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 637/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 638/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 639/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 640/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 641/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 642/800, Reward: -117.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 643/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 644/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 645/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 646/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 647/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 648/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 649/800, Reward: -223.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 650/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 651/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 652/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 653/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 654/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 655/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 656/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 657/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 658/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 659/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 660/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 661/800, Reward: -221.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 662/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 663/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 664/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 665/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 666/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 667/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 668/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 669/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 670/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 671/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 672/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 673/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 674/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 675/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 676/800, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 677/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 678/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 679/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 680/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 681/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 682/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 683/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 684/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 685/800, Reward: -113.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 686/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 687/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 688/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 689/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 690/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 691/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 692/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 693/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 694/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 695/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 696/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 697/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 698/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 699/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 700/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 701/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 702/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 703/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 704/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 705/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 706/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 707/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 708/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 709/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 710/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 711/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 712/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 713/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 714/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 715/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 716/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 717/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 718/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 719/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 720/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 721/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 722/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 723/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 724/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 725/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 726/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 727/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 728/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 729/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 730/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 731/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 732/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 733/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 734/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 735/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 736/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 737/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 738/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 739/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 740/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 741/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 742/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 743/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 744/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 745/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 746/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 747/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 748/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 749/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 750/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 751/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 752/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 753/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 754/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 755/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 756/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 757/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 758/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 759/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 760/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 761/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 762/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 763/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 764/800, Reward: -122.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 765/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 766/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 767/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 768/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 769/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 770/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 771/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 772/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 773/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 774/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 775/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 776/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 777/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 778/800, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 779/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 780/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 781/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 782/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 783/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 784/800, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 785/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 786/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 787/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 788/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 789/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 790/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 791/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 792/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 793/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 794/800, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 795/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 796/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 797/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 798/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 799/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Episode: 800/800, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:49:16 - r - INFO: - Finish training! diff --git a/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/models/Qleaning_model.pkl b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/models/Qleaning_model.pkl new file mode 100644 index 0000000..3be0dc4 Binary files /dev/null and b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/models/Qleaning_model.pkl differ diff --git a/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/results/learning_curve.png b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/results/learning_curve.png new file mode 100644 index 0000000..ee7abc9 Binary files /dev/null and b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/results/learning_curve.png differ diff --git a/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/results/res.csv b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/results/res.csv new file mode 100644 index 0000000..3799662 --- /dev/null +++ b/projects/codes/QLearning/Train_CliffWalking-v0_QLearning_20221030-014916/results/res.csv @@ -0,0 +1,801 @@ +episodes,rewards,steps +0,-1586,200 +1,-1091,200 +2,-596,200 +3,-497,200 +4,-398,200 +5,-362,164 +6,-179,179 +7,-398,200 +8,-79,79 +9,-141,141 +10,-143,143 +11,-134,134 +12,-299,200 +13,-102,102 +14,-61,61 +15,-136,136 +16,-176,176 +17,-98,98 +18,-92,92 +19,-110,110 +20,-67,67 +21,-136,136 +22,-98,98 +23,-164,164 +24,-65,65 +25,-98,98 +26,-33,33 +27,-161,161 +28,-72,72 +29,-73,73 +30,-116,116 +31,-50,50 +32,-66,66 +33,-123,123 +34,-40,40 +35,-100,100 +36,-56,56 +37,-101,101 +38,-55,55 +39,-84,84 +40,-68,68 +41,-33,33 +42,-113,113 +43,-72,72 +44,-36,36 +45,-84,84 +46,-45,45 +47,-86,86 +48,-57,57 +49,-92,92 +50,-39,39 +51,-76,76 +52,-39,39 +53,-47,47 +54,-88,88 +55,-40,40 +56,-55,55 +57,-69,69 +58,-51,51 +59,-69,69 +60,-36,36 +61,-84,84 +62,-38,38 +63,-56,56 +64,-58,58 +65,-27,27 +66,-64,64 +67,-38,38 +68,-53,53 +69,-70,70 +70,-40,40 +71,-47,47 +72,-71,71 +73,-47,47 +74,-32,32 +75,-70,70 +76,-36,36 +77,-36,36 +78,-73,73 +79,-18,18 +80,-67,67 +81,-29,29 +82,-25,25 +83,-64,64 +84,-28,28 +85,-61,61 +86,-33,33 +87,-30,30 +88,-25,25 +89,-86,86 +90,-19,19 +91,-53,53 +92,-39,39 +93,-39,39 +94,-36,36 +95,-45,45 +96,-43,43 +97,-31,31 +98,-37,37 +99,-43,43 +100,-46,46 +101,-28,28 +102,-32,32 +103,-47,47 +104,-37,37 +105,-39,39 +106,-38,38 +107,-29,29 +108,-44,44 +109,-39,39 +110,-26,26 +111,-28,28 +112,-63,63 +113,-18,18 +114,-52,52 +115,-24,24 +116,-26,26 +117,-39,39 +118,-21,21 +119,-44,44 +120,-48,48 +121,-24,24 +122,-40,40 +123,-31,31 +124,-23,23 +125,-35,35 +126,-26,26 +127,-31,31 +128,-33,33 +129,-32,32 +130,-36,36 +131,-21,21 +132,-43,43 +133,-51,51 +134,-17,17 +135,-28,28 +136,-24,24 +137,-42,42 +138,-21,21 +139,-24,24 +140,-30,30 +141,-24,24 +142,-36,36 +143,-14,14 +144,-42,42 +145,-44,44 +146,-25,25 +147,-42,42 +148,-16,16 +149,-30,30 +150,-32,32 +151,-20,20 +152,-44,44 +153,-20,20 +154,-29,29 +155,-20,20 +156,-30,30 +157,-18,18 +158,-25,25 +159,-38,38 +160,-34,34 +161,-25,25 +162,-30,30 +163,-24,24 +164,-19,19 +165,-34,34 +166,-15,15 +167,-27,27 +168,-22,22 +169,-28,28 +170,-13,13 +171,-20,20 +172,-58,58 +173,-18,18 +174,-19,19 +175,-29,29 +176,-125,26 +177,-156,57 +178,-18,18 +179,-25,25 +180,-27,27 +181,-21,21 +182,-22,22 +183,-21,21 +184,-22,22 +185,-25,25 +186,-25,25 +187,-27,27 +188,-19,19 +189,-26,26 +190,-17,17 +191,-21,21 +192,-30,30 +193,-16,16 +194,-35,35 +195,-21,21 +196,-134,35 +197,-21,21 +198,-18,18 +199,-27,27 +200,-16,16 +201,-44,44 +202,-23,23 +203,-23,23 +204,-16,16 +205,-18,18 +206,-17,17 +207,-18,18 +208,-16,16 +209,-13,13 +210,-19,19 +211,-26,26 +212,-27,27 +213,-133,34 +214,-21,21 +215,-24,24 +216,-29,29 +217,-24,24 +218,-16,16 +219,-16,16 +220,-24,24 +221,-17,17 +222,-143,44 +223,-15,15 +224,-15,15 +225,-23,23 +226,-21,21 +227,-26,26 +228,-16,16 +229,-19,19 +230,-13,13 +231,-19,19 +232,-29,29 +233,-26,26 +234,-30,30 +235,-13,13 +236,-13,13 +237,-21,21 +238,-15,15 +239,-18,18 +240,-13,13 +241,-16,16 +242,-27,27 +243,-17,17 +244,-27,27 +245,-15,15 +246,-14,14 +247,-28,28 +248,-17,17 +249,-15,15 +250,-17,17 +251,-19,19 +252,-13,13 +253,-23,23 +254,-15,15 +255,-15,15 +256,-19,19 +257,-15,15 +258,-22,22 +259,-13,13 +260,-16,16 +261,-15,15 +262,-34,34 +263,-16,16 +264,-26,26 +265,-13,13 +266,-15,15 +267,-15,15 +268,-18,18 +269,-18,18 +270,-13,13 +271,-13,13 +272,-19,19 +273,-13,13 +274,-27,27 +275,-13,13 +276,-13,13 +277,-22,22 +278,-17,17 +279,-17,17 +280,-13,13 +281,-26,26 +282,-13,13 +283,-13,13 +284,-14,14 +285,-15,15 +286,-13,13 +287,-13,13 +288,-14,14 +289,-24,24 +290,-21,21 +291,-13,13 +292,-13,13 +293,-14,14 +294,-15,15 +295,-13,13 +296,-13,13 +297,-13,13 +298,-14,14 +299,-21,21 +300,-15,15 +301,-13,13 +302,-13,13 +303,-21,21 +304,-13,13 +305,-22,22 +306,-13,13 +307,-13,13 +308,-16,16 +309,-15,15 +310,-13,13 +311,-31,31 +312,-13,13 +313,-13,13 +314,-15,15 +315,-13,13 +316,-13,13 +317,-13,13 +318,-14,14 +319,-13,13 +320,-15,15 +321,-13,13 +322,-13,13 +323,-13,13 +324,-16,16 +325,-13,13 +326,-13,13 +327,-13,13 +328,-13,13 +329,-13,13 +330,-13,13 +331,-15,15 +332,-16,16 +333,-13,13 +334,-13,13 +335,-13,13 +336,-13,13 +337,-13,13 +338,-15,15 +339,-13,13 +340,-13,13 +341,-13,13 +342,-13,13 +343,-13,13 +344,-13,13 +345,-13,13 +346,-22,22 +347,-13,13 +348,-13,13 +349,-13,13 +350,-17,17 +351,-13,13 +352,-13,13 +353,-13,13 +354,-13,13 +355,-13,13 +356,-13,13 +357,-13,13 +358,-13,13 +359,-13,13 +360,-13,13 +361,-13,13 +362,-13,13 +363,-13,13 +364,-13,13 +365,-13,13 +366,-13,13 +367,-13,13 +368,-13,13 +369,-13,13 +370,-13,13 +371,-13,13 +372,-13,13 +373,-13,13 +374,-13,13 +375,-13,13 +376,-21,21 +377,-123,24 +378,-13,13 +379,-14,14 +380,-13,13 +381,-13,13 +382,-13,13 +383,-13,13 +384,-13,13 +385,-13,13 +386,-13,13 +387,-13,13 +388,-13,13 +389,-13,13 +390,-13,13 +391,-13,13 +392,-13,13 +393,-13,13 +394,-13,13 +395,-13,13 +396,-15,15 +397,-13,13 +398,-13,13 +399,-13,13 +400,-14,14 +401,-13,13 +402,-13,13 +403,-13,13 +404,-13,13 +405,-13,13 +406,-13,13 +407,-13,13 +408,-13,13 +409,-13,13 +410,-13,13 +411,-13,13 +412,-13,13 +413,-13,13 +414,-13,13 +415,-13,13 +416,-13,13 +417,-13,13 +418,-13,13 +419,-113,14 +420,-13,13 +421,-13,13 +422,-13,13 +423,-13,13 +424,-13,13 +425,-13,13 +426,-13,13 +427,-115,16 +428,-13,13 +429,-13,13 +430,-13,13 +431,-13,13 +432,-13,13 +433,-13,13 +434,-15,15 +435,-13,13 +436,-13,13 +437,-13,13 +438,-13,13 +439,-13,13 +440,-13,13 +441,-13,13 +442,-13,13 +443,-13,13 +444,-13,13 +445,-15,15 +446,-13,13 +447,-13,13 +448,-13,13 +449,-13,13 +450,-13,13 +451,-13,13 +452,-13,13 +453,-13,13 +454,-13,13 +455,-13,13 +456,-13,13 +457,-13,13 +458,-13,13 +459,-13,13 +460,-13,13 +461,-13,13 +462,-13,13 +463,-13,13 +464,-13,13 +465,-13,13 +466,-13,13 +467,-13,13 +468,-13,13 +469,-15,15 +470,-13,13 +471,-13,13 +472,-13,13 +473,-13,13 +474,-13,13 +475,-13,13 +476,-13,13 +477,-13,13 +478,-13,13 +479,-13,13 +480,-13,13 +481,-13,13 +482,-13,13 +483,-13,13 +484,-13,13 +485,-13,13 +486,-13,13 +487,-13,13 +488,-13,13 +489,-13,13 +490,-13,13 +491,-13,13 +492,-13,13 +493,-13,13 +494,-13,13 +495,-13,13 +496,-13,13 +497,-13,13 +498,-13,13 +499,-13,13 +500,-13,13 +501,-13,13 +502,-15,15 +503,-13,13 +504,-13,13 +505,-15,15 +506,-13,13 +507,-13,13 +508,-13,13 +509,-13,13 +510,-13,13 +511,-13,13 +512,-13,13 +513,-13,13 +514,-13,13 +515,-13,13 +516,-13,13 +517,-13,13 +518,-13,13 +519,-13,13 +520,-13,13 +521,-13,13 +522,-13,13 +523,-13,13 +524,-13,13 +525,-13,13 +526,-15,15 +527,-13,13 +528,-13,13 +529,-13,13 +530,-13,13 +531,-13,13 +532,-13,13 +533,-13,13 +534,-122,23 +535,-13,13 +536,-13,13 +537,-13,13 +538,-13,13 +539,-13,13 +540,-13,13 +541,-13,13 +542,-13,13 +543,-15,15 +544,-13,13 +545,-13,13 +546,-13,13 +547,-13,13 +548,-13,13 +549,-13,13 +550,-13,13 +551,-15,15 +552,-13,13 +553,-13,13 +554,-13,13 +555,-13,13 +556,-13,13 +557,-115,16 +558,-13,13 +559,-15,15 +560,-13,13 +561,-13,13 +562,-13,13 +563,-13,13 +564,-13,13 +565,-13,13 +566,-13,13 +567,-13,13 +568,-13,13 +569,-13,13 +570,-13,13 +571,-13,13 +572,-13,13 +573,-13,13 +574,-15,15 +575,-13,13 +576,-13,13 +577,-13,13 +578,-13,13 +579,-122,23 +580,-13,13 +581,-13,13 +582,-13,13 +583,-13,13 +584,-14,14 +585,-14,14 +586,-13,13 +587,-13,13 +588,-13,13 +589,-13,13 +590,-13,13 +591,-13,13 +592,-13,13 +593,-13,13 +594,-15,15 +595,-13,13 +596,-13,13 +597,-13,13 +598,-13,13 +599,-13,13 +600,-122,23 +601,-13,13 +602,-13,13 +603,-13,13 +604,-13,13 +605,-13,13 +606,-13,13 +607,-13,13 +608,-116,17 +609,-13,13 +610,-13,13 +611,-13,13 +612,-13,13 +613,-13,13 +614,-115,16 +615,-13,13 +616,-13,13 +617,-122,23 +618,-13,13 +619,-13,13 +620,-13,13 +621,-13,13 +622,-13,13 +623,-13,13 +624,-13,13 +625,-13,13 +626,-13,13 +627,-13,13 +628,-13,13 +629,-13,13 +630,-15,15 +631,-13,13 +632,-116,17 +633,-13,13 +634,-13,13 +635,-13,13 +636,-13,13 +637,-13,13 +638,-13,13 +639,-13,13 +640,-13,13 +641,-117,18 +642,-13,13 +643,-13,13 +644,-13,13 +645,-13,13 +646,-13,13 +647,-13,13 +648,-223,25 +649,-13,13 +650,-13,13 +651,-13,13 +652,-13,13 +653,-13,13 +654,-15,15 +655,-13,13 +656,-13,13 +657,-13,13 +658,-13,13 +659,-13,13 +660,-221,23 +661,-13,13 +662,-15,15 +663,-13,13 +664,-13,13 +665,-13,13 +666,-13,13 +667,-13,13 +668,-13,13 +669,-13,13 +670,-13,13 +671,-13,13 +672,-13,13 +673,-13,13 +674,-13,13 +675,-21,21 +676,-13,13 +677,-15,15 +678,-13,13 +679,-13,13 +680,-13,13 +681,-13,13 +682,-13,13 +683,-13,13 +684,-113,14 +685,-13,13 +686,-13,13 +687,-13,13 +688,-13,13 +689,-13,13 +690,-13,13 +691,-13,13 +692,-13,13 +693,-13,13 +694,-13,13 +695,-13,13 +696,-13,13 +697,-13,13 +698,-13,13 +699,-13,13 +700,-13,13 +701,-15,15 +702,-13,13 +703,-15,15 +704,-13,13 +705,-13,13 +706,-15,15 +707,-13,13 +708,-13,13 +709,-13,13 +710,-13,13 +711,-17,17 +712,-13,13 +713,-13,13 +714,-13,13 +715,-13,13 +716,-13,13 +717,-13,13 +718,-13,13 +719,-13,13 +720,-14,14 +721,-13,13 +722,-13,13 +723,-13,13 +724,-13,13 +725,-13,13 +726,-13,13 +727,-13,13 +728,-13,13 +729,-13,13 +730,-13,13 +731,-13,13 +732,-14,14 +733,-13,13 +734,-13,13 +735,-13,13 +736,-13,13 +737,-15,15 +738,-13,13 +739,-15,15 +740,-13,13 +741,-13,13 +742,-13,13 +743,-13,13 +744,-15,15 +745,-13,13 +746,-13,13 +747,-13,13 +748,-15,15 +749,-13,13 +750,-13,13 +751,-13,13 +752,-13,13 +753,-13,13 +754,-13,13 +755,-13,13 +756,-13,13 +757,-13,13 +758,-13,13 +759,-13,13 +760,-13,13 +761,-13,13 +762,-13,13 +763,-122,23 +764,-15,15 +765,-13,13 +766,-13,13 +767,-13,13 +768,-13,13 +769,-13,13 +770,-13,13 +771,-13,13 +772,-13,13 +773,-13,13 +774,-15,15 +775,-13,13 +776,-13,13 +777,-14,14 +778,-13,13 +779,-13,13 +780,-13,13 +781,-13,13 +782,-13,13 +783,-17,17 +784,-13,13 +785,-13,13 +786,-13,13 +787,-15,15 +788,-13,13 +789,-13,13 +790,-13,13 +791,-13,13 +792,-13,13 +793,-15,15 +794,-13,13 +795,-13,13 +796,-13,13 +797,-13,13 +798,-13,13 +799,-13,13 diff --git a/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/config.yaml b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/config.yaml new file mode 100644 index 0000000..a0bf456 --- /dev/null +++ b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: FrozenLakeNoSlippery-v1 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + mode: train + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 2000 + epsilon_end: 0.1 + epsilon_start: 0.7 + gamma: 0.95 + lr: 0.9 diff --git a/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/logs/log.txt b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/logs/log.txt new file mode 100644 index 0000000..f52cf7f --- /dev/null +++ b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/logs/log.txt @@ -0,0 +1,804 @@ +2022-10-30 01:45:04 - r - INFO: - n_states: 16, n_actions: 4 +2022-10-30 01:45:04 - r - INFO: - Start training! +2022-10-30 01:45:04 - r - INFO: - Env: FrozenLakeNoSlippery-v1, Algorithm: QLearning, Device: cpu +2022-10-30 01:45:04 - r - INFO: - Episode: 1/800, Reward: 0.00: Epislon: 0.694 +2022-10-30 01:45:04 - r - INFO: - Episode: 2/800, Reward: 0.00: Epislon: 0.690 +2022-10-30 01:45:04 - r - INFO: - Episode: 3/800, Reward: 0.00: Epislon: 0.686 +2022-10-30 01:45:04 - r - INFO: - Episode: 4/800, Reward: 0.00: Epislon: 0.683 +2022-10-30 01:45:04 - r - INFO: - Episode: 5/800, Reward: 0.00: Epislon: 0.681 +2022-10-30 01:45:04 - r - INFO: - Episode: 6/800, Reward: 0.00: Epislon: 0.679 +2022-10-30 01:45:04 - r - INFO: - Episode: 7/800, Reward: 0.00: Epislon: 0.676 +2022-10-30 01:45:04 - r - INFO: - Episode: 8/800, Reward: 0.00: Epislon: 0.674 +2022-10-30 01:45:04 - r - INFO: - Episode: 9/800, Reward: 0.00: Epislon: 0.673 +2022-10-30 01:45:04 - r - INFO: - Episode: 10/800, Reward: 0.00: Epislon: 0.670 +2022-10-30 01:45:04 - r - INFO: - Episode: 11/800, Reward: 0.00: Epislon: 0.667 +2022-10-30 01:45:04 - r - INFO: - Episode: 12/800, Reward: 0.00: Epislon: 0.661 +2022-10-30 01:45:04 - r - INFO: - Episode: 13/800, Reward: 0.00: Epislon: 0.660 +2022-10-30 01:45:04 - r - INFO: - Episode: 14/800, Reward: 0.00: Epislon: 0.655 +2022-10-30 01:45:04 - r - INFO: - Episode: 15/800, Reward: 0.00: Epislon: 0.654 +2022-10-30 01:45:04 - r - INFO: - Episode: 16/800, Reward: 0.00: Epislon: 0.652 +2022-10-30 01:45:04 - r - INFO: - Episode: 17/800, Reward: 0.00: Epislon: 0.647 +2022-10-30 01:45:04 - r - INFO: - Episode: 18/800, Reward: 0.00: Epislon: 0.646 +2022-10-30 01:45:04 - r - INFO: - Episode: 19/800, Reward: 0.00: Epislon: 0.645 +2022-10-30 01:45:04 - r - INFO: - Episode: 20/800, Reward: 0.00: Epislon: 0.643 +2022-10-30 01:45:04 - r - INFO: - Episode: 21/800, Reward: 0.00: Epislon: 0.641 +2022-10-30 01:45:04 - r - INFO: - Episode: 22/800, Reward: 0.00: Epislon: 0.640 +2022-10-30 01:45:04 - r - INFO: - Episode: 23/800, Reward: 0.00: Epislon: 0.634 +2022-10-30 01:45:04 - r - INFO: - Episode: 24/800, Reward: 0.00: Epislon: 0.630 +2022-10-30 01:45:04 - r - INFO: - Episode: 25/800, Reward: 0.00: Epislon: 0.629 +2022-10-30 01:45:04 - r - INFO: - Episode: 26/800, Reward: 0.00: Epislon: 0.624 +2022-10-30 01:45:04 - r - INFO: - Episode: 27/800, Reward: 0.00: Epislon: 0.623 +2022-10-30 01:45:04 - r - INFO: - Episode: 28/800, Reward: 0.00: Epislon: 0.618 +2022-10-30 01:45:04 - r - INFO: - Episode: 29/800, Reward: 0.00: Epislon: 0.612 +2022-10-30 01:45:04 - r - INFO: - Episode: 30/800, Reward: 0.00: Epislon: 0.608 +2022-10-30 01:45:04 - r - INFO: - Episode: 31/800, Reward: 0.00: Epislon: 0.605 +2022-10-30 01:45:05 - r - INFO: - Episode: 32/800, Reward: 0.00: Epislon: 0.600 +2022-10-30 01:45:05 - r - INFO: - Episode: 33/800, Reward: 0.00: Epislon: 0.593 +2022-10-30 01:45:05 - r - INFO: - Episode: 34/800, Reward: 0.00: Epislon: 0.587 +2022-10-30 01:45:05 - r - INFO: - Episode: 35/800, Reward: 0.00: Epislon: 0.586 +2022-10-30 01:45:05 - r - INFO: - Episode: 36/800, Reward: 0.00: Epislon: 0.583 +2022-10-30 01:45:05 - r - INFO: - Episode: 37/800, Reward: 0.00: Epislon: 0.582 +2022-10-30 01:45:05 - r - INFO: - Episode: 38/800, Reward: 0.00: Epislon: 0.578 +2022-10-30 01:45:05 - r - INFO: - Episode: 39/800, Reward: 0.00: Epislon: 0.577 +2022-10-30 01:45:05 - r - INFO: - Episode: 40/800, Reward: 0.00: Epislon: 0.575 +2022-10-30 01:45:05 - r - INFO: - Episode: 41/800, Reward: 0.00: Epislon: 0.573 +2022-10-30 01:45:05 - r - INFO: - Episode: 42/800, Reward: 0.00: Epislon: 0.572 +2022-10-30 01:45:05 - r - INFO: - Episode: 43/800, Reward: 0.00: Epislon: 0.571 +2022-10-30 01:45:05 - r - INFO: - Episode: 44/800, Reward: 0.00: Epislon: 0.570 +2022-10-30 01:45:05 - r - INFO: - Episode: 45/800, Reward: 0.00: Epislon: 0.560 +2022-10-30 01:45:05 - r - INFO: - Episode: 46/800, Reward: 0.00: Epislon: 0.558 +2022-10-30 01:45:05 - r - INFO: - Episode: 47/800, Reward: 0.00: Epislon: 0.553 +2022-10-30 01:45:05 - r - INFO: - Episode: 48/800, Reward: 0.00: Epislon: 0.552 +2022-10-30 01:45:05 - r - INFO: - Episode: 49/800, Reward: 1.00: Epislon: 0.544 +2022-10-30 01:45:05 - r - INFO: - Episode: 50/800, Reward: 0.00: Epislon: 0.537 +2022-10-30 01:45:05 - r - INFO: - Episode: 51/800, Reward: 0.00: Epislon: 0.534 +2022-10-30 01:45:05 - r - INFO: - Episode: 52/800, Reward: 0.00: Epislon: 0.533 +2022-10-30 01:45:05 - r - INFO: - Episode: 53/800, Reward: 0.00: Epislon: 0.532 +2022-10-30 01:45:05 - r - INFO: - Episode: 54/800, Reward: 0.00: Epislon: 0.527 +2022-10-30 01:45:05 - r - INFO: - Episode: 55/800, Reward: 0.00: Epislon: 0.526 +2022-10-30 01:45:05 - r - INFO: - Episode: 56/800, Reward: 0.00: Epislon: 0.525 +2022-10-30 01:45:05 - r - INFO: - Episode: 57/800, Reward: 0.00: Epislon: 0.519 +2022-10-30 01:45:05 - r - INFO: - Episode: 58/800, Reward: 0.00: Epislon: 0.518 +2022-10-30 01:45:05 - r - INFO: - Episode: 59/800, Reward: 0.00: Epislon: 0.516 +2022-10-30 01:45:05 - r - INFO: - Episode: 60/800, Reward: 0.00: Epislon: 0.514 +2022-10-30 01:45:05 - r - INFO: - Episode: 61/800, Reward: 0.00: Epislon: 0.512 +2022-10-30 01:45:05 - r - INFO: - Episode: 62/800, Reward: 0.00: Epislon: 0.511 +2022-10-30 01:45:05 - r - INFO: - Episode: 63/800, Reward: 0.00: Epislon: 0.506 +2022-10-30 01:45:05 - r - INFO: - Episode: 64/800, Reward: 0.00: Epislon: 0.504 +2022-10-30 01:45:05 - r - INFO: - Episode: 65/800, Reward: 0.00: Epislon: 0.503 +2022-10-30 01:45:05 - r - INFO: - Episode: 66/800, Reward: 0.00: Epislon: 0.502 +2022-10-30 01:45:05 - r - INFO: - Episode: 67/800, Reward: 0.00: Epislon: 0.501 +2022-10-30 01:45:05 - r - INFO: - Episode: 68/800, Reward: 0.00: Epislon: 0.497 +2022-10-30 01:45:05 - r - INFO: - Episode: 69/800, Reward: 0.00: Epislon: 0.496 +2022-10-30 01:45:05 - r - INFO: - Episode: 70/800, Reward: 0.00: Epislon: 0.491 +2022-10-30 01:45:05 - r - INFO: - Episode: 71/800, Reward: 0.00: Epislon: 0.489 +2022-10-30 01:45:05 - r - INFO: - Episode: 72/800, Reward: 0.00: Epislon: 0.487 +2022-10-30 01:45:05 - r - INFO: - Episode: 73/800, Reward: 0.00: Epislon: 0.486 +2022-10-30 01:45:05 - r - INFO: - Episode: 74/800, Reward: 0.00: Epislon: 0.481 +2022-10-30 01:45:05 - r - INFO: - Episode: 75/800, Reward: 0.00: Epislon: 0.477 +2022-10-30 01:45:05 - r - INFO: - Episode: 76/800, Reward: 0.00: Epislon: 0.475 +2022-10-30 01:45:05 - r - INFO: - Episode: 77/800, Reward: 0.00: Epislon: 0.474 +2022-10-30 01:45:05 - r - INFO: - Episode: 78/800, Reward: 0.00: Epislon: 0.468 +2022-10-30 01:45:05 - r - INFO: - Episode: 79/800, Reward: 0.00: Epislon: 0.465 +2022-10-30 01:45:05 - r - INFO: - Episode: 80/800, Reward: 0.00: Epislon: 0.464 +2022-10-30 01:45:05 - r - INFO: - Episode: 81/800, Reward: 0.00: Epislon: 0.462 +2022-10-30 01:45:05 - r - INFO: - Episode: 82/800, Reward: 0.00: Epislon: 0.460 +2022-10-30 01:45:05 - r - INFO: - Episode: 83/800, Reward: 0.00: Epislon: 0.457 +2022-10-30 01:45:05 - r - INFO: - Episode: 84/800, Reward: 0.00: Epislon: 0.455 +2022-10-30 01:45:05 - r - INFO: - Episode: 85/800, Reward: 0.00: Epislon: 0.454 +2022-10-30 01:45:05 - r - INFO: - Episode: 86/800, Reward: 0.00: Epislon: 0.452 +2022-10-30 01:45:05 - r - INFO: - Episode: 87/800, Reward: 0.00: Epislon: 0.444 +2022-10-30 01:45:05 - r - INFO: - Episode: 88/800, Reward: 0.00: Epislon: 0.440 +2022-10-30 01:45:05 - r - INFO: - Episode: 89/800, Reward: 0.00: Epislon: 0.414 +2022-10-30 01:45:05 - r - INFO: - Episode: 90/800, Reward: 0.00: Epislon: 0.413 +2022-10-30 01:45:05 - r - INFO: - Episode: 91/800, Reward: 0.00: Epislon: 0.411 +2022-10-30 01:45:05 - r - INFO: - Episode: 92/800, Reward: 0.00: Epislon: 0.407 +2022-10-30 01:45:05 - r - INFO: - Episode: 93/800, Reward: 0.00: Epislon: 0.407 +2022-10-30 01:45:05 - r - INFO: - Episode: 94/800, Reward: 0.00: Epislon: 0.406 +2022-10-30 01:45:05 - r - INFO: - Episode: 95/800, Reward: 0.00: Epislon: 0.403 +2022-10-30 01:45:05 - r - INFO: - Episode: 96/800, Reward: 0.00: Epislon: 0.390 +2022-10-30 01:45:05 - r - INFO: - Episode: 97/800, Reward: 0.00: Epislon: 0.386 +2022-10-30 01:45:05 - r - INFO: - Episode: 98/800, Reward: 0.00: Epislon: 0.385 +2022-10-30 01:45:05 - r - INFO: - Episode: 99/800, Reward: 0.00: Epislon: 0.385 +2022-10-30 01:45:05 - r - INFO: - Episode: 100/800, Reward: 0.00: Epislon: 0.383 +2022-10-30 01:45:05 - r - INFO: - Episode: 101/800, Reward: 0.00: Epislon: 0.381 +2022-10-30 01:45:05 - r - INFO: - Episode: 102/800, Reward: 0.00: Epislon: 0.380 +2022-10-30 01:45:05 - r - INFO: - Episode: 103/800, Reward: 0.00: Epislon: 0.378 +2022-10-30 01:45:05 - r - INFO: - Episode: 104/800, Reward: 0.00: Epislon: 0.366 +2022-10-30 01:45:05 - r - INFO: - Episode: 105/800, Reward: 0.00: Epislon: 0.365 +2022-10-30 01:45:05 - r - INFO: - Episode: 106/800, Reward: 0.00: Epislon: 0.359 +2022-10-30 01:45:05 - r - INFO: - Episode: 107/800, Reward: 0.00: Epislon: 0.357 +2022-10-30 01:45:05 - r - INFO: - Episode: 108/800, Reward: 0.00: Epislon: 0.356 +2022-10-30 01:45:05 - r - INFO: - Episode: 109/800, Reward: 0.00: Epislon: 0.350 +2022-10-30 01:45:05 - r - INFO: - Episode: 110/800, Reward: 0.00: Epislon: 0.347 +2022-10-30 01:45:05 - r - INFO: - Episode: 111/800, Reward: 0.00: Epislon: 0.345 +2022-10-30 01:45:05 - r - INFO: - Episode: 112/800, Reward: 0.00: Epislon: 0.343 +2022-10-30 01:45:05 - r - INFO: - Episode: 113/800, Reward: 0.00: Epislon: 0.322 +2022-10-30 01:45:05 - r - INFO: - Episode: 114/800, Reward: 0.00: Epislon: 0.317 +2022-10-30 01:45:05 - r - INFO: - Episode: 115/800, Reward: 0.00: Epislon: 0.308 +2022-10-30 01:45:05 - r - INFO: - Episode: 116/800, Reward: 0.00: Epislon: 0.306 +2022-10-30 01:45:05 - r - INFO: - Episode: 117/800, Reward: 0.00: Epislon: 0.303 +2022-10-30 01:45:05 - r - INFO: - Episode: 118/800, Reward: 0.00: Epislon: 0.300 +2022-10-30 01:45:05 - r - INFO: - Episode: 119/800, Reward: 0.00: Epislon: 0.300 +2022-10-30 01:45:05 - r - INFO: - Episode: 120/800, Reward: 0.00: Epislon: 0.291 +2022-10-30 01:45:05 - r - INFO: - Episode: 121/800, Reward: 0.00: Epislon: 0.290 +2022-10-30 01:45:05 - r - INFO: - Episode: 122/800, Reward: 0.00: Epislon: 0.284 +2022-10-30 01:45:05 - r - INFO: - Episode: 123/800, Reward: 0.00: Epislon: 0.282 +2022-10-30 01:45:05 - r - INFO: - Episode: 124/800, Reward: 0.00: Epislon: 0.276 +2022-10-30 01:45:05 - r - INFO: - Episode: 125/800, Reward: 0.00: Epislon: 0.269 +2022-10-30 01:45:05 - r - INFO: - Episode: 126/800, Reward: 0.00: Epislon: 0.262 +2022-10-30 01:45:05 - r - INFO: - Episode: 127/800, Reward: 0.00: Epislon: 0.246 +2022-10-30 01:45:05 - r - INFO: - Episode: 128/800, Reward: 0.00: Epislon: 0.244 +2022-10-30 01:45:05 - r - INFO: - Episode: 129/800, Reward: 0.00: Epislon: 0.241 +2022-10-30 01:45:05 - r - INFO: - Episode: 130/800, Reward: 0.00: Epislon: 0.236 +2022-10-30 01:45:05 - r - INFO: - Episode: 131/800, Reward: 0.00: Epislon: 0.235 +2022-10-30 01:45:05 - r - INFO: - Episode: 132/800, Reward: 0.00: Epislon: 0.234 +2022-10-30 01:45:05 - r - INFO: - Episode: 133/800, Reward: 0.00: Epislon: 0.233 +2022-10-30 01:45:05 - r - INFO: - Episode: 134/800, Reward: 0.00: Epislon: 0.231 +2022-10-30 01:45:05 - r - INFO: - Episode: 135/800, Reward: 0.00: Epislon: 0.229 +2022-10-30 01:45:05 - r - INFO: - Episode: 136/800, Reward: 0.00: Epislon: 0.227 +2022-10-30 01:45:05 - r - INFO: - Episode: 137/800, Reward: 0.00: Epislon: 0.226 +2022-10-30 01:45:05 - r - INFO: - Episode: 138/800, Reward: 0.00: Epislon: 0.223 +2022-10-30 01:45:05 - r - INFO: - Episode: 139/800, Reward: 0.00: Epislon: 0.216 +2022-10-30 01:45:05 - r - INFO: - Episode: 140/800, Reward: 0.00: Epislon: 0.214 +2022-10-30 01:45:05 - r - INFO: - Episode: 141/800, Reward: 0.00: Epislon: 0.213 +2022-10-30 01:45:05 - r - INFO: - Episode: 142/800, Reward: 0.00: Epislon: 0.211 +2022-10-30 01:45:05 - r - INFO: - Episode: 143/800, Reward: 0.00: Epislon: 0.210 +2022-10-30 01:45:05 - r - INFO: - Episode: 144/800, Reward: 0.00: Epislon: 0.207 +2022-10-30 01:45:05 - r - INFO: - Episode: 145/800, Reward: 0.00: Epislon: 0.202 +2022-10-30 01:45:05 - r - INFO: - Episode: 146/800, Reward: 0.00: Epislon: 0.201 +2022-10-30 01:45:05 - r - INFO: - Episode: 147/800, Reward: 0.00: Epislon: 0.198 +2022-10-30 01:45:05 - r - INFO: - Episode: 148/800, Reward: 0.00: Epislon: 0.196 +2022-10-30 01:45:05 - r - INFO: - Episode: 149/800, Reward: 0.00: Epislon: 0.195 +2022-10-30 01:45:05 - r - INFO: - Episode: 150/800, Reward: 0.00: Epislon: 0.192 +2022-10-30 01:45:05 - r - INFO: - Episode: 151/800, Reward: 0.00: Epislon: 0.190 +2022-10-30 01:45:05 - r - INFO: - Episode: 152/800, Reward: 0.00: Epislon: 0.188 +2022-10-30 01:45:05 - r - INFO: - Episode: 153/800, Reward: 0.00: Epislon: 0.186 +2022-10-30 01:45:05 - r - INFO: - Episode: 154/800, Reward: 0.00: Epislon: 0.185 +2022-10-30 01:45:05 - r - INFO: - Episode: 155/800, Reward: 0.00: Epislon: 0.185 +2022-10-30 01:45:05 - r - INFO: - Episode: 156/800, Reward: 0.00: Epislon: 0.183 +2022-10-30 01:45:05 - r - INFO: - Episode: 157/800, Reward: 0.00: Epislon: 0.182 +2022-10-30 01:45:05 - r - INFO: - Episode: 158/800, Reward: 0.00: Epislon: 0.181 +2022-10-30 01:45:05 - r - INFO: - Episode: 159/800, Reward: 0.00: Epislon: 0.179 +2022-10-30 01:45:05 - r - INFO: - Episode: 160/800, Reward: 0.00: Epislon: 0.173 +2022-10-30 01:45:05 - r - INFO: - Episode: 161/800, Reward: 0.00: Epislon: 0.169 +2022-10-30 01:45:05 - r - INFO: - Episode: 162/800, Reward: 0.00: Epislon: 0.167 +2022-10-30 01:45:05 - r - INFO: - Episode: 163/800, Reward: 0.00: Epislon: 0.165 +2022-10-30 01:45:05 - r - INFO: - Episode: 164/800, Reward: 0.00: Epislon: 0.165 +2022-10-30 01:45:05 - r - INFO: - Episode: 165/800, Reward: 0.00: Epislon: 0.163 +2022-10-30 01:45:05 - r - INFO: - Episode: 166/800, Reward: 0.00: Epislon: 0.163 +2022-10-30 01:45:05 - r - INFO: - Episode: 167/800, Reward: 0.00: Epislon: 0.162 +2022-10-30 01:45:05 - r - INFO: - Episode: 168/800, Reward: 0.00: Epislon: 0.161 +2022-10-30 01:45:05 - r - INFO: - Episode: 169/800, Reward: 0.00: Epislon: 0.160 +2022-10-30 01:45:05 - r - INFO: - Episode: 170/800, Reward: 0.00: Epislon: 0.159 +2022-10-30 01:45:05 - r - INFO: - Episode: 171/800, Reward: 0.00: Epislon: 0.158 +2022-10-30 01:45:05 - r - INFO: - Episode: 172/800, Reward: 0.00: Epislon: 0.155 +2022-10-30 01:45:05 - r - INFO: - Episode: 173/800, Reward: 0.00: Epislon: 0.151 +2022-10-30 01:45:05 - r - INFO: - Episode: 174/800, Reward: 0.00: Epislon: 0.149 +2022-10-30 01:45:05 - r - INFO: - Episode: 175/800, Reward: 0.00: Epislon: 0.148 +2022-10-30 01:45:05 - r - INFO: - Episode: 176/800, Reward: 0.00: Epislon: 0.148 +2022-10-30 01:45:05 - r - INFO: - Episode: 177/800, Reward: 0.00: Epislon: 0.148 +2022-10-30 01:45:05 - r - INFO: - Episode: 178/800, Reward: 0.00: Epislon: 0.147 +2022-10-30 01:45:05 - r - INFO: - Episode: 179/800, Reward: 0.00: Epislon: 0.146 +2022-10-30 01:45:05 - r - INFO: - Episode: 180/800, Reward: 0.00: Epislon: 0.146 +2022-10-30 01:45:05 - r - INFO: - Episode: 181/800, Reward: 0.00: Epislon: 0.145 +2022-10-30 01:45:05 - r - INFO: - Episode: 182/800, Reward: 0.00: Epislon: 0.144 +2022-10-30 01:45:05 - r - INFO: - Episode: 183/800, Reward: 0.00: Epislon: 0.140 +2022-10-30 01:45:05 - r - INFO: - Episode: 184/800, Reward: 0.00: Epislon: 0.139 +2022-10-30 01:45:05 - r - INFO: - Episode: 185/800, Reward: 0.00: Epislon: 0.138 +2022-10-30 01:45:05 - r - INFO: - Episode: 186/800, Reward: 0.00: Epislon: 0.137 +2022-10-30 01:45:05 - r - INFO: - Episode: 187/800, Reward: 0.00: Epislon: 0.137 +2022-10-30 01:45:05 - r - INFO: - Episode: 188/800, Reward: 0.00: Epislon: 0.134 +2022-10-30 01:45:05 - r - INFO: - Episode: 189/800, Reward: 0.00: Epislon: 0.134 +2022-10-30 01:45:05 - r - INFO: - Episode: 190/800, Reward: 0.00: Epislon: 0.133 +2022-10-30 01:45:05 - r - INFO: - Episode: 191/800, Reward: 0.00: Epislon: 0.133 +2022-10-30 01:45:05 - r - INFO: - Episode: 192/800, Reward: 0.00: Epislon: 0.132 +2022-10-30 01:45:05 - r - INFO: - Episode: 193/800, Reward: 0.00: Epislon: 0.131 +2022-10-30 01:45:05 - r - INFO: - Episode: 194/800, Reward: 0.00: Epislon: 0.131 +2022-10-30 01:45:05 - r - INFO: - Episode: 195/800, Reward: 0.00: Epislon: 0.130 +2022-10-30 01:45:05 - r - INFO: - Episode: 196/800, Reward: 0.00: Epislon: 0.129 +2022-10-30 01:45:05 - r - INFO: - Episode: 197/800, Reward: 0.00: Epislon: 0.129 +2022-10-30 01:45:05 - r - INFO: - Episode: 198/800, Reward: 0.00: Epislon: 0.126 +2022-10-30 01:45:05 - r - INFO: - Episode: 199/800, Reward: 0.00: Epislon: 0.123 +2022-10-30 01:45:05 - r - INFO: - Episode: 200/800, Reward: 0.00: Epislon: 0.123 +2022-10-30 01:45:05 - r - INFO: - Episode: 201/800, Reward: 0.00: Epislon: 0.122 +2022-10-30 01:45:05 - r - INFO: - Episode: 202/800, Reward: 0.00: Epislon: 0.122 +2022-10-30 01:45:05 - r - INFO: - Episode: 203/800, Reward: 0.00: Epislon: 0.122 +2022-10-30 01:45:05 - r - INFO: - Episode: 204/800, Reward: 0.00: Epislon: 0.121 +2022-10-30 01:45:05 - r - INFO: - Episode: 205/800, Reward: 0.00: Epislon: 0.119 +2022-10-30 01:45:05 - r - INFO: - Episode: 206/800, Reward: 0.00: Epislon: 0.119 +2022-10-30 01:45:05 - r - INFO: - Episode: 207/800, Reward: 0.00: Epislon: 0.119 +2022-10-30 01:45:05 - r - INFO: - Episode: 208/800, Reward: 0.00: Epislon: 0.118 +2022-10-30 01:45:05 - r - INFO: - Episode: 209/800, Reward: 0.00: Epislon: 0.118 +2022-10-30 01:45:05 - r - INFO: - Episode: 210/800, Reward: 0.00: Epislon: 0.118 +2022-10-30 01:45:05 - r - INFO: - Episode: 211/800, Reward: 0.00: Epislon: 0.116 +2022-10-30 01:45:05 - r - INFO: - Episode: 212/800, Reward: 0.00: Epislon: 0.115 +2022-10-30 01:45:05 - r - INFO: - Episode: 213/800, Reward: 0.00: Epislon: 0.115 +2022-10-30 01:45:05 - r - INFO: - Episode: 214/800, Reward: 0.00: Epislon: 0.114 +2022-10-30 01:45:05 - r - INFO: - Episode: 215/800, Reward: 0.00: Epislon: 0.113 +2022-10-30 01:45:05 - r - INFO: - Episode: 216/800, Reward: 0.00: Epislon: 0.113 +2022-10-30 01:45:05 - r - INFO: - Episode: 217/800, Reward: 0.00: Epislon: 0.112 +2022-10-30 01:45:05 - r - INFO: - Episode: 218/800, Reward: 0.00: Epislon: 0.111 +2022-10-30 01:45:05 - r - INFO: - Episode: 219/800, Reward: 0.00: Epislon: 0.111 +2022-10-30 01:45:05 - r - INFO: - Episode: 220/800, Reward: 0.00: Epislon: 0.111 +2022-10-30 01:45:05 - r - INFO: - Episode: 221/800, Reward: 0.00: Epislon: 0.110 +2022-10-30 01:45:05 - r - INFO: - Episode: 222/800, Reward: 0.00: Epislon: 0.110 +2022-10-30 01:45:05 - r - INFO: - Episode: 223/800, Reward: 0.00: Epislon: 0.109 +2022-10-30 01:45:05 - r - INFO: - Episode: 224/800, Reward: 0.00: Epislon: 0.108 +2022-10-30 01:45:05 - r - INFO: - Episode: 225/800, Reward: 0.00: Epislon: 0.108 +2022-10-30 01:45:05 - r - INFO: - Episode: 226/800, Reward: 0.00: Epislon: 0.108 +2022-10-30 01:45:05 - r - INFO: - Episode: 227/800, Reward: 0.00: Epislon: 0.108 +2022-10-30 01:45:05 - r - INFO: - Episode: 228/800, Reward: 0.00: Epislon: 0.107 +2022-10-30 01:45:05 - r - INFO: - Episode: 229/800, Reward: 0.00: Epislon: 0.107 +2022-10-30 01:45:05 - r - INFO: - Episode: 230/800, Reward: 0.00: Epislon: 0.107 +2022-10-30 01:45:05 - r - INFO: - Episode: 231/800, Reward: 0.00: Epislon: 0.107 +2022-10-30 01:45:05 - r - INFO: - Episode: 232/800, Reward: 0.00: Epislon: 0.106 +2022-10-30 01:45:05 - r - INFO: - Episode: 233/800, Reward: 0.00: Epislon: 0.106 +2022-10-30 01:45:05 - r - INFO: - Episode: 234/800, Reward: 0.00: Epislon: 0.106 +2022-10-30 01:45:05 - r - INFO: - Episode: 235/800, Reward: 0.00: Epislon: 0.105 +2022-10-30 01:45:05 - r - INFO: - Episode: 236/800, Reward: 0.00: Epislon: 0.105 +2022-10-30 01:45:05 - r - INFO: - Episode: 237/800, Reward: 0.00: Epislon: 0.105 +2022-10-30 01:45:05 - r - INFO: - Episode: 238/800, Reward: 0.00: Epislon: 0.105 +2022-10-30 01:45:05 - r - INFO: - Episode: 239/800, Reward: 0.00: Epislon: 0.104 +2022-10-30 01:45:05 - r - INFO: - Episode: 240/800, Reward: 0.00: Epislon: 0.104 +2022-10-30 01:45:05 - r - INFO: - Episode: 241/800, Reward: 0.00: Epislon: 0.104 +2022-10-30 01:45:05 - r - INFO: - Episode: 242/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 243/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 244/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 245/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 246/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 247/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 248/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 249/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 250/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 251/800, Reward: 0.00: Epislon: 0.103 +2022-10-30 01:45:05 - r - INFO: - Episode: 252/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 253/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 254/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 255/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 256/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 257/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 258/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 259/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 260/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 261/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 262/800, Reward: 0.00: Epislon: 0.102 +2022-10-30 01:45:05 - r - INFO: - Episode: 263/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 264/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 265/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 266/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 267/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 268/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 269/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 270/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 271/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 272/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 273/800, Reward: 1.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 274/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 275/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 276/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 277/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 278/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 279/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 280/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 281/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 282/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 283/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 284/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 285/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 286/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 287/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 288/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 289/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 290/800, Reward: 0.00: Epislon: 0.101 +2022-10-30 01:45:05 - r - INFO: - Episode: 291/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 292/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 293/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 294/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 295/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 296/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 297/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 298/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 299/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 300/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 301/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 302/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 303/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 304/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 305/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 306/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 307/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 308/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 309/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 310/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 311/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 312/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 313/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 314/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 315/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 316/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 317/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 318/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 319/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 320/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 321/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 322/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 323/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 324/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 325/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 326/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 327/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 328/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 329/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 330/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 331/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 332/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 333/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 334/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 335/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 336/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 337/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 338/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 339/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 340/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 341/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 342/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 343/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 344/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 345/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 346/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 347/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 348/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 349/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 350/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 351/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 352/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 353/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 354/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 355/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 356/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 357/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 358/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 359/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 360/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 361/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 362/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 363/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 364/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 365/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 366/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 367/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 368/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 369/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 370/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 371/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 372/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 373/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 374/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 375/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 376/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 377/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 378/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 379/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 380/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 381/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 382/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 383/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 384/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 385/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 386/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 387/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 388/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 389/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 390/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 391/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 392/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 393/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 394/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 395/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 396/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 397/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 398/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 399/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 400/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 401/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 402/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 403/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 404/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 405/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 406/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 407/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 408/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 409/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 410/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 411/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 412/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 413/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 414/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 415/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 416/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 417/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 418/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 419/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 420/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 421/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 422/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 423/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 424/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 425/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 426/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 427/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 428/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 429/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 430/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 431/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 432/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 433/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 434/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 435/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 436/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 437/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 438/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 439/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 440/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 441/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 442/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 443/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 444/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 445/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 446/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 447/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 448/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 449/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 450/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 451/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 452/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 453/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 454/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 455/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 456/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 457/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 458/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 459/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 460/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 461/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 462/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 463/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 464/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 465/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 466/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 467/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 468/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 469/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 470/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 471/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 472/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 473/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 474/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 475/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 476/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 477/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 478/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 479/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 480/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 481/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 482/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 483/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 484/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 485/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 486/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 487/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 488/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 489/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 490/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 491/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 492/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 493/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 494/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 495/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 496/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 497/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 498/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 499/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 500/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 501/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 502/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 503/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 504/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 505/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 506/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 507/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 508/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 509/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 510/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 511/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 512/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 513/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 514/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 515/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 516/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 517/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 518/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 519/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 520/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 521/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 522/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 523/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 524/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 525/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 526/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 527/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 528/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 529/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 530/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 531/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 532/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 533/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 534/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 535/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 536/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 537/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 538/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 539/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 540/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 541/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 542/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 543/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 544/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 545/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 546/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 547/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 548/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 549/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 550/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 551/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 552/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 553/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 554/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 555/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 556/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 557/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 558/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 559/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 560/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 561/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 562/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 563/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 564/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 565/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 566/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 567/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 568/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 569/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 570/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 571/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 572/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 573/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 574/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 575/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 576/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 577/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 578/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 579/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 580/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 581/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 582/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 583/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 584/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 585/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 586/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 587/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 588/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 589/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 590/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 591/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 592/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 593/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 594/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 595/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 596/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 597/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 598/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 599/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 600/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 601/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 602/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 603/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 604/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 605/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 606/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 607/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 608/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 609/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 610/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 611/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 612/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 613/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 614/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 615/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 616/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 617/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 618/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 619/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 620/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 621/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 622/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 623/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 624/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 625/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 626/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 627/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 628/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 629/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 630/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 631/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 632/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 633/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 634/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 635/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 636/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 637/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 638/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 639/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 640/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 641/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 642/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 643/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 644/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 645/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 646/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 647/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 648/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 649/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 650/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 651/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 652/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 653/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 654/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 655/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 656/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 657/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 658/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 659/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 660/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 661/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 662/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 663/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 664/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 665/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 666/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 667/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 668/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 669/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 670/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 671/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 672/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 673/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 674/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 675/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 676/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 677/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 678/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 679/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 680/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 681/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 682/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 683/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 684/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 685/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 686/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 687/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 688/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 689/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 690/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 691/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 692/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 693/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 694/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 695/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 696/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 697/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 698/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 699/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 700/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 701/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 702/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 703/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 704/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 705/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 706/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 707/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 708/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 709/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 710/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 711/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 712/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 713/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 714/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 715/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 716/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 717/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 718/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 719/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 720/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 721/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 722/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 723/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 724/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 725/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 726/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 727/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 728/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 729/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 730/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 731/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 732/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 733/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 734/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 735/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 736/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 737/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 738/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 739/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 740/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 741/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 742/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 743/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 744/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 745/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 746/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 747/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 748/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 749/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 750/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 751/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 752/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 753/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 754/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 755/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 756/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 757/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 758/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 759/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 760/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 761/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 762/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 763/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 764/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 765/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 766/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 767/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 768/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 769/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 770/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 771/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 772/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 773/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 774/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 775/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 776/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 777/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 778/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 779/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 780/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 781/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 782/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 783/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 784/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 785/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 786/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 787/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 788/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 789/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 790/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 791/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 792/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 793/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 794/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 795/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 796/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 797/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 798/800, Reward: 0.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 799/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Episode: 800/800, Reward: 1.00: Epislon: 0.100 +2022-10-30 01:45:05 - r - INFO: - Finish training! diff --git a/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/models/Qleaning_model.pkl b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/models/Qleaning_model.pkl new file mode 100644 index 0000000..41a5a05 Binary files /dev/null and b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/models/Qleaning_model.pkl differ diff --git a/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/results/learning_curve.png b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/results/learning_curve.png new file mode 100644 index 0000000..ad789b7 Binary files /dev/null and b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/results/learning_curve.png differ diff --git a/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/results/res.csv b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/results/res.csv new file mode 100644 index 0000000..335c1d8 --- /dev/null +++ b/projects/codes/QLearning/Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504/results/res.csv @@ -0,0 +1,801 @@ +episodes,rewards,steps +0,0.0,20 +1,0.0,14 +2,0.0,13 +3,0.0,9 +4,0.0,10 +5,0.0,6 +6,0.0,11 +7,0.0,6 +8,0.0,3 +9,0.0,9 +10,0.0,11 +11,0.0,22 +12,0.0,5 +13,0.0,16 +14,0.0,4 +15,0.0,9 +16,0.0,18 +17,0.0,2 +18,0.0,4 +19,0.0,8 +20,0.0,7 +21,0.0,4 +22,0.0,22 +23,0.0,15 +24,0.0,5 +25,0.0,16 +26,0.0,7 +27,0.0,19 +28,0.0,22 +29,0.0,16 +30,0.0,11 +31,0.0,22 +32,0.0,28 +33,0.0,23 +34,0.0,4 +35,0.0,11 +36,0.0,8 +37,0.0,15 +38,0.0,5 +39,0.0,7 +40,0.0,9 +41,0.0,4 +42,0.0,3 +43,0.0,6 +44,0.0,41 +45,0.0,9 +46,0.0,23 +47,0.0,3 +48,1.0,38 +49,0.0,29 +50,0.0,17 +51,0.0,4 +52,0.0,2 +53,0.0,25 +54,0.0,6 +55,0.0,2 +56,0.0,30 +57,0.0,6 +58,0.0,7 +59,0.0,11 +60,0.0,9 +61,0.0,8 +62,0.0,23 +63,0.0,10 +64,0.0,3 +65,0.0,5 +66,0.0,7 +67,0.0,18 +68,0.0,8 +69,0.0,26 +70,0.0,6 +71,0.0,14 +72,0.0,4 +73,0.0,25 +74,0.0,21 +75,0.0,13 +76,0.0,4 +77,0.0,29 +78,0.0,21 +79,0.0,6 +80,0.0,6 +81,0.0,11 +82,0.0,21 +83,0.0,9 +84,0.0,9 +85,0.0,7 +86,0.0,48 +87,0.0,23 +88,0.0,160 +89,0.0,7 +90,0.0,10 +91,0.0,24 +92,0.0,4 +93,0.0,7 +94,0.0,17 +95,0.0,87 +96,0.0,28 +97,0.0,7 +98,0.0,5 +99,0.0,12 +100,0.0,14 +101,0.0,6 +102,0.0,13 +103,0.0,93 +104,0.0,4 +105,0.0,50 +106,0.0,8 +107,0.0,12 +108,0.0,43 +109,0.0,30 +110,0.0,15 +111,0.0,19 +112,0.0,182 +113,0.0,40 +114,0.0,88 +115,0.0,19 +116,0.0,30 +117,0.0,27 +118,0.0,5 +119,0.0,87 +120,0.0,9 +121,0.0,64 +122,0.0,27 +123,0.0,68 +124,0.0,81 +125,0.0,86 +126,0.0,200 +127,0.0,27 +128,0.0,41 +129,0.0,70 +130,0.0,27 +131,0.0,6 +132,0.0,18 +133,0.0,38 +134,0.0,26 +135,0.0,36 +136,0.0,3 +137,0.0,61 +138,0.0,105 +139,0.0,38 +140,0.0,18 +141,0.0,33 +142,0.0,29 +143,0.0,49 +144,0.0,88 +145,0.0,22 +146,0.0,65 +147,0.0,36 +148,0.0,30 +149,0.0,58 +150,0.0,43 +151,0.0,53 +152,0.0,43 +153,0.0,13 +154,0.0,8 +155,0.0,39 +156,0.0,29 +157,0.0,26 +158,0.0,60 +159,0.0,153 +160,0.0,116 +161,0.0,53 +162,0.0,54 +163,0.0,8 +164,0.0,58 +165,0.0,3 +166,0.0,47 +167,0.0,16 +168,0.0,21 +169,0.0,44 +170,0.0,29 +171,0.0,104 +172,0.0,158 +173,0.0,83 +174,0.0,26 +175,0.0,24 +176,0.0,10 +177,0.0,12 +178,0.0,40 +179,0.0,25 +180,0.0,18 +181,0.0,60 +182,0.0,200 +183,0.0,24 +184,0.0,56 +185,0.0,71 +186,0.0,19 +187,0.0,118 +188,0.0,26 +189,0.0,41 +190,0.0,41 +191,0.0,60 +192,0.0,31 +193,0.0,34 +194,0.0,35 +195,0.0,59 +196,0.0,51 +197,0.0,200 +198,0.0,200 +199,0.0,37 +200,0.0,68 +201,0.0,40 +202,0.0,17 +203,0.0,79 +204,0.0,126 +205,0.0,61 +206,0.0,25 +207,0.0,18 +208,0.0,27 +209,0.0,13 +210,0.0,187 +211,0.0,160 +212,0.0,32 +213,0.0,108 +214,0.0,164 +215,0.0,17 +216,0.0,82 +217,0.0,194 +218,0.0,7 +219,0.0,36 +220,0.0,156 +221,0.0,17 +222,0.0,183 +223,0.0,200 +224,0.0,43 +225,0.0,87 +226,0.0,42 +227,0.0,80 +228,0.0,54 +229,0.0,82 +230,0.0,97 +231,0.0,65 +232,0.0,83 +233,0.0,159 +234,0.0,178 +235,0.0,104 +236,0.0,21 +237,0.0,118 +238,0.0,80 +239,0.0,170 +240,0.0,94 +241,0.0,200 +242,0.0,37 +243,0.0,11 +244,0.0,31 +245,0.0,134 +246,0.0,32 +247,0.0,58 +248,0.0,38 +249,0.0,28 +250,0.0,159 +251,0.0,182 +252,0.0,51 +253,0.0,25 +254,0.0,73 +255,0.0,56 +256,0.0,55 +257,0.0,38 +258,0.0,200 +259,0.0,92 +260,0.0,200 +261,0.0,119 +262,0.0,100 +263,0.0,84 +264,0.0,24 +265,0.0,17 +266,0.0,159 +267,0.0,25 +268,0.0,73 +269,0.0,130 +270,0.0,111 +271,0.0,65 +272,1.0,58 +273,0.0,47 +274,0.0,48 +275,0.0,13 +276,0.0,100 +277,0.0,38 +278,0.0,111 +279,0.0,200 +280,0.0,26 +281,0.0,38 +282,0.0,83 +283,0.0,42 +284,0.0,199 +285,0.0,83 +286,0.0,28 +287,0.0,46 +288,0.0,200 +289,0.0,62 +290,0.0,123 +291,0.0,91 +292,0.0,53 +293,0.0,19 +294,0.0,26 +295,0.0,93 +296,0.0,38 +297,0.0,22 +298,0.0,43 +299,0.0,163 +300,0.0,25 +301,0.0,59 +302,0.0,71 +303,0.0,20 +304,0.0,115 +305,0.0,200 +306,0.0,48 +307,0.0,66 +308,0.0,58 +309,0.0,129 +310,0.0,122 +311,0.0,47 +312,0.0,60 +313,0.0,79 +314,1.0,137 +315,0.0,27 +316,1.0,93 +317,0.0,46 +318,1.0,83 +319,1.0,8 +320,1.0,6 +321,1.0,6 +322,0.0,4 +323,1.0,6 +324,0.0,2 +325,1.0,6 +326,1.0,6 +327,1.0,6 +328,1.0,6 +329,1.0,8 +330,0.0,5 +331,1.0,6 +332,1.0,7 +333,0.0,5 +334,1.0,6 +335,1.0,6 +336,1.0,8 +337,1.0,6 +338,1.0,6 +339,1.0,6 +340,1.0,7 +341,1.0,6 +342,1.0,6 +343,0.0,3 +344,1.0,7 +345,0.0,4 +346,1.0,6 +347,1.0,6 +348,1.0,7 +349,1.0,6 +350,1.0,6 +351,1.0,7 +352,1.0,7 +353,1.0,7 +354,1.0,6 +355,1.0,6 +356,1.0,6 +357,1.0,6 +358,1.0,6 +359,1.0,6 +360,1.0,6 +361,1.0,7 +362,0.0,4 +363,1.0,8 +364,1.0,8 +365,1.0,7 +366,1.0,6 +367,1.0,8 +368,1.0,6 +369,1.0,6 +370,1.0,7 +371,1.0,6 +372,1.0,6 +373,1.0,8 +374,1.0,7 +375,1.0,6 +376,1.0,6 +377,0.0,3 +378,1.0,11 +379,1.0,6 +380,1.0,8 +381,0.0,2 +382,1.0,6 +383,1.0,6 +384,1.0,6 +385,1.0,6 +386,1.0,8 +387,1.0,6 +388,1.0,7 +389,1.0,6 +390,1.0,7 +391,1.0,6 +392,1.0,8 +393,0.0,2 +394,1.0,6 +395,1.0,7 +396,1.0,6 +397,1.0,6 +398,1.0,10 +399,1.0,7 +400,1.0,6 +401,1.0,6 +402,1.0,6 +403,1.0,6 +404,1.0,6 +405,1.0,7 +406,0.0,4 +407,1.0,7 +408,1.0,6 +409,1.0,8 +410,0.0,3 +411,1.0,6 +412,1.0,6 +413,1.0,6 +414,1.0,6 +415,0.0,2 +416,1.0,6 +417,1.0,6 +418,1.0,6 +419,1.0,6 +420,1.0,6 +421,1.0,7 +422,1.0,6 +423,1.0,6 +424,1.0,7 +425,1.0,6 +426,1.0,6 +427,1.0,6 +428,1.0,6 +429,1.0,6 +430,1.0,6 +431,1.0,6 +432,1.0,8 +433,1.0,6 +434,1.0,8 +435,1.0,7 +436,1.0,6 +437,0.0,3 +438,1.0,6 +439,1.0,7 +440,1.0,6 +441,1.0,6 +442,1.0,6 +443,1.0,10 +444,1.0,6 +445,1.0,6 +446,1.0,6 +447,1.0,6 +448,1.0,10 +449,1.0,6 +450,1.0,8 +451,1.0,8 +452,1.0,7 +453,1.0,6 +454,0.0,5 +455,0.0,2 +456,1.0,8 +457,1.0,6 +458,1.0,10 +459,1.0,6 +460,1.0,8 +461,1.0,10 +462,1.0,6 +463,1.0,6 +464,1.0,6 +465,1.0,10 +466,1.0,6 +467,0.0,4 +468,1.0,6 +469,1.0,6 +470,1.0,6 +471,1.0,15 +472,1.0,6 +473,1.0,6 +474,1.0,6 +475,1.0,6 +476,1.0,6 +477,1.0,6 +478,1.0,8 +479,1.0,6 +480,1.0,7 +481,1.0,6 +482,1.0,6 +483,1.0,8 +484,1.0,6 +485,1.0,6 +486,1.0,8 +487,1.0,8 +488,1.0,6 +489,1.0,6 +490,1.0,6 +491,1.0,10 +492,1.0,6 +493,1.0,6 +494,1.0,6 +495,1.0,6 +496,1.0,6 +497,1.0,6 +498,1.0,6 +499,1.0,8 +500,1.0,8 +501,1.0,6 +502,1.0,6 +503,0.0,2 +504,1.0,6 +505,1.0,6 +506,1.0,6 +507,1.0,8 +508,1.0,6 +509,1.0,6 +510,1.0,6 +511,1.0,6 +512,1.0,6 +513,1.0,6 +514,1.0,6 +515,1.0,6 +516,1.0,6 +517,1.0,7 +518,0.0,3 +519,1.0,7 +520,1.0,6 +521,1.0,6 +522,1.0,6 +523,0.0,2 +524,1.0,6 +525,1.0,8 +526,1.0,6 +527,1.0,6 +528,1.0,6 +529,1.0,6 +530,1.0,9 +531,1.0,6 +532,1.0,6 +533,1.0,6 +534,1.0,6 +535,1.0,6 +536,1.0,6 +537,1.0,9 +538,1.0,7 +539,0.0,4 +540,1.0,6 +541,1.0,8 +542,1.0,11 +543,1.0,6 +544,1.0,6 +545,1.0,6 +546,1.0,6 +547,1.0,6 +548,1.0,8 +549,1.0,6 +550,1.0,6 +551,1.0,8 +552,1.0,7 +553,1.0,6 +554,1.0,8 +555,1.0,6 +556,0.0,5 +557,1.0,9 +558,1.0,8 +559,1.0,8 +560,1.0,6 +561,1.0,8 +562,1.0,8 +563,1.0,6 +564,0.0,5 +565,0.0,3 +566,0.0,2 +567,1.0,8 +568,1.0,6 +569,1.0,6 +570,1.0,6 +571,1.0,6 +572,1.0,6 +573,1.0,6 +574,1.0,6 +575,1.0,6 +576,1.0,6 +577,1.0,6 +578,1.0,6 +579,1.0,6 +580,1.0,6 +581,1.0,6 +582,0.0,2 +583,1.0,6 +584,0.0,4 +585,1.0,6 +586,1.0,6 +587,1.0,6 +588,1.0,6 +589,1.0,6 +590,1.0,8 +591,0.0,5 +592,1.0,6 +593,1.0,6 +594,1.0,6 +595,1.0,6 +596,1.0,6 +597,1.0,6 +598,0.0,3 +599,1.0,6 +600,1.0,6 +601,1.0,6 +602,0.0,2 +603,1.0,6 +604,0.0,4 +605,1.0,6 +606,1.0,6 +607,1.0,6 +608,1.0,6 +609,1.0,8 +610,1.0,6 +611,1.0,7 +612,1.0,6 +613,1.0,7 +614,1.0,6 +615,0.0,2 +616,1.0,6 +617,1.0,6 +618,0.0,5 +619,0.0,3 +620,0.0,3 +621,1.0,6 +622,0.0,5 +623,1.0,8 +624,1.0,8 +625,1.0,6 +626,1.0,6 +627,1.0,7 +628,1.0,6 +629,1.0,6 +630,1.0,6 +631,1.0,6 +632,1.0,6 +633,1.0,8 +634,0.0,2 +635,1.0,6 +636,1.0,6 +637,1.0,6 +638,1.0,6 +639,1.0,6 +640,1.0,6 +641,1.0,6 +642,1.0,8 +643,1.0,6 +644,1.0,8 +645,1.0,6 +646,1.0,6 +647,1.0,8 +648,1.0,8 +649,0.0,5 +650,0.0,4 +651,0.0,4 +652,1.0,6 +653,1.0,6 +654,1.0,6 +655,1.0,6 +656,1.0,8 +657,1.0,6 +658,0.0,4 +659,1.0,6 +660,1.0,8 +661,1.0,6 +662,1.0,6 +663,1.0,6 +664,1.0,6 +665,1.0,6 +666,1.0,6 +667,1.0,6 +668,1.0,8 +669,1.0,8 +670,1.0,6 +671,1.0,8 +672,1.0,9 +673,1.0,6 +674,1.0,6 +675,1.0,6 +676,1.0,6 +677,1.0,10 +678,1.0,6 +679,1.0,6 +680,1.0,6 +681,1.0,11 +682,1.0,10 +683,1.0,8 +684,1.0,6 +685,1.0,6 +686,1.0,6 +687,0.0,5 +688,1.0,6 +689,0.0,2 +690,1.0,9 +691,1.0,6 +692,1.0,8 +693,1.0,7 +694,1.0,6 +695,1.0,6 +696,1.0,7 +697,0.0,3 +698,1.0,7 +699,0.0,2 +700,1.0,6 +701,1.0,6 +702,1.0,8 +703,1.0,8 +704,1.0,6 +705,1.0,6 +706,0.0,2 +707,1.0,8 +708,1.0,6 +709,1.0,8 +710,1.0,6 +711,1.0,6 +712,1.0,9 +713,1.0,6 +714,1.0,8 +715,1.0,11 +716,1.0,6 +717,1.0,6 +718,1.0,6 +719,1.0,6 +720,1.0,8 +721,1.0,6 +722,1.0,6 +723,1.0,6 +724,0.0,5 +725,1.0,6 +726,1.0,6 +727,1.0,6 +728,1.0,6 +729,1.0,6 +730,1.0,7 +731,1.0,6 +732,1.0,6 +733,1.0,6 +734,1.0,6 +735,1.0,10 +736,1.0,6 +737,1.0,6 +738,1.0,6 +739,1.0,6 +740,1.0,6 +741,1.0,7 +742,1.0,6 +743,1.0,8 +744,1.0,7 +745,1.0,6 +746,1.0,6 +747,1.0,14 +748,1.0,6 +749,1.0,6 +750,1.0,12 +751,1.0,6 +752,1.0,6 +753,1.0,6 +754,1.0,6 +755,1.0,6 +756,1.0,6 +757,0.0,3 +758,1.0,6 +759,1.0,6 +760,1.0,6 +761,1.0,7 +762,1.0,6 +763,1.0,6 +764,1.0,6 +765,1.0,8 +766,0.0,2 +767,1.0,6 +768,1.0,6 +769,1.0,6 +770,1.0,6 +771,1.0,6 +772,1.0,6 +773,1.0,6 +774,1.0,6 +775,1.0,6 +776,0.0,4 +777,1.0,8 +778,1.0,6 +779,0.0,2 +780,1.0,10 +781,1.0,8 +782,1.0,6 +783,1.0,6 +784,1.0,6 +785,0.0,3 +786,1.0,6 +787,1.0,6 +788,0.0,6 +789,1.0,8 +790,1.0,6 +791,1.0,9 +792,1.0,6 +793,1.0,6 +794,1.0,8 +795,1.0,8 +796,1.0,6 +797,0.0,5 +798,1.0,6 +799,1.0,6 diff --git a/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/config.yaml b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/config.yaml new file mode 100644 index 0000000..d5b9c4c --- /dev/null +++ b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: Racetrack-v0 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + mode: train + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.9 + lr: 0.1 diff --git a/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/logs/log.txt b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/logs/log.txt new file mode 100644 index 0000000..e737550 --- /dev/null +++ b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/logs/log.txt @@ -0,0 +1,404 @@ +2022-10-30 01:48:33 - r - INFO: - n_states: 4, n_actions: 9 +2022-10-30 01:48:33 - r - INFO: - Start training! +2022-10-30 01:48:33 - r - INFO: - Env: Racetrack-v0, Algorithm: QLearning, Device: cpu +2022-10-30 01:48:33 - r - INFO: - Episode: 1/400, Reward: -850.00: Epislon: 0.493 +2022-10-30 01:48:33 - r - INFO: - Episode: 2/400, Reward: -780.00: Epislon: 0.258 +2022-10-30 01:48:33 - r - INFO: - Episode: 3/400, Reward: -730.00: Epislon: 0.137 +2022-10-30 01:48:33 - r - INFO: - Episode: 4/400, Reward: -650.00: Epislon: 0.075 +2022-10-30 01:48:33 - r - INFO: - Episode: 5/400, Reward: -540.00: Epislon: 0.044 +2022-10-30 01:48:33 - r - INFO: - Episode: 6/400, Reward: -640.00: Epislon: 0.027 +2022-10-30 01:48:34 - r - INFO: - Episode: 7/400, Reward: -570.00: Epislon: 0.019 +2022-10-30 01:48:34 - r - INFO: - Episode: 8/400, Reward: -570.00: Epislon: 0.015 +2022-10-30 01:48:34 - r - INFO: - Episode: 9/400, Reward: -550.00: Epislon: 0.012 +2022-10-30 01:48:34 - r - INFO: - Episode: 10/400, Reward: -550.00: Epislon: 0.011 +2022-10-30 01:48:34 - r - INFO: - Episode: 11/400, Reward: -580.00: Epislon: 0.011 +2022-10-30 01:48:34 - r - INFO: - Episode: 12/400, Reward: -530.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 13/400, Reward: -580.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 14/400, Reward: -570.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 15/400, Reward: -550.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 16/400, Reward: -560.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 17/400, Reward: -550.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 18/400, Reward: -580.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 19/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 20/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 21/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 22/400, Reward: -540.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 23/400, Reward: -550.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 24/400, Reward: -560.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 25/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 26/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 27/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 28/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 29/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 30/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 31/400, Reward: -540.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 32/400, Reward: -540.00: Epislon: 0.010 +2022-10-30 01:48:34 - r - INFO: - Episode: 33/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 34/400, Reward: -540.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 35/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 36/400, Reward: -530.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 37/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 38/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 39/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 40/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 41/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 42/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 43/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 44/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 45/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 46/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 47/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 48/400, Reward: -530.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 49/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 50/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 51/400, Reward: -500.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 52/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 53/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 54/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 55/400, Reward: -500.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 56/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 57/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 58/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 59/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 60/400, Reward: -530.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 61/400, Reward: -440.00: Epislon: 0.010 +2022-10-30 01:48:35 - r - INFO: - Episode: 62/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 63/400, Reward: -520.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 64/400, Reward: -510.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 65/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 66/400, Reward: -344.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 67/400, Reward: -500.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 68/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 69/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 70/400, Reward: -440.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 71/400, Reward: -77.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 72/400, Reward: -198.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 73/400, Reward: -440.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 74/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 75/400, Reward: -354.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 76/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 77/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 78/400, Reward: -38.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 79/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 80/400, Reward: -480.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 81/400, Reward: -490.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 82/400, Reward: -140.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 83/400, Reward: -102.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 84/400, Reward: -265.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 85/400, Reward: -145.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 86/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 87/400, Reward: -500.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 88/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 89/400, Reward: -325.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 90/400, Reward: -470.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 91/400, Reward: -376.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 92/400, Reward: -98.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 93/400, Reward: -130.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 94/400, Reward: -450.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 95/400, Reward: -146.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 96/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 97/400, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 98/400, Reward: -102.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 99/400, Reward: -163.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 100/400, Reward: -209.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 101/400, Reward: -460.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 102/400, Reward: -286.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 103/400, Reward: -189.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 104/400, Reward: -50.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 105/400, Reward: -398.00: Epislon: 0.010 +2022-10-30 01:48:36 - r - INFO: - Episode: 106/400, Reward: -72.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 107/400, Reward: -450.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 108/400, Reward: -125.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 109/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 110/400, Reward: -161.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 111/400, Reward: -408.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 112/400, Reward: -440.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 113/400, Reward: -188.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 114/400, Reward: -114.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 115/400, Reward: -415.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 116/400, Reward: -159.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 117/400, Reward: -234.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 118/400, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 119/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 120/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 121/400, Reward: -63.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 122/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 123/400, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 124/400, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 125/400, Reward: -49.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 126/400, Reward: -87.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 127/400, Reward: -2.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 128/400, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 129/400, Reward: -238.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 130/400, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 131/400, Reward: -235.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 132/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 133/400, Reward: -135.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 134/400, Reward: -20.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 135/400, Reward: -46.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 136/400, Reward: -66.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 137/400, Reward: -45.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 138/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 139/400, Reward: 1.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 140/400, Reward: -106.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 141/400, Reward: -112.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 142/400, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 143/400, Reward: 1.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 144/400, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 145/400, Reward: -147.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 146/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 147/400, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 148/400, Reward: -167.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 149/400, Reward: 1.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 150/400, Reward: -72.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 151/400, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 152/400, Reward: -76.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 153/400, Reward: -63.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 154/400, Reward: -34.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 155/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 156/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 157/400, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 158/400, Reward: -80.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 159/400, Reward: -168.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 160/400, Reward: -164.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 161/400, Reward: 1.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 162/400, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 163/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 164/400, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 165/400, Reward: -80.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 166/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 167/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 168/400, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 169/400, Reward: -56.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 170/400, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 171/400, Reward: -76.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 172/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 173/400, Reward: -145.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 174/400, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 175/400, Reward: -63.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 176/400, Reward: -106.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 177/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 178/400, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 179/400, Reward: -60.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 180/400, Reward: -49.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 181/400, Reward: -52.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 182/400, Reward: -84.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 183/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 184/400, Reward: -55.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 185/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 186/400, Reward: 1.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 187/400, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 188/400, Reward: -47.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 189/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 190/400, Reward: -53.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 191/400, Reward: -50.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 192/400, Reward: -104.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 193/400, Reward: -253.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 194/400, Reward: -48.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 195/400, Reward: -190.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 196/400, Reward: -43.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 197/400, Reward: -35.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 198/400, Reward: 0.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 199/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 200/400, Reward: -11.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 201/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 202/400, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 203/400, Reward: -99.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 204/400, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 205/400, Reward: -170.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 206/400, Reward: -109.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 207/400, Reward: -48.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 208/400, Reward: -275.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 209/400, Reward: -49.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 210/400, Reward: -147.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 211/400, Reward: -51.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 212/400, Reward: -67.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 213/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 214/400, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 215/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 216/400, Reward: -69.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 217/400, Reward: -218.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 218/400, Reward: -63.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 219/400, Reward: -11.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 220/400, Reward: -34.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 221/400, Reward: -32.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 222/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 223/400, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 224/400, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 225/400, Reward: -148.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 226/400, Reward: -19.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 227/400, Reward: 1.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 228/400, Reward: -49.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 229/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 230/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 231/400, Reward: -223.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 232/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 233/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 234/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 235/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 236/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 237/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 238/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 239/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 240/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 241/400, Reward: -44.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 242/400, Reward: -10.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 243/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 244/400, Reward: -108.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 245/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 246/400, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 247/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 248/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 249/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 250/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 251/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 252/400, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 253/400, Reward: -112.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 254/400, Reward: -39.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 255/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 256/400, Reward: -48.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 257/400, Reward: -149.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 258/400, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 259/400, Reward: -33.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 260/400, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 261/400, Reward: -29.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 262/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 263/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 264/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 265/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 266/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 267/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 268/400, Reward: -52.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 269/400, Reward: -53.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 270/400, Reward: -62.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 271/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 272/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 273/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 274/400, Reward: -10.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 275/400, Reward: -8.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 276/400, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 277/400, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 278/400, Reward: -45.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 279/400, Reward: -48.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 280/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 281/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 282/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 283/400, Reward: -26.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 284/400, Reward: -116.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 285/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 286/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 287/400, Reward: -42.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 288/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 289/400, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 290/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 291/400, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 292/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 293/400, Reward: -43.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 294/400, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 295/400, Reward: -33.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 296/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 297/400, Reward: -28.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 298/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 299/400, Reward: 0.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 300/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 301/400, Reward: -6.00: Epislon: 0.010 +2022-10-30 01:48:37 - r - INFO: - Episode: 302/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 303/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 304/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 305/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 306/400, Reward: -77.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 307/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 308/400, Reward: -32.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 309/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 310/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 311/400, Reward: -36.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 312/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 313/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 314/400, Reward: -34.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 315/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 316/400, Reward: -21.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 317/400, Reward: -48.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 318/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 319/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 320/400, Reward: -25.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 321/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 322/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 323/400, Reward: -135.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 324/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 325/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 326/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 327/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 328/400, Reward: -11.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 329/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 330/400, Reward: -11.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 331/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 332/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 333/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 334/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 335/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 336/400, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 337/400, Reward: -16.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 338/400, Reward: -17.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 339/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 340/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 341/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 342/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 343/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 344/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 345/400, Reward: -90.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 346/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 347/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 348/400, Reward: -53.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 349/400, Reward: -87.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 350/400, Reward: -22.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 351/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 352/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 353/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 354/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 355/400, Reward: -113.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 356/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 357/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 358/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 359/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 360/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 361/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 362/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 363/400, Reward: -63.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 364/400, Reward: -14.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 365/400, Reward: -15.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 366/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 367/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 368/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 369/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 370/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 371/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 372/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 373/400, Reward: -12.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 374/400, Reward: -30.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 375/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 376/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 377/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 378/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 379/400, Reward: -31.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 380/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 381/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 382/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 383/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 384/400, Reward: -84.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 385/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 386/400, Reward: -27.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 387/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 388/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 389/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 390/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 391/400, Reward: 2.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 392/400, Reward: 3.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 393/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 394/400, Reward: 4.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 395/400, Reward: -18.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 396/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 397/400, Reward: -41.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 398/400, Reward: 5.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 399/400, Reward: -41.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Episode: 400/400, Reward: -13.00: Epislon: 0.010 +2022-10-30 01:48:38 - r - INFO: - Finish training! diff --git a/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/models/Qleaning_model.pkl b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/models/Qleaning_model.pkl new file mode 100644 index 0000000..1f458e1 Binary files /dev/null and b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/models/Qleaning_model.pkl differ diff --git a/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/results/learning_curve.png b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/results/learning_curve.png new file mode 100644 index 0000000..8c1c331 Binary files /dev/null and b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/results/learning_curve.png differ diff --git a/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/results/res.csv b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/results/res.csv new file mode 100644 index 0000000..79373d8 --- /dev/null +++ b/projects/codes/QLearning/Train_Racetrack-v0_QLearning_20221030-014833/results/res.csv @@ -0,0 +1,401 @@ +episodes,rewards,steps +0,-850,200 +1,-780,200 +2,-730,200 +3,-650,200 +4,-540,200 +5,-640,200 +6,-570,200 +7,-570,200 +8,-550,200 +9,-550,200 +10,-580,200 +11,-530,200 +12,-580,200 +13,-570,200 +14,-550,200 +15,-560,200 +16,-550,200 +17,-580,200 +18,-520,200 +19,-490,200 +20,-480,200 +21,-540,200 +22,-550,200 +23,-560,200 +24,-510,200 +25,-520,200 +26,-480,200 +27,-520,200 +28,-480,200 +29,-470,200 +30,-540,200 +31,-540,200 +32,-470,200 +33,-540,200 +34,-490,200 +35,-530,200 +36,-520,200 +37,-510,200 +38,-520,200 +39,-510,200 +40,-480,200 +41,-510,200 +42,-470,200 +43,-490,200 +44,-490,200 +45,-490,200 +46,-520,200 +47,-530,200 +48,-510,200 +49,-460,200 +50,-500,200 +51,-470,200 +52,-520,200 +53,-490,200 +54,-500,200 +55,-460,200 +56,-490,200 +57,-510,200 +58,-460,200 +59,-530,200 +60,-440,200 +61,-510,200 +62,-520,200 +63,-510,200 +64,-460,200 +65,-344,154 +66,-500,200 +67,-490,200 +68,-490,200 +69,-440,200 +70,-77,47 +71,-198,88 +72,-440,200 +73,-480,200 +74,-354,154 +75,-470,200 +76,-480,200 +77,-38,28 +78,-460,200 +79,-480,200 +80,-490,200 +81,-140,70 +82,-102,52 +83,-265,125 +84,-145,75 +85,-460,200 +86,-500,200 +87,-470,200 +88,-325,155 +89,-470,200 +90,-376,156 +91,-98,58 +92,-130,70 +93,-450,200 +94,-146,66 +95,2,8 +96,-18,18 +97,-102,52 +98,-163,73 +99,-209,89 +100,-460,200 +101,-286,126 +102,-189,89 +103,-50,30 +104,-398,168 +105,-72,32 +106,-450,200 +107,-125,65 +108,4,6 +109,-161,71 +110,-408,178 +111,-440,200 +112,-188,78 +113,-114,64 +114,-415,185 +115,-159,69 +116,-234,104 +117,-31,21 +118,3,7 +119,4,6 +120,-63,33 +121,5,5 +122,-47,27 +123,-16,16 +124,-49,29 +125,-87,47 +126,-2,12 +127,-26,16 +128,-238,108 +129,-18,18 +130,-235,105 +131,-13,13 +132,-135,65 +133,-20,20 +134,-46,26 +135,-66,36 +136,-45,25 +137,-14,14 +138,1,9 +139,-106,56 +140,-112,62 +141,-47,27 +142,1,9 +143,-30,20 +144,-147,77 +145,5,5 +146,-30,20 +147,-167,77 +148,1,9 +149,-72,32 +150,-44,24 +151,-76,46 +152,-63,33 +153,-34,24 +154,5,5 +155,5,5 +156,-26,16 +157,-80,40 +158,-168,78 +159,-164,74 +160,1,9 +161,-19,19 +162,-12,12 +163,-44,24 +164,-80,40 +165,5,5 +166,4,6 +167,-29,19 +168,-56,26 +169,-47,27 +170,-76,46 +171,-13,13 +172,-145,65 +173,-28,18 +174,-63,33 +175,-106,56 +176,3,7 +177,-28,28 +178,-60,30 +179,-49,29 +180,-52,32 +181,-84,44 +182,5,5 +183,-55,35 +184,-14,14 +185,1,9 +186,-39,19 +187,-47,27 +188,-13,13 +189,-53,33 +190,-50,30 +191,-104,54 +192,-253,113 +193,-48,28 +194,-190,90 +195,-43,23 +196,-35,25 +197,0,10 +198,5,5 +199,-11,11 +200,5,5 +201,-16,16 +202,-99,49 +203,-22,22 +204,-170,80 +205,-109,59 +206,-48,28 +207,-275,115 +208,-49,29 +209,-147,77 +210,-51,31 +211,-67,37 +212,4,6 +213,-17,17 +214,3,7 +215,-69,39 +216,-218,88 +217,-63,33 +218,-11,11 +219,-34,24 +220,-32,22 +221,-15,15 +222,-26,16 +223,-19,19 +224,-148,78 +225,-19,19 +226,1,9 +227,-49,29 +228,5,5 +229,3,7 +230,-223,103 +231,-14,14 +232,4,6 +233,5,5 +234,2,8 +235,5,5 +236,4,6 +237,3,7 +238,3,7 +239,4,6 +240,-44,24 +241,-10,10 +242,2,8 +243,-108,58 +244,4,6 +245,-27,17 +246,3,7 +247,5,5 +248,5,5 +249,3,7 +250,-15,15 +251,-28,28 +252,-112,52 +253,-39,29 +254,4,6 +255,-48,28 +256,-149,69 +257,-27,17 +258,-33,23 +259,-30,20 +260,-29,19 +261,4,6 +262,4,6 +263,3,7 +264,3,7 +265,4,6 +266,5,5 +267,-52,42 +268,-53,33 +269,-62,42 +270,5,5 +271,4,6 +272,4,6 +273,-10,10 +274,-8,8 +275,-30,20 +276,-25,15 +277,-45,35 +278,-48,28 +279,-15,15 +280,4,6 +281,-14,14 +282,-26,16 +283,-116,56 +284,5,5 +285,-14,14 +286,-42,22 +287,3,7 +288,-31,21 +289,4,6 +290,-25,25 +291,5,5 +292,-43,23 +293,-21,21 +294,-33,23 +295,-12,12 +296,-28,18 +297,3,7 +298,0,10 +299,4,6 +300,-6,16 +301,4,6 +302,2,8 +303,-12,12 +304,4,6 +305,-77,47 +306,5,5 +307,-32,22 +308,5,5 +309,-12,12 +310,-36,26 +311,4,6 +312,4,6 +313,-34,24 +314,4,6 +315,-21,21 +316,-48,28 +317,4,6 +318,5,5 +319,-25,15 +320,4,6 +321,-14,14 +322,-135,65 +323,3,7 +324,5,5 +325,4,6 +326,3,7 +327,-11,11 +328,3,7 +329,-11,11 +330,3,7 +331,4,6 +332,3,7 +333,5,5 +334,-12,12 +335,-22,22 +336,-16,16 +337,-17,17 +338,-14,14 +339,3,7 +340,5,5 +341,-15,15 +342,-13,13 +343,4,6 +344,-90,40 +345,3,7 +346,3,7 +347,-53,33 +348,-87,47 +349,-22,22 +350,5,5 +351,-12,12 +352,3,7 +353,4,6 +354,-113,53 +355,3,7 +356,3,7 +357,-13,13 +358,-15,15 +359,-14,14 +360,2,8 +361,-15,15 +362,-63,33 +363,-14,14 +364,-15,15 +365,3,7 +366,3,7 +367,4,6 +368,4,6 +369,4,6 +370,3,7 +371,-13,13 +372,-12,12 +373,-30,20 +374,3,7 +375,2,8 +376,-13,13 +377,5,5 +378,-31,21 +379,3,7 +380,2,8 +381,4,6 +382,4,6 +383,-84,44 +384,3,7 +385,-27,17 +386,4,6 +387,4,6 +388,4,6 +389,2,8 +390,2,8 +391,3,7 +392,4,6 +393,4,6 +394,-18,18 +395,-13,13 +396,-41,31 +397,5,5 +398,-41,31 +399,-13,13 diff --git a/projects/codes/QLearning/config/CliffWalking-v0_QLearning_Test.yaml b/projects/codes/QLearning/config/CliffWalking-v0_QLearning_Test.yaml new file mode 100644 index 0000000..d1a9903 --- /dev/null +++ b/projects/codes/QLearning/config/CliffWalking-v0_QLearning_Test.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: CliffWalking-v0 + mode: test + load_checkpoint: true + load_path: Train_CliffWalking-v0_QLearning_20221030-013856 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/QLearning/config/CliffWalking-v0_QLearning_Train.yaml b/projects/codes/QLearning/config/CliffWalking-v0_QLearning_Train.yaml new file mode 100644 index 0000000..332f3ab --- /dev/null +++ b/projects/codes/QLearning/config/CliffWalking-v0_QLearning_Train.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: CliffWalking-v0 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/QLearning/config/FrozenLakeNoSlippery-v1_QLearning_Test.yaml b/projects/codes/QLearning/config/FrozenLakeNoSlippery-v1_QLearning_Test.yaml new file mode 100644 index 0000000..089e391 --- /dev/null +++ b/projects/codes/QLearning/config/FrozenLakeNoSlippery-v1_QLearning_Test.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: FrozenLakeNoSlippery-v1 + mode: test + load_checkpoint: true + load_path: Train_FrozenLakeNoSlippery-v1_QLearning_20221030-014504 + max_steps: 200 + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 2000 + epsilon_end: 0.1 + epsilon_start: 0.7 + gamma: 0.95 + lr: 0.9 diff --git a/projects/codes/QLearning/config/FrozenLakeNoSlippery-v1_QLearning_Train.yaml b/projects/codes/QLearning/config/FrozenLakeNoSlippery-v1_QLearning_Train.yaml new file mode 100644 index 0000000..760750a --- /dev/null +++ b/projects/codes/QLearning/config/FrozenLakeNoSlippery-v1_QLearning_Train.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: FrozenLakeNoSlippery-v1 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 2000 + epsilon_end: 0.1 + epsilon_start: 0.7 + gamma: 0.95 + lr: 0.9 diff --git a/projects/codes/QLearning/config/Racetrack-v0_QLearning_Test.yaml b/projects/codes/QLearning/config/Racetrack-v0_QLearning_Test.yaml new file mode 100644 index 0000000..3aa9985 --- /dev/null +++ b/projects/codes/QLearning/config/Racetrack-v0_QLearning_Test.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: Racetrack-v0 + mode: test + load_checkpoint: true + load_path: Train_Racetrack-v0_QLearning_20221030-014833 + max_steps: 200 + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.9 + lr: 0.1 diff --git a/projects/codes/QLearning/config/Racetrack-v0_QLearning_Train.yaml b/projects/codes/QLearning/config/Racetrack-v0_QLearning_Train.yaml new file mode 100644 index 0000000..63e51c3 --- /dev/null +++ b/projects/codes/QLearning/config/Racetrack-v0_QLearning_Train.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: QLearning + device: cpu + env_name: Racetrack-v0 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.9 + lr: 0.1 diff --git a/projects/codes/QLearning/config/config.py b/projects/codes/QLearning/config/config.py new file mode 100644 index 0000000..e0ed62a --- /dev/null +++ b/projects/codes/QLearning/config/config.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 01:23:07 +LastEditor: JiangJi +LastEditTime: 2022-10-30 01:39:54 +Discription: default parameters of QLearning +''' +from common.config import GeneralConfig,AlgoConfig + +class GeneralConfigQLearning(GeneralConfig): + def __init__(self) -> None: + self.env_name = "CliffWalking-v0" # name of environment + self.algo_name = "QLearning" # name of algorithm + self.mode = "train" # train or test + self.seed = 1 # random seed + self.device = "cpu" # device to use + self.train_eps = 400 # number of episodes for training + self.test_eps = 20 # number of episodes for testing + self.max_steps = 200 # max steps for each episode + self.load_checkpoint = False + self.load_path = "tasks" # path to load model + self.show_fig = False # show figure or not + self.save_fig = True # save figure or not + +class AlgoConfigQLearning(AlgoConfig): + def __init__(self) -> None: + # set epsilon_start=epsilon_end can obtain fixed epsilon=epsilon_end + self.epsilon_start = 0.95 # epsilon start value + self.epsilon_end = 0.01 # epsilon end value + self.epsilon_decay = 300 # epsilon decay rate + self.gamma = 0.90 # discount factor + self.lr = 0.1 # learning rate \ No newline at end of file diff --git a/projects/codes/QLearning/main.py b/projects/codes/QLearning/main.py deleted file mode 100644 index 7adbfbe..0000000 --- a/projects/codes/QLearning/main.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -''' -Author: John -Email: johnjim0816@gmail.com -Date: 2020-09-11 23:03:00 -LastEditor: John -LastEditTime: 2022-08-26 22:46:21 -Discription: -Environment: -''' -import sys,os -os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." -curr_path = os.path.dirname(os.path.abspath(__file__)) # current path -parent_path = os.path.dirname(curr_path) # parent path -sys.path.append(parent_path) # add path to system path - -import gym -import datetime -import argparse -from envs.gridworld_env import FrozenLakeWapper -from envs.wrappers import CliffWalkingWapper -from envs.register import register_env -from qlearning import QLearning -from common.utils import all_seed -from common.launcher import Launcher - -class Main(Launcher): - def get_args(self): - curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # obtain current time - parser = argparse.ArgumentParser(description="hyperparameters") - parser.add_argument('--algo_name',default='Q-learning',type=str,help="name of algorithm") - parser.add_argument('--env_name',default='CliffWalking-v0',type=str,help="name of environment") - parser.add_argument('--train_eps',default=400,type=int,help="episodes of training") - parser.add_argument('--test_eps',default=20,type=int,help="episodes of testing") - parser.add_argument('--gamma',default=0.90,type=float,help="discounted factor") - parser.add_argument('--epsilon_start',default=0.95,type=float,help="initial value of epsilon") - parser.add_argument('--epsilon_end',default=0.01,type=float,help="final value of epsilon") - parser.add_argument('--epsilon_decay',default=300,type=int,help="decay rate of epsilon") - parser.add_argument('--lr',default=0.1,type=float,help="learning rate") - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--seed',default=10,type=int,help="seed") - parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") - parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") - args = parser.parse_args() - default_args = {'result_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/results/", - 'model_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/models/", - } - args = {**vars(args),**default_args} # type(dict) - return args - def env_agent_config(self,cfg): - ''' create env and agent - ''' - register_env(cfg['env_name']) - env = gym.make(cfg['env_name']) - if cfg['env_name'] == 'CliffWalking-v0': - env = CliffWalkingWapper(env) - if cfg['seed'] !=0: # set random seed - all_seed(env,seed=cfg["seed"]) - try: # state dimension - n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) - except AttributeError: - n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) - n_actions = env.action_space.n # action dimension - print(f"n_states: {n_states}, n_actions: {n_actions}") - cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters - agent = QLearning(cfg) - return env,agent - def train(self,cfg,env,agent): - print("Start training!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # record rewards for all episodes - steps = [] # record steps for all episodes - for i_ep in range(cfg['train_eps']): - ep_reward = 0 # reward per episode - ep_step = 0 # step per episode - state = env.reset() # reset and obtain initial state - while True: - action = agent.sample_action(state) # sample action - next_state, reward, done, _ = env.step(action) # update env and return transitions - agent.update(state, action, reward, next_state, done) # update agent - state = next_state # update state - ep_reward += reward - ep_step += 1 - if done: - break - rewards.append(ep_reward) - steps.append(ep_step) - if (i_ep+1)%10==0: - print(f'Episode: {i_ep+1}/{cfg["train_eps"]}, Reward: {ep_reward:.2f}, Steps:{ep_step}, Epislon: {agent.epsilon:.3f}') - print("Finish training!") - return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} - def test(self,cfg,env,agent): - print("Start testing!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # record rewards for all episodes - steps = [] # record steps for all episodes - for i_ep in range(cfg['test_eps']): - ep_reward = 0 # reward per episode - ep_step = 0 - state = env.reset() # reset and obtain initial state - while True: - action = agent.predict_action(state) # predict action - next_state, reward, done, _ = env.step(action) - state = next_state - ep_reward += reward - ep_step += 1 - if done: - break - rewards.append(ep_reward) - steps.append(ep_step) - print(f"Episode: {i_ep+1}/{cfg['test_eps']}, Steps:{ep_step}, Reward: {ep_reward:.2f}") - print("Finish testing!") - return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} - -if __name__ == "__main__": - main = Main() - main.run() - - - - diff --git a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/models/Qleaning_model.pkl b/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/models/Qleaning_model.pkl deleted file mode 100644 index 2369fe1..0000000 Binary files a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/models/Qleaning_model.pkl and /dev/null differ diff --git a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/params.json b/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/params.json deleted file mode 100644 index 09764c9..0000000 --- a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/params.json +++ /dev/null @@ -1 +0,0 @@ -{"algo_name": "Q-learning", "env_name": "CliffWalking-v0", "train_eps": 400, "test_eps": 20, "gamma": 0.9, "epsilon_start": 0.95, "epsilon_end": 0.01, "epsilon_decay": 300, "lr": 0.1, "device": "cpu", "seed": 10, "show_fig": false, "save_fig": true, "result_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\QLearning/outputs/CliffWalking-v0/20220826-224730/results/", "model_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\QLearning/outputs/CliffWalking-v0/20220826-224730/models/", "n_states": 48, "n_actions": 4} \ No newline at end of file diff --git a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/testing_curve.png b/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/testing_curve.png deleted file mode 100644 index 527fff3..0000000 Binary files a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/training_curve.png b/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/training_curve.png deleted file mode 100644 index 819e106..0000000 Binary files a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/training_curve.png and /dev/null differ diff --git a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/training_results.csv b/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/training_results.csv deleted file mode 100644 index 523dc54..0000000 --- a/projects/codes/QLearning/outputs/CliffWalking-v0/20220826-224730/results/training_results.csv +++ /dev/null @@ -1,401 +0,0 @@ -episodes,rewards,steps -0,-2131,448 -1,-1086,492 -2,-586,388 -3,-220,220 -4,-154,154 -5,-122,122 -6,-150,150 -7,-159,159 -8,-164,164 -9,-88,88 -10,-195,195 -11,-114,114 -12,-60,60 -13,-179,179 -14,-101,101 -15,-304,205 -16,-96,96 -17,-119,119 -18,-113,113 -19,-98,98 -20,-106,106 -21,-105,105 -22,-77,77 -23,-51,51 -24,-105,105 -25,-136,136 -26,-100,100 -27,-29,29 -28,-79,79 -29,-114,114 -30,-82,82 -31,-70,70 -32,-75,75 -33,-51,51 -34,-94,94 -35,-52,52 -36,-93,93 -37,-71,71 -38,-73,73 -39,-48,48 -40,-52,52 -41,-96,96 -42,-46,46 -43,-65,65 -44,-57,57 -45,-41,41 -46,-104,104 -47,-51,51 -48,-181,82 -49,-229,130 -50,-39,39 -51,-69,69 -52,-53,53 -53,-59,59 -54,-26,26 -55,-75,75 -56,-31,31 -57,-60,60 -58,-63,63 -59,-40,40 -60,-35,35 -61,-79,79 -62,-42,42 -63,-22,22 -64,-73,73 -65,-71,71 -66,-18,18 -67,-55,55 -68,-29,29 -69,-43,43 -70,-70,70 -71,-49,49 -72,-42,42 -73,-29,29 -74,-81,81 -75,-36,36 -76,-38,38 -77,-36,36 -78,-52,52 -79,-28,28 -80,-42,42 -81,-52,52 -82,-66,66 -83,-31,31 -84,-27,27 -85,-49,49 -86,-28,28 -87,-54,54 -88,-34,34 -89,-35,35 -90,-50,50 -91,-36,36 -92,-36,36 -93,-46,46 -94,-34,34 -95,-135,36 -96,-39,39 -97,-36,36 -98,-26,26 -99,-56,56 -100,-40,40 -101,-40,40 -102,-26,26 -103,-28,28 -104,-31,31 -105,-35,35 -106,-26,26 -107,-57,57 -108,-44,44 -109,-41,41 -110,-31,31 -111,-26,26 -112,-25,25 -113,-41,41 -114,-32,32 -115,-44,44 -116,-30,30 -117,-32,32 -118,-30,30 -119,-25,25 -120,-23,23 -121,-47,47 -122,-24,24 -123,-45,45 -124,-39,39 -125,-21,21 -126,-43,43 -127,-143,44 -128,-26,26 -129,-20,20 -130,-32,32 -131,-16,16 -132,-24,24 -133,-42,42 -134,-25,25 -135,-36,36 -136,-19,19 -137,-29,29 -138,-43,43 -139,-17,17 -140,-150,51 -141,-32,32 -142,-34,34 -143,-19,19 -144,-26,26 -145,-30,30 -146,-31,31 -147,-49,49 -148,-33,33 -149,-21,21 -150,-17,17 -151,-48,48 -152,-34,34 -153,-20,20 -154,-20,20 -155,-26,26 -156,-21,21 -157,-13,13 -158,-40,40 -159,-22,22 -160,-26,26 -161,-30,30 -162,-29,29 -163,-25,25 -164,-26,26 -165,-27,27 -166,-21,21 -167,-29,29 -168,-24,24 -169,-17,17 -170,-22,22 -171,-35,35 -172,-35,35 -173,-18,18 -174,-135,36 -175,-15,15 -176,-23,23 -177,-28,28 -178,-25,25 -179,-24,24 -180,-29,29 -181,-31,31 -182,-24,24 -183,-129,30 -184,-45,45 -185,-24,24 -186,-17,17 -187,-20,20 -188,-21,21 -189,-23,23 -190,-15,15 -191,-32,32 -192,-22,22 -193,-19,19 -194,-17,17 -195,-45,45 -196,-15,15 -197,-14,14 -198,-14,14 -199,-37,37 -200,-23,23 -201,-17,17 -202,-19,19 -203,-21,21 -204,-23,23 -205,-27,27 -206,-14,14 -207,-18,18 -208,-23,23 -209,-34,34 -210,-23,23 -211,-13,13 -212,-25,25 -213,-17,17 -214,-13,13 -215,-21,21 -216,-29,29 -217,-18,18 -218,-24,24 -219,-15,15 -220,-27,27 -221,-25,25 -222,-21,21 -223,-19,19 -224,-17,17 -225,-18,18 -226,-13,13 -227,-22,22 -228,-14,14 -229,-13,13 -230,-29,29 -231,-23,23 -232,-15,15 -233,-15,15 -234,-14,14 -235,-28,28 -236,-25,25 -237,-17,17 -238,-23,23 -239,-29,29 -240,-15,15 -241,-14,14 -242,-15,15 -243,-23,23 -244,-15,15 -245,-16,16 -246,-19,19 -247,-13,13 -248,-16,16 -249,-17,17 -250,-25,25 -251,-30,30 -252,-13,13 -253,-14,14 -254,-15,15 -255,-22,22 -256,-14,14 -257,-17,17 -258,-126,27 -259,-15,15 -260,-21,21 -261,-16,16 -262,-23,23 -263,-14,14 -264,-13,13 -265,-13,13 -266,-19,19 -267,-13,13 -268,-19,19 -269,-17,17 -270,-17,17 -271,-13,13 -272,-19,19 -273,-13,13 -274,-13,13 -275,-16,16 -276,-22,22 -277,-14,14 -278,-15,15 -279,-19,19 -280,-34,34 -281,-13,13 -282,-15,15 -283,-32,32 -284,-13,13 -285,-13,13 -286,-13,13 -287,-14,14 -288,-16,16 -289,-13,13 -290,-13,13 -291,-17,17 -292,-13,13 -293,-13,13 -294,-22,22 -295,-14,14 -296,-15,15 -297,-13,13 -298,-13,13 -299,-13,13 -300,-16,16 -301,-13,13 -302,-14,14 -303,-13,13 -304,-13,13 -305,-13,13 -306,-24,24 -307,-13,13 -308,-13,13 -309,-15,15 -310,-13,13 -311,-13,13 -312,-13,13 -313,-15,15 -314,-13,13 -315,-19,19 -316,-15,15 -317,-17,17 -318,-13,13 -319,-13,13 -320,-13,13 -321,-13,13 -322,-13,13 -323,-15,15 -324,-13,13 -325,-13,13 -326,-13,13 -327,-123,24 -328,-13,13 -329,-13,13 -330,-13,13 -331,-13,13 -332,-13,13 -333,-13,13 -334,-13,13 -335,-13,13 -336,-16,16 -337,-13,13 -338,-23,23 -339,-13,13 -340,-13,13 -341,-13,13 -342,-13,13 -343,-13,13 -344,-13,13 -345,-13,13 -346,-13,13 -347,-13,13 -348,-13,13 -349,-13,13 -350,-134,35 -351,-13,13 -352,-13,13 -353,-13,13 -354,-13,13 -355,-13,13 -356,-13,13 -357,-13,13 -358,-13,13 -359,-13,13 -360,-15,15 -361,-13,13 -362,-13,13 -363,-13,13 -364,-13,13 -365,-13,13 -366,-13,13 -367,-13,13 -368,-13,13 -369,-14,14 -370,-13,13 -371,-13,13 -372,-13,13 -373,-13,13 -374,-13,13 -375,-13,13 -376,-13,13 -377,-124,25 -378,-13,13 -379,-13,13 -380,-13,13 -381,-13,13 -382,-13,13 -383,-13,13 -384,-13,13 -385,-13,13 -386,-13,13 -387,-13,13 -388,-13,13 -389,-121,22 -390,-13,13 -391,-13,13 -392,-13,13 -393,-13,13 -394,-13,13 -395,-13,13 -396,-13,13 -397,-13,13 -398,-17,17 -399,-13,13 diff --git a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/models/Qleaning_model.pkl b/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/models/Qleaning_model.pkl deleted file mode 100644 index 3699d45..0000000 Binary files a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/models/Qleaning_model.pkl and /dev/null differ diff --git a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/params.json b/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/params.json deleted file mode 100644 index 045ef65..0000000 --- a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/params.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "algo_name": "Q-learning", - "env_name": "FrozenLakeNoSlippery-v1", - "train_eps": 800, - "test_eps": 20, - "gamma": 0.9, - "epsilon_start": 0.7, - "epsilon_end": 0.1, - "epsilon_decay": 2000, - "lr": 0.9, - "device": "cpu", - "seed": 10, - "show_fig": false, - "save_fig": true, - "result_path": "/Users/jj/Desktop/rl-tutorials/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/", - "model_path": "/Users/jj/Desktop/rl-tutorials/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/models/", - "n_states": 16, - "n_actions": 4 -} \ No newline at end of file diff --git a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/testing_curve.png b/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/testing_curve.png deleted file mode 100644 index e70c9f5..0000000 Binary files a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_curve.png b/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_curve.png deleted file mode 100644 index 98c0816..0000000 Binary files a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_curve.png and /dev/null differ diff --git a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_results.csv b/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_results.csv deleted file mode 100644 index 4177f08..0000000 --- a/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_results.csv +++ /dev/null @@ -1,801 +0,0 @@ -episodes,rewards,steps -0,0.0,20 -1,0.0,14 -2,0.0,13 -3,0.0,9 -4,0.0,10 -5,0.0,6 -6,0.0,11 -7,0.0,6 -8,0.0,3 -9,0.0,9 -10,0.0,11 -11,0.0,22 -12,0.0,5 -13,0.0,16 -14,0.0,4 -15,0.0,9 -16,0.0,18 -17,0.0,2 -18,0.0,4 -19,0.0,8 -20,0.0,7 -21,0.0,4 -22,0.0,22 -23,0.0,15 -24,0.0,5 -25,0.0,16 -26,0.0,7 -27,0.0,19 -28,0.0,22 -29,0.0,16 -30,0.0,11 -31,0.0,22 -32,0.0,28 -33,0.0,23 -34,0.0,4 -35,0.0,11 -36,0.0,8 -37,0.0,15 -38,0.0,5 -39,0.0,7 -40,0.0,9 -41,0.0,4 -42,0.0,3 -43,0.0,6 -44,0.0,41 -45,0.0,9 -46,0.0,23 -47,0.0,3 -48,1.0,38 -49,0.0,29 -50,0.0,17 -51,0.0,4 -52,0.0,2 -53,0.0,25 -54,0.0,6 -55,0.0,2 -56,0.0,30 -57,0.0,6 -58,0.0,7 -59,0.0,11 -60,0.0,9 -61,0.0,8 -62,0.0,23 -63,0.0,10 -64,0.0,3 -65,0.0,5 -66,0.0,7 -67,0.0,18 -68,0.0,8 -69,0.0,26 -70,0.0,6 -71,0.0,14 -72,0.0,4 -73,0.0,25 -74,0.0,21 -75,0.0,13 -76,0.0,4 -77,0.0,29 -78,0.0,21 -79,0.0,6 -80,0.0,6 -81,0.0,11 -82,0.0,21 -83,0.0,9 -84,0.0,9 -85,0.0,7 -86,0.0,48 -87,0.0,23 -88,0.0,160 -89,0.0,7 -90,0.0,10 -91,0.0,24 -92,0.0,4 -93,0.0,7 -94,0.0,17 -95,0.0,87 -96,0.0,28 -97,0.0,7 -98,0.0,5 -99,0.0,12 -100,0.0,14 -101,0.0,6 -102,0.0,13 -103,0.0,93 -104,0.0,4 -105,0.0,50 -106,0.0,8 -107,0.0,12 -108,0.0,43 -109,0.0,30 -110,0.0,15 -111,0.0,19 -112,0.0,182 -113,0.0,40 -114,0.0,88 -115,0.0,19 -116,0.0,30 -117,0.0,27 -118,0.0,5 -119,0.0,87 -120,0.0,9 -121,0.0,64 -122,0.0,27 -123,0.0,68 -124,0.0,81 -125,0.0,86 -126,0.0,227 -127,0.0,41 -128,0.0,70 -129,0.0,27 -130,0.0,6 -131,0.0,18 -132,0.0,38 -133,0.0,26 -134,0.0,36 -135,0.0,3 -136,0.0,61 -137,0.0,105 -138,0.0,38 -139,0.0,18 -140,0.0,33 -141,0.0,29 -142,0.0,49 -143,0.0,88 -144,0.0,22 -145,0.0,65 -146,0.0,36 -147,0.0,30 -148,0.0,58 -149,0.0,43 -150,0.0,53 -151,0.0,43 -152,0.0,13 -153,0.0,8 -154,0.0,39 -155,0.0,29 -156,0.0,26 -157,0.0,60 -158,0.0,153 -159,0.0,116 -160,0.0,53 -161,0.0,54 -162,0.0,8 -163,0.0,58 -164,0.0,3 -165,0.0,47 -166,0.0,16 -167,0.0,21 -168,0.0,44 -169,0.0,29 -170,0.0,104 -171,0.0,158 -172,0.0,83 -173,0.0,26 -174,0.0,24 -175,0.0,10 -176,0.0,12 -177,0.0,40 -178,0.0,25 -179,0.0,18 -180,0.0,60 -181,0.0,203 -182,0.0,23 -183,0.0,54 -184,0.0,71 -185,0.0,19 -186,0.0,118 -187,0.0,26 -188,0.0,41 -189,0.0,41 -190,0.0,60 -191,0.0,31 -192,0.0,34 -193,0.0,35 -194,0.0,59 -195,0.0,51 -196,0.0,426 -197,0.0,79 -198,0.0,40 -199,0.0,17 -200,0.0,79 -201,0.0,126 -202,0.0,61 -203,0.0,25 -204,0.0,18 -205,0.0,27 -206,0.0,13 -207,0.0,187 -208,0.0,160 -209,0.0,32 -210,0.0,108 -211,0.0,164 -212,0.0,17 -213,0.0,82 -214,0.0,194 -215,0.0,7 -216,0.0,36 -217,0.0,156 -218,0.0,17 -219,0.0,183 -220,0.0,243 -221,0.0,87 -222,0.0,42 -223,0.0,80 -224,0.0,54 -225,0.0,82 -226,0.0,97 -227,0.0,65 -228,0.0,83 -229,0.0,159 -230,0.0,178 -231,0.0,104 -232,0.0,21 -233,0.0,118 -234,0.0,80 -235,0.0,170 -236,0.0,94 -237,0.0,235 -238,0.0,13 -239,0.0,31 -240,0.0,134 -241,0.0,32 -242,0.0,58 -243,0.0,38 -244,0.0,28 -245,0.0,159 -246,0.0,182 -247,0.0,51 -248,0.0,25 -249,0.0,73 -250,0.0,56 -251,0.0,55 -252,0.0,38 -253,0.0,292 -254,0.0,319 -255,0.0,100 -256,0.0,84 -257,0.0,24 -258,0.0,17 -259,0.0,159 -260,0.0,25 -261,0.0,73 -262,0.0,130 -263,0.0,111 -264,0.0,65 -265,1.0,58 -266,0.0,47 -267,0.0,48 -268,0.0,13 -269,0.0,100 -270,0.0,38 -271,0.0,111 -272,0.0,226 -273,0.0,38 -274,0.0,83 -275,0.0,42 -276,0.0,199 -277,0.0,83 -278,0.0,28 -279,0.0,46 -280,0.0,262 -281,0.0,123 -282,0.0,91 -283,0.0,53 -284,0.0,19 -285,0.0,26 -286,0.0,93 -287,0.0,38 -288,0.0,22 -289,0.0,43 -290,0.0,163 -291,0.0,25 -292,0.0,59 -293,0.0,71 -294,0.0,20 -295,0.0,115 -296,0.0,248 -297,0.0,66 -298,0.0,58 -299,0.0,129 -300,0.0,122 -301,0.0,47 -302,0.0,60 -303,0.0,79 -304,1.0,137 -305,0.0,27 -306,1.0,93 -307,0.0,46 -308,1.0,83 -309,1.0,8 -310,1.0,6 -311,1.0,6 -312,0.0,4 -313,1.0,6 -314,0.0,2 -315,1.0,6 -316,1.0,6 -317,1.0,6 -318,1.0,6 -319,1.0,8 -320,0.0,5 -321,1.0,6 -322,1.0,7 -323,0.0,5 -324,1.0,6 -325,1.0,6 -326,1.0,8 -327,1.0,6 -328,1.0,6 -329,1.0,6 -330,1.0,7 -331,1.0,6 -332,1.0,6 -333,0.0,3 -334,1.0,7 -335,0.0,4 -336,1.0,6 -337,1.0,6 -338,1.0,7 -339,1.0,6 -340,1.0,6 -341,1.0,7 -342,1.0,7 -343,1.0,7 -344,1.0,6 -345,1.0,6 -346,1.0,6 -347,1.0,6 -348,1.0,6 -349,1.0,6 -350,1.0,6 -351,1.0,7 -352,0.0,4 -353,1.0,8 -354,1.0,8 -355,1.0,7 -356,1.0,6 -357,1.0,8 -358,1.0,6 -359,1.0,6 -360,1.0,7 -361,1.0,6 -362,1.0,6 -363,1.0,8 -364,1.0,7 -365,1.0,6 -366,1.0,6 -367,0.0,3 -368,1.0,11 -369,1.0,6 -370,1.0,8 -371,0.0,2 -372,1.0,6 -373,1.0,6 -374,1.0,6 -375,1.0,6 -376,1.0,8 -377,1.0,6 -378,1.0,7 -379,1.0,6 -380,1.0,7 -381,1.0,6 -382,1.0,8 -383,0.0,2 -384,1.0,6 -385,1.0,7 -386,1.0,6 -387,1.0,6 -388,1.0,10 -389,1.0,7 -390,1.0,6 -391,1.0,6 -392,1.0,6 -393,1.0,6 -394,1.0,6 -395,1.0,7 -396,0.0,4 -397,1.0,7 -398,1.0,6 -399,1.0,8 -400,0.0,3 -401,1.0,6 -402,1.0,6 -403,1.0,6 -404,1.0,6 -405,0.0,2 -406,1.0,6 -407,1.0,6 -408,1.0,6 -409,1.0,6 -410,1.0,6 -411,1.0,7 -412,1.0,6 -413,1.0,6 -414,1.0,7 -415,1.0,6 -416,1.0,6 -417,1.0,6 -418,1.0,6 -419,1.0,6 -420,1.0,6 -421,1.0,6 -422,1.0,8 -423,1.0,6 -424,1.0,8 -425,1.0,7 -426,1.0,6 -427,0.0,3 -428,1.0,6 -429,1.0,7 -430,1.0,6 -431,1.0,6 -432,1.0,6 -433,1.0,10 -434,1.0,6 -435,1.0,6 -436,1.0,6 -437,1.0,6 -438,1.0,10 -439,1.0,6 -440,1.0,8 -441,1.0,8 -442,1.0,7 -443,1.0,6 -444,0.0,5 -445,0.0,2 -446,1.0,8 -447,1.0,6 -448,1.0,10 -449,1.0,6 -450,1.0,8 -451,1.0,10 -452,1.0,6 -453,1.0,6 -454,1.0,6 -455,1.0,10 -456,1.0,6 -457,0.0,4 -458,1.0,6 -459,1.0,6 -460,1.0,6 -461,1.0,15 -462,1.0,6 -463,1.0,6 -464,1.0,6 -465,1.0,6 -466,1.0,6 -467,1.0,6 -468,1.0,8 -469,1.0,6 -470,1.0,7 -471,1.0,6 -472,1.0,6 -473,1.0,8 -474,1.0,6 -475,1.0,6 -476,1.0,8 -477,1.0,8 -478,1.0,6 -479,1.0,6 -480,1.0,6 -481,1.0,10 -482,1.0,6 -483,1.0,6 -484,1.0,6 -485,1.0,6 -486,1.0,6 -487,1.0,6 -488,1.0,6 -489,1.0,8 -490,1.0,8 -491,1.0,6 -492,1.0,6 -493,0.0,2 -494,1.0,6 -495,1.0,6 -496,1.0,6 -497,1.0,8 -498,1.0,6 -499,1.0,6 -500,1.0,6 -501,1.0,6 -502,1.0,6 -503,1.0,6 -504,1.0,6 -505,1.0,6 -506,1.0,6 -507,1.0,7 -508,0.0,3 -509,1.0,7 -510,1.0,6 -511,1.0,6 -512,1.0,6 -513,0.0,2 -514,1.0,6 -515,1.0,8 -516,1.0,6 -517,1.0,6 -518,1.0,6 -519,1.0,6 -520,1.0,9 -521,1.0,6 -522,1.0,6 -523,1.0,6 -524,1.0,6 -525,1.0,6 -526,1.0,6 -527,1.0,9 -528,1.0,7 -529,0.0,4 -530,1.0,6 -531,1.0,8 -532,1.0,11 -533,1.0,6 -534,1.0,6 -535,1.0,6 -536,1.0,6 -537,1.0,6 -538,1.0,8 -539,1.0,6 -540,1.0,6 -541,1.0,8 -542,1.0,7 -543,1.0,6 -544,1.0,8 -545,1.0,6 -546,0.0,5 -547,1.0,9 -548,1.0,8 -549,1.0,8 -550,1.0,6 -551,1.0,8 -552,1.0,8 -553,1.0,6 -554,0.0,5 -555,0.0,3 -556,0.0,2 -557,1.0,8 -558,1.0,6 -559,1.0,6 -560,1.0,6 -561,1.0,6 -562,1.0,6 -563,1.0,6 -564,1.0,6 -565,1.0,6 -566,1.0,6 -567,1.0,6 -568,1.0,6 -569,1.0,6 -570,1.0,6 -571,1.0,6 -572,0.0,2 -573,1.0,6 -574,0.0,4 -575,1.0,6 -576,1.0,6 -577,1.0,6 -578,1.0,6 -579,1.0,6 -580,1.0,8 -581,0.0,5 -582,1.0,6 -583,1.0,6 -584,1.0,6 -585,1.0,6 -586,1.0,6 -587,1.0,6 -588,0.0,3 -589,1.0,6 -590,1.0,6 -591,1.0,6 -592,0.0,2 -593,1.0,6 -594,0.0,4 -595,1.0,6 -596,1.0,6 -597,1.0,6 -598,1.0,6 -599,1.0,8 -600,1.0,6 -601,1.0,7 -602,1.0,6 -603,1.0,7 -604,1.0,6 -605,0.0,2 -606,1.0,6 -607,1.0,6 -608,0.0,5 -609,0.0,3 -610,0.0,3 -611,1.0,6 -612,0.0,5 -613,1.0,8 -614,1.0,8 -615,1.0,6 -616,1.0,6 -617,1.0,7 -618,1.0,6 -619,1.0,6 -620,1.0,6 -621,1.0,6 -622,1.0,6 -623,1.0,8 -624,0.0,2 -625,1.0,6 -626,1.0,6 -627,1.0,6 -628,1.0,6 -629,1.0,6 -630,1.0,6 -631,1.0,6 -632,1.0,8 -633,1.0,6 -634,1.0,8 -635,1.0,6 -636,1.0,6 -637,1.0,8 -638,1.0,8 -639,0.0,5 -640,0.0,4 -641,0.0,4 -642,1.0,6 -643,1.0,6 -644,1.0,6 -645,1.0,6 -646,1.0,8 -647,1.0,6 -648,0.0,4 -649,1.0,6 -650,1.0,8 -651,1.0,6 -652,1.0,6 -653,1.0,6 -654,1.0,6 -655,1.0,6 -656,1.0,6 -657,1.0,6 -658,1.0,8 -659,1.0,8 -660,1.0,6 -661,1.0,8 -662,1.0,9 -663,1.0,6 -664,1.0,6 -665,1.0,6 -666,1.0,6 -667,1.0,10 -668,1.0,6 -669,1.0,6 -670,1.0,6 -671,1.0,11 -672,1.0,10 -673,1.0,8 -674,1.0,6 -675,1.0,6 -676,1.0,6 -677,0.0,5 -678,1.0,6 -679,0.0,2 -680,1.0,9 -681,1.0,6 -682,1.0,8 -683,1.0,7 -684,1.0,6 -685,1.0,6 -686,1.0,7 -687,0.0,3 -688,1.0,7 -689,0.0,2 -690,1.0,6 -691,1.0,6 -692,1.0,8 -693,1.0,8 -694,1.0,6 -695,1.0,6 -696,0.0,2 -697,1.0,8 -698,1.0,6 -699,1.0,8 -700,1.0,6 -701,1.0,6 -702,1.0,9 -703,1.0,6 -704,1.0,8 -705,1.0,11 -706,1.0,6 -707,1.0,6 -708,1.0,6 -709,1.0,6 -710,1.0,8 -711,1.0,6 -712,1.0,6 -713,1.0,6 -714,0.0,5 -715,1.0,6 -716,1.0,6 -717,1.0,6 -718,1.0,6 -719,1.0,6 -720,1.0,7 -721,1.0,6 -722,1.0,6 -723,1.0,6 -724,1.0,6 -725,1.0,10 -726,1.0,6 -727,1.0,6 -728,1.0,6 -729,1.0,6 -730,1.0,6 -731,1.0,7 -732,1.0,6 -733,1.0,8 -734,1.0,7 -735,1.0,6 -736,1.0,6 -737,1.0,14 -738,1.0,6 -739,1.0,6 -740,1.0,12 -741,1.0,6 -742,1.0,6 -743,1.0,6 -744,1.0,6 -745,1.0,6 -746,1.0,6 -747,0.0,3 -748,1.0,6 -749,1.0,6 -750,1.0,6 -751,1.0,7 -752,1.0,6 -753,1.0,6 -754,1.0,6 -755,1.0,8 -756,0.0,2 -757,1.0,6 -758,1.0,6 -759,1.0,6 -760,1.0,6 -761,1.0,6 -762,1.0,6 -763,1.0,6 -764,1.0,6 -765,1.0,6 -766,0.0,4 -767,1.0,8 -768,1.0,6 -769,0.0,2 -770,1.0,10 -771,1.0,8 -772,1.0,6 -773,1.0,6 -774,1.0,6 -775,0.0,3 -776,1.0,6 -777,1.0,6 -778,0.0,6 -779,1.0,8 -780,1.0,6 -781,1.0,9 -782,1.0,6 -783,1.0,6 -784,1.0,8 -785,1.0,8 -786,1.0,6 -787,0.0,5 -788,1.0,6 -789,1.0,6 -790,1.0,6 -791,1.0,6 -792,1.0,6 -793,1.0,6 -794,1.0,8 -795,1.0,6 -796,0.0,2 -797,1.0,8 -798,1.0,7 -799,1.0,6 diff --git a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/models/Qleaning_model.pkl b/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/models/Qleaning_model.pkl deleted file mode 100644 index 6d6b01f..0000000 Binary files a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/models/Qleaning_model.pkl and /dev/null differ diff --git a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/params.json b/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/params.json deleted file mode 100644 index ead445f..0000000 --- a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/params.json +++ /dev/null @@ -1 +0,0 @@ -{"algo_name": "Q-learning", "env_name": "Racetrack-v0", "train_eps": 400, "test_eps": 20, "gamma": 0.9, "epsilon_start": 0.95, "epsilon_end": 0.01, "epsilon_decay": 300, "lr": 0.1, "device": "cpu", "seed": 10, "show_fig": false, "save_fig": true, "result_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\QLearning/outputs/Racetrack-v0/20220826-224626/results/", "model_path": "C:\\Users\\24438\\Desktop\\rl-tutorials\\codes\\QLearning/outputs/Racetrack-v0/20220826-224626/models/", "n_states": 4, "n_actions": 9} \ No newline at end of file diff --git a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/testing_curve.png b/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/testing_curve.png deleted file mode 100644 index fa1588a..0000000 Binary files a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/testing_results.csv b/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/testing_results.csv deleted file mode 100644 index 3d60bb2..0000000 --- a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/testing_results.csv +++ /dev/null @@ -1,21 +0,0 @@ -episodes,rewards,steps -0,-1000,1000 -1,2,8 -2,4,6 -3,3,7 -4,2,8 -5,3,7 -6,4,6 -7,-1000,1000 -8,3,7 -9,-11,11 -10,-19,19 -11,-18,18 -12,1,9 -13,1,9 -14,4,6 -15,-16,16 -16,-17,17 -17,4,6 -18,-16,16 -19,4,6 diff --git a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/training_curve.png b/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/training_curve.png deleted file mode 100644 index c0c7b24..0000000 Binary files a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/training_curve.png and /dev/null differ diff --git a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/training_results.csv b/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/training_results.csv deleted file mode 100644 index a7df26d..0000000 --- a/projects/codes/QLearning/outputs/Racetrack-v0/20220826-224626/results/training_results.csv +++ /dev/null @@ -1,401 +0,0 @@ -episodes,rewards,steps -0,-3580,1000 -1,-2960,1000 -2,-2670,1000 -3,-2720,1000 -4,-2670,1000 -5,-2570,1000 -6,-2407,977 -7,-2012,852 -8,-2500,1000 -9,-2530,1000 -10,-2550,1000 -11,-437,187 -12,-80,40 -13,-2450,1000 -14,-338,148 -15,-1175,525 -16,-755,325 -17,-411,181 -18,-1068,448 -19,-785,325 -20,-149,79 -21,-628,268 -22,-423,183 -23,-282,122 -24,-2198,938 -25,-13,13 -26,-253,113 -27,-48,28 -28,-72,42 -29,-123,63 -30,-305,145 -31,-72,32 -32,-142,72 -33,-13,13 -34,4,6 -35,-1285,545 -36,-174,94 -37,-436,196 -38,-759,339 -39,-11,11 -40,-17,17 -41,-283,123 -42,-181,81 -43,-44,24 -44,-55,35 -45,-135,65 -46,-577,277 -47,-234,114 -48,-54,34 -49,4,6 -50,-29,19 -51,-100,50 -52,-32,22 -53,-23,23 -54,4,6 -55,-17,17 -56,-18,18 -57,-48,28 -58,-34,24 -59,-45,25 -60,-29,19 -61,1,9 -62,-77,37 -63,3,7 -64,-25,15 -65,-3,13 -66,-78,48 -67,-69,39 -68,-105,45 -69,-48,28 -70,3,7 -71,4,6 -72,-100,50 -73,-130,60 -74,-20,20 -75,4,6 -76,4,6 -77,4,6 -78,4,6 -79,-47,27 -80,4,6 -81,4,6 -82,-174,94 -83,-12,12 -84,-26,16 -85,3,7 -86,3,7 -87,-42,32 -88,-48,28 -89,-97,57 -90,-11,11 -91,-16,16 -92,-15,15 -93,4,6 -94,-147,67 -95,-52,32 -96,-97,47 -97,3,7 -98,-17,17 -99,3,7 -100,4,6 -101,3,7 -102,3,7 -103,3,7 -104,1,9 -105,4,6 -106,4,6 -107,3,7 -108,4,6 -109,-68,38 -110,3,7 -111,4,6 -112,-14,14 -113,4,6 -114,-57,37 -115,3,7 -116,4,6 -117,-12,12 -118,3,7 -119,3,7 -120,-64,34 -121,-13,13 -122,3,7 -123,-13,13 -124,4,6 -125,3,7 -126,-32,22 -127,-41,31 -128,3,7 -129,3,7 -130,3,7 -131,4,6 -132,4,6 -133,3,7 -134,-12,12 -135,-31,21 -136,4,6 -137,3,7 -138,-51,31 -139,-48,28 -140,4,6 -141,-85,45 -142,-14,14 -143,4,6 -144,3,7 -145,-6,16 -146,4,6 -147,4,6 -148,-15,15 -149,4,6 -150,-24,24 -151,3,7 -152,-14,14 -153,-18,18 -154,3,7 -155,4,6 -156,-85,45 -157,-51,31 -158,3,7 -159,2,8 -160,3,7 -161,-79,39 -162,-14,14 -163,-13,13 -164,4,6 -165,3,7 -166,4,6 -167,3,7 -168,-74,34 -169,-15,15 -170,4,6 -171,-14,14 -172,4,6 -173,-31,21 -174,-8,18 -175,4,6 -176,4,6 -177,4,6 -178,4,6 -179,-29,19 -180,4,6 -181,3,7 -182,4,6 -183,-82,42 -184,3,7 -185,4,6 -186,4,6 -187,-11,11 -188,-23,23 -189,-33,23 -190,3,7 -191,-12,12 -192,-44,24 -193,-62,42 -194,-16,16 -195,4,6 -196,-12,12 -197,3,7 -198,-13,13 -199,3,7 -200,3,7 -201,4,6 -202,4,6 -203,4,6 -204,-28,18 -205,-16,16 -206,3,7 -207,4,6 -208,-12,12 -209,-13,13 -210,-66,36 -211,-14,14 -212,4,6 -213,4,6 -214,-15,15 -215,-60,30 -216,4,6 -217,3,7 -218,4,6 -219,-33,23 -220,-12,12 -221,-14,14 -222,4,6 -223,3,7 -224,-97,47 -225,4,6 -226,2,8 -227,4,6 -228,4,6 -229,3,7 -230,-11,11 -231,4,6 -232,3,7 -233,3,7 -234,4,6 -235,3,7 -236,3,7 -237,-32,22 -238,-13,13 -239,3,7 -240,-22,22 -241,4,6 -242,2,8 -243,-31,21 -244,4,6 -245,-4,14 -246,-30,20 -247,4,6 -248,3,7 -249,-26,16 -250,4,6 -251,-12,12 -252,2,8 -253,1,9 -254,4,6 -255,2,8 -256,2,8 -257,-12,12 -258,3,7 -259,-48,28 -260,4,6 -261,4,6 -262,-51,31 -263,-12,12 -264,4,6 -265,2,8 -266,2,8 -267,2,8 -268,3,7 -269,4,6 -270,4,6 -271,-17,17 -272,4,6 -273,-13,13 -274,-16,16 -275,-97,57 -276,3,7 -277,-1,11 -278,-32,22 -279,3,7 -280,4,6 -281,3,7 -282,3,7 -283,3,7 -284,3,7 -285,2,8 -286,3,7 -287,-15,15 -288,2,8 -289,-18,18 -290,4,6 -291,-36,26 -292,4,6 -293,4,6 -294,4,6 -295,4,6 -296,-77,47 -297,-14,14 -298,3,7 -299,3,7 -300,3,7 -301,4,6 -302,3,7 -303,4,6 -304,-12,12 -305,-45,35 -306,-63,43 -307,2,8 -308,4,6 -309,4,6 -310,-13,13 -311,4,6 -312,-13,13 -313,4,6 -314,3,7 -315,-30,20 -316,-13,13 -317,3,7 -318,4,6 -319,4,6 -320,-12,12 -321,-13,13 -322,3,7 -323,3,7 -324,3,7 -325,3,7 -326,-36,26 -327,4,6 -328,3,7 -329,3,7 -330,3,7 -331,3,7 -332,-14,14 -333,-16,16 -334,3,7 -335,3,7 -336,-14,14 -337,1,9 -338,2,8 -339,3,7 -340,4,6 -341,-36,26 -342,-14,14 -343,-78,48 -344,2,8 -345,-37,27 -346,3,7 -347,3,7 -348,-37,27 -349,-16,16 -350,4,6 -351,-15,15 -352,4,6 -353,2,8 -354,-44,24 -355,-13,13 -356,-14,14 -357,-17,17 -358,-13,13 -359,3,7 -360,2,8 -361,4,6 -362,3,7 -363,-5,15 -364,-14,14 -365,2,8 -366,-12,12 -367,3,7 -368,4,6 -369,2,8 -370,2,8 -371,1,9 -372,-16,16 -373,1,9 -374,4,6 -375,-16,16 -376,3,7 -377,2,8 -378,-13,13 -379,-44,34 -380,-16,16 -381,-30,20 -382,4,6 -383,4,6 -384,2,8 -385,-15,15 -386,4,6 -387,3,7 -388,2,8 -389,4,6 -390,2,8 -391,3,7 -392,3,7 -393,-14,14 -394,-15,15 -395,3,7 -396,-13,13 -397,3,7 -398,4,6 -399,3,7 diff --git a/projects/codes/QLearning/qlearning.py b/projects/codes/QLearning/qlearning.py index c987242..48dfa37 100644 --- a/projects/codes/QLearning/qlearning.py +++ b/projects/codes/QLearning/qlearning.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2020-09-11 23:03:00 LastEditor: John -LastEditTime: 2022-08-24 10:31:04 +LastEditTime: 2022-10-30 01:38:26 Discription: use defaultdict to define Q table Environment: ''' @@ -16,14 +16,14 @@ from collections import defaultdict class QLearning(object): def __init__(self,cfg): - self.n_actions = cfg['n_actions'] - self.lr = cfg['lr'] - self.gamma = cfg['gamma'] - self.epsilon = cfg['epsilon_start'] + self.n_actions = cfg.n_actions + self.lr = cfg.lr + self.gamma = cfg.gamma + self.epsilon = cfg.epsilon_start self.sample_count = 0 - self.epsilon_start = cfg['epsilon_start'] - self.epsilon_end = cfg['epsilon_end'] - self.epsilon_decay = cfg['epsilon_decay'] + self.epsilon_start = cfg.epsilon_start + self.epsilon_end = cfg.epsilon_end + self.epsilon_decay = cfg.epsilon_decay self.Q_table = defaultdict(lambda: np.zeros(self.n_actions)) # use nested dictionary to represent Q(s,a), here set all Q(s,a)=0 initially, not like pseudo code def sample_action(self, state): ''' sample action with e-greedy policy while training diff --git a/projects/codes/QLearning/task0.py b/projects/codes/QLearning/task0.py new file mode 100644 index 0000000..da52113 --- /dev/null +++ b/projects/codes/QLearning/task0.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: John +Email: johnjim0816@gmail.com +Date: 2020-09-11 23:03:00 +LastEditor: John +LastEditTime: 2022-10-30 02:04:55 +Discription: +Environment: +''' +import sys,os +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path + +import gym +import datetime +import argparse +from envs.gridworld_env import FrozenLakeWapper +from envs.wrappers import CliffWalkingWapper +from envs.register import register_env +from qlearning import QLearning +from common.utils import all_seed,merge_class_attrs +from common.launcher import Launcher +from config.config import GeneralConfigQLearning,AlgoConfigQLearning + +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigQLearning()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigQLearning()) + def env_agent_config(self,cfg,logger): + ''' create env and agent + ''' + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=False) # create env + if cfg.env_name == 'CliffWalking-v0': + env = CliffWalkingWapper(env) + if cfg.seed !=0: # set random seed + all_seed(env,seed=cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + agent = QLearning(cfg) + return env,agent + def train(self,cfg,env,agent,logger): + logger.info("Start training!") + logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + rewards = [] # record rewards for all episodes + steps = [] # record steps for all episodes + for i_ep in range(cfg.train_eps): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.sample_action(state) # sample action + next_state, reward, terminated, _ = env.step(action) # update env and return transitions + agent.update(state, action, reward, next_state, terminated) # update agent + state = next_state # update state + ep_reward += reward + ep_step += 1 + if terminated: + break + rewards.append(ep_reward) + steps.append(ep_step) + logger.info(f'Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step:d}, Epislon: {agent.epsilon:.3f}') + logger.info("Finish training!") + return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + def test(self,cfg,env,agent,logger): + logger.info("Start testing!") + logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + rewards = [] # record rewards for all episodes + steps = [] # record steps for all episodes + for i_ep in range(cfg.test_eps): + ep_reward = 0 # reward per episode + ep_step = 0 + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.predict_action(state) # predict action + next_state, reward, terminated, _ = env.step(action) + state = next_state + ep_reward += reward + ep_step += 1 + if terminated: + break + rewards.append(ep_reward) + steps.append(ep_step) + logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step:d}") + logger.info("Finish testing!") + return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + +if __name__ == "__main__": + main = Main() + main.run() + + + + diff --git a/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/config.yaml b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/config.yaml new file mode 100644 index 0000000..f1c252d --- /dev/null +++ b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: CliffWalking-v0 + load_checkpoint: true + load_path: Train_CliffWalking-v0_Sarsa_20221030-021146 + max_steps: 200 + mode: test + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/logs/log.txt b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/logs/log.txt new file mode 100644 index 0000000..29ed4a8 --- /dev/null +++ b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/logs/log.txt @@ -0,0 +1,24 @@ +2022-10-30 02:12:06 - r - INFO: - n_states: 48, n_actions: 4 +2022-10-30 02:12:06 - r - INFO: - Start testing! +2022-10-30 02:12:06 - r - INFO: - Env: CliffWalking-v0, Algorithm: Sarsa, Device: cpu +2022-10-30 02:12:06 - r - INFO: - Episode: 1/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 2/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 3/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 4/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 5/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 6/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 7/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 8/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 9/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 10/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 11/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 12/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 13/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 14/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 15/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 16/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 17/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 18/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 19/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Episode: 20/20, Reward: -15.00, Steps:15 +2022-10-30 02:12:06 - r - INFO: - Finish testing! diff --git a/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/models/checkpoint.pkl b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/models/checkpoint.pkl new file mode 100644 index 0000000..d226d4c Binary files /dev/null and b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/models/checkpoint.pkl differ diff --git a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/testing_curve.png b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/results/learning_curve.png similarity index 100% rename from projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/testing_curve.png rename to projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/results/learning_curve.png diff --git a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/testing_results.csv b/projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/results/res.csv similarity index 100% rename from projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/testing_results.csv rename to projects/codes/Sarsa/Test_CliffWalking-v0_Sarsa_20221030-021206/results/res.csv diff --git a/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/config.yaml b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/config.yaml new file mode 100644 index 0000000..7c1b16f --- /dev/null +++ b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: Racetrack-v0 + load_checkpoint: true + load_path: Train_Racetrack-v0_Sarsa_20221030-021315 + max_steps: 200 + mode: test + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 200 + epsilon_end: 0.01 + epsilon_start: 0.9 + gamma: 0.99 + lr: 0.1 diff --git a/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/logs/log.txt b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/logs/log.txt new file mode 100644 index 0000000..7fd4614 --- /dev/null +++ b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/logs/log.txt @@ -0,0 +1,24 @@ +2022-10-30 02:13:47 - r - INFO: - n_states: 4, n_actions: 9 +2022-10-30 02:13:47 - r - INFO: - Start testing! +2022-10-30 02:13:47 - r - INFO: - Env: Racetrack-v0, Algorithm: Sarsa, Device: cpu +2022-10-30 02:13:47 - r - INFO: - Episode: 1/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 2/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 3/20, Reward: 2.00, Steps:8 +2022-10-30 02:13:47 - r - INFO: - Episode: 4/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 5/20, Reward: -12.00, Steps:12 +2022-10-30 02:13:47 - r - INFO: - Episode: 6/20, Reward: -49.00, Steps:29 +2022-10-30 02:13:47 - r - INFO: - Episode: 7/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 8/20, Reward: -17.00, Steps:17 +2022-10-30 02:13:47 - r - INFO: - Episode: 9/20, Reward: 4.00, Steps:6 +2022-10-30 02:13:47 - r - INFO: - Episode: 10/20, Reward: -17.00, Steps:17 +2022-10-30 02:13:47 - r - INFO: - Episode: 11/20, Reward: 2.00, Steps:8 +2022-10-30 02:13:47 - r - INFO: - Episode: 12/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 13/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 14/20, Reward: 2.00, Steps:8 +2022-10-30 02:13:47 - r - INFO: - Episode: 15/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 16/20, Reward: -34.00, Steps:24 +2022-10-30 02:13:47 - r - INFO: - Episode: 17/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Episode: 18/20, Reward: 5.00, Steps:5 +2022-10-30 02:13:47 - r - INFO: - Episode: 19/20, Reward: 5.00, Steps:5 +2022-10-30 02:13:47 - r - INFO: - Episode: 20/20, Reward: 3.00, Steps:7 +2022-10-30 02:13:47 - r - INFO: - Finish testing! diff --git a/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/models/checkpoint.pkl b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/models/checkpoint.pkl new file mode 100644 index 0000000..d950b3f Binary files /dev/null and b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/models/checkpoint.pkl differ diff --git a/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/results/learning_curve.png b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/results/learning_curve.png new file mode 100644 index 0000000..fde014e Binary files /dev/null and b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/results/learning_curve.png differ diff --git a/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/results/res.csv b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/results/res.csv new file mode 100644 index 0000000..5d08ed0 --- /dev/null +++ b/projects/codes/Sarsa/Test_Racetrack-v0_Sarsa_20221030-021347/results/res.csv @@ -0,0 +1,21 @@ +episodes,rewards,steps +0,3,7 +1,3,7 +2,2,8 +3,3,7 +4,-12,12 +5,-49,29 +6,3,7 +7,-17,17 +8,4,6 +9,-17,17 +10,2,8 +11,3,7 +12,3,7 +13,2,8 +14,3,7 +15,-34,24 +16,3,7 +17,5,5 +18,5,5 +19,3,7 diff --git a/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/config.yaml b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/config.yaml new file mode 100644 index 0000000..4d61198 --- /dev/null +++ b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: CliffWalking-v0 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + mode: train + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/logs/log.txt b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/logs/log.txt new file mode 100644 index 0000000..76df5b3 --- /dev/null +++ b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/logs/log.txt @@ -0,0 +1,804 @@ +2022-10-30 02:11:46 - r - INFO: - n_states: 48, n_actions: 4 +2022-10-30 02:11:46 - r - INFO: - Start training! +2022-10-30 02:11:46 - r - INFO: - Env: CliffWalking-v0, Algorithm: Sarsa, Device: cpu +2022-10-30 02:11:46 - r - INFO: - Episode: 1/800, Reward: -1091.00, Steps:200, Epislon: 0.491 +2022-10-30 02:11:46 - r - INFO: - Episode: 2/800, Reward: -320.00, Steps:122, Epislon: 0.329 +2022-10-30 02:11:46 - r - INFO: - Episode: 3/800, Reward: -794.00, Steps:200, Epislon: 0.173 +2022-10-30 02:11:46 - r - INFO: - Episode: 4/800, Reward: -596.00, Steps:200, Epislon: 0.094 +2022-10-30 02:11:46 - r - INFO: - Episode: 5/800, Reward: -398.00, Steps:200, Epislon: 0.053 +2022-10-30 02:11:46 - r - INFO: - Episode: 6/800, Reward: -59.00, Steps:59, Epislon: 0.045 +2022-10-30 02:11:46 - r - INFO: - Episode: 7/800, Reward: -299.00, Steps:200, Epislon: 0.028 +2022-10-30 02:11:46 - r - INFO: - Episode: 8/800, Reward: -82.00, Steps:82, Epislon: 0.024 +2022-10-30 02:11:46 - r - INFO: - Episode: 9/800, Reward: -125.00, Steps:125, Epislon: 0.019 +2022-10-30 02:11:46 - r - INFO: - Episode: 10/800, Reward: -75.00, Steps:75, Epislon: 0.017 +2022-10-30 02:11:46 - r - INFO: - Episode: 11/800, Reward: -285.00, Steps:186, Epislon: 0.014 +2022-10-30 02:11:46 - r - INFO: - Episode: 12/800, Reward: -103.00, Steps:103, Epislon: 0.013 +2022-10-30 02:11:46 - r - INFO: - Episode: 13/800, Reward: -103.00, Steps:103, Epislon: 0.012 +2022-10-30 02:11:46 - r - INFO: - Episode: 14/800, Reward: -131.00, Steps:131, Epislon: 0.011 +2022-10-30 02:11:46 - r - INFO: - Episode: 15/800, Reward: -53.00, Steps:53, Epislon: 0.011 +2022-10-30 02:11:46 - r - INFO: - Episode: 16/800, Reward: -113.00, Steps:113, Epislon: 0.011 +2022-10-30 02:11:46 - r - INFO: - Episode: 17/800, Reward: -125.00, Steps:125, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 18/800, Reward: -95.00, Steps:95, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 19/800, Reward: -97.00, Steps:97, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 20/800, Reward: -145.00, Steps:145, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 21/800, Reward: -89.00, Steps:89, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 22/800, Reward: -97.00, Steps:97, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 23/800, Reward: -115.00, Steps:115, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 24/800, Reward: -121.00, Steps:121, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 25/800, Reward: -53.00, Steps:53, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 26/800, Reward: -111.00, Steps:111, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 27/800, Reward: -97.00, Steps:97, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 28/800, Reward: -206.00, Steps:107, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 29/800, Reward: -147.00, Steps:147, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 30/800, Reward: -36.00, Steps:36, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 31/800, Reward: -216.00, Steps:117, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 32/800, Reward: -103.00, Steps:103, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 33/800, Reward: -87.00, Steps:87, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 34/800, Reward: -80.00, Steps:80, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 35/800, Reward: -73.00, Steps:73, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 36/800, Reward: -83.00, Steps:83, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 37/800, Reward: -143.00, Steps:44, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 38/800, Reward: -241.00, Steps:142, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 39/800, Reward: -77.00, Steps:77, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 40/800, Reward: -49.00, Steps:49, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 41/800, Reward: -87.00, Steps:87, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 42/800, Reward: -47.00, Steps:47, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 43/800, Reward: -89.00, Steps:89, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 44/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 45/800, Reward: -192.00, Steps:93, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 46/800, Reward: -85.00, Steps:85, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 47/800, Reward: -55.00, Steps:55, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 48/800, Reward: -59.00, Steps:59, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 49/800, Reward: -60.00, Steps:60, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 50/800, Reward: -50.00, Steps:50, Epislon: 0.010 +2022-10-30 02:11:46 - r - INFO: - Episode: 51/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 52/800, Reward: -101.00, Steps:101, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 53/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 54/800, Reward: -70.00, Steps:70, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 55/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 56/800, Reward: -47.00, Steps:47, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 57/800, Reward: -80.00, Steps:80, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 58/800, Reward: -61.00, Steps:61, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 59/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 60/800, Reward: -73.00, Steps:73, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 61/800, Reward: -54.00, Steps:54, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 62/800, Reward: -37.00, Steps:37, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 63/800, Reward: -65.00, Steps:65, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 64/800, Reward: -41.00, Steps:41, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 65/800, Reward: -81.00, Steps:81, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 66/800, Reward: -39.00, Steps:39, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 67/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 68/800, Reward: -61.00, Steps:61, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 69/800, Reward: -57.00, Steps:57, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 70/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 71/800, Reward: -59.00, Steps:59, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 72/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 73/800, Reward: -51.00, Steps:51, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 74/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 75/800, Reward: -69.00, Steps:69, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 76/800, Reward: -41.00, Steps:41, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 77/800, Reward: -194.00, Steps:95, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 78/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 79/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 80/800, Reward: -81.00, Steps:81, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 81/800, Reward: -65.00, Steps:65, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 82/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 83/800, Reward: -47.00, Steps:47, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 84/800, Reward: -53.00, Steps:53, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 85/800, Reward: -165.00, Steps:66, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 86/800, Reward: -69.00, Steps:69, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 87/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 88/800, Reward: -56.00, Steps:56, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 89/800, Reward: -164.00, Steps:65, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 90/800, Reward: -45.00, Steps:45, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 91/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 92/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 93/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 94/800, Reward: -69.00, Steps:69, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 95/800, Reward: -33.00, Steps:33, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 96/800, Reward: -57.00, Steps:57, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 97/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 98/800, Reward: -55.00, Steps:55, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 99/800, Reward: -61.00, Steps:61, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 100/800, Reward: -162.00, Steps:63, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 101/800, Reward: -55.00, Steps:55, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 102/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 103/800, Reward: -53.00, Steps:53, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 104/800, Reward: -39.00, Steps:39, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 105/800, Reward: -55.00, Steps:55, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 106/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 107/800, Reward: -33.00, Steps:33, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 108/800, Reward: -49.00, Steps:49, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 109/800, Reward: -65.00, Steps:65, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 110/800, Reward: -45.00, Steps:45, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 111/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 112/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 113/800, Reward: -51.00, Steps:51, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 114/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 115/800, Reward: -47.00, Steps:47, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 116/800, Reward: -41.00, Steps:41, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 117/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 118/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 119/800, Reward: -180.00, Steps:81, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 120/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 121/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 122/800, Reward: -47.00, Steps:47, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 123/800, Reward: -65.00, Steps:65, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 124/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 125/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 126/800, Reward: -49.00, Steps:49, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 127/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 128/800, Reward: -45.00, Steps:45, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 129/800, Reward: -49.00, Steps:49, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 130/800, Reward: -37.00, Steps:37, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 131/800, Reward: -49.00, Steps:49, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 132/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 133/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 134/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 135/800, Reward: -37.00, Steps:37, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 136/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 137/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 138/800, Reward: -51.00, Steps:51, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 139/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 140/800, Reward: -51.00, Steps:51, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 141/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 142/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 143/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 144/800, Reward: -41.00, Steps:41, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 145/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 146/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 147/800, Reward: -47.00, Steps:47, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 148/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 149/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 150/800, Reward: -45.00, Steps:45, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 151/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 152/800, Reward: -33.00, Steps:33, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 153/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 154/800, Reward: -148.00, Steps:49, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 155/800, Reward: -41.00, Steps:41, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 156/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 157/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 158/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 159/800, Reward: -33.00, Steps:33, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 160/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 161/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 162/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 163/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 164/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 165/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 166/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 167/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 168/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 169/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 170/800, Reward: -41.00, Steps:41, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 171/800, Reward: -39.00, Steps:39, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 172/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 173/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 174/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 175/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 176/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 177/800, Reward: -155.00, Steps:56, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 178/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 179/800, Reward: -37.00, Steps:37, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 180/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 181/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 182/800, Reward: -39.00, Steps:39, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 183/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 184/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 185/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 186/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 187/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 188/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 189/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 190/800, Reward: -42.00, Steps:42, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 191/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 192/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 193/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 194/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 195/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 196/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 197/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 198/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 199/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 200/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 201/800, Reward: -33.00, Steps:33, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 202/800, Reward: -37.00, Steps:37, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 203/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 204/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 205/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 206/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 207/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 208/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 209/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 210/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 211/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 212/800, Reward: -37.00, Steps:37, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 213/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 214/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 215/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 216/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 217/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 218/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 219/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 220/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 221/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 222/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 223/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 224/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 225/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 226/800, Reward: -43.00, Steps:43, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 227/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 228/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 229/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 230/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 231/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 232/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 233/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 234/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 235/800, Reward: -31.00, Steps:31, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 236/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 237/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 238/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 239/800, Reward: -30.00, Steps:30, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 240/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 241/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 242/800, Reward: -24.00, Steps:24, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 243/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 244/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 245/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 246/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 247/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 248/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 249/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 250/800, Reward: -29.00, Steps:29, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 251/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 252/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 253/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 254/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 255/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 256/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 257/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 258/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 259/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 260/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 261/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 262/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 263/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 264/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 265/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 266/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 267/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 268/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 269/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 270/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 271/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 272/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 273/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 274/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 275/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 276/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 277/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 278/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 279/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 280/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 281/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 282/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 283/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 284/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 285/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 286/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 287/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 288/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 289/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 290/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 291/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 292/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 293/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 294/800, Reward: -120.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 295/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 296/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 297/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 298/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 299/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 300/800, Reward: -35.00, Steps:35, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 301/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 302/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 303/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 304/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 305/800, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 306/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 307/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 308/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 309/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 310/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 311/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 312/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 313/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 314/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 315/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 316/800, Reward: -32.00, Steps:32, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 317/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 318/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 319/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 320/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 321/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 322/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 323/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 324/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 325/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 326/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 327/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 328/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 329/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 330/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 331/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 332/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 333/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 334/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 335/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 336/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 337/800, Reward: -26.00, Steps:26, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 338/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 339/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 340/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 341/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 342/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 343/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 344/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 345/800, Reward: -27.00, Steps:27, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 346/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 347/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 348/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 349/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 350/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 351/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 352/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 353/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 354/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 355/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 356/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 357/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 358/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 359/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 360/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 361/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 362/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 363/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 364/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 365/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 366/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 367/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 368/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 369/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 370/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 371/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 372/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 373/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 374/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 375/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 376/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 377/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 378/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 379/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 380/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 381/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 382/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 383/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 384/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 385/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 386/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 387/800, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 388/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 389/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 390/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 391/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 392/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 393/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 394/800, Reward: -122.00, Steps:23, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 395/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 396/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 397/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 398/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 399/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 400/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 401/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 402/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 403/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 404/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 405/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 406/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 407/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 408/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 409/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 410/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 411/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 412/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 413/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 414/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 415/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 416/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 417/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 418/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 419/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 420/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 421/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 422/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 423/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 424/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 425/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 426/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 427/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 428/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 429/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 430/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 431/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 432/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 433/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 434/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 435/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 436/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 437/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 438/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 439/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 440/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 441/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 442/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 443/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 444/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 445/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 446/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 447/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 448/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 449/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 450/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 451/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 452/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 453/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 454/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 455/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 456/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 457/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 458/800, Reward: -22.00, Steps:22, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 459/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 460/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 461/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 462/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 463/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 464/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 465/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 466/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 467/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 468/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 469/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 470/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 471/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 472/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 473/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 474/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 475/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 476/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 477/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 478/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 479/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 480/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 481/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 482/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 483/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 484/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 485/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 486/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 487/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 488/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 489/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 490/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 491/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 492/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 493/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 494/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 495/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 496/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 497/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 498/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 499/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 500/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 501/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 502/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 503/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 504/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 505/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 506/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 507/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 508/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 509/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 510/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 511/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 512/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 513/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 514/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 515/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 516/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 517/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 518/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 519/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 520/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 521/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 522/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 523/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 524/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 525/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 526/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 527/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 528/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 529/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 530/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 531/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 532/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 533/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 534/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 535/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 536/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 537/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 538/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 539/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 540/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 541/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 542/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 543/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 544/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 545/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 546/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 547/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 548/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 549/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 550/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 551/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 552/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 553/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 554/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 555/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 556/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 557/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 558/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:47 - r - INFO: - Episode: 559/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 560/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 561/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 562/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 563/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 564/800, Reward: -20.00, Steps:20, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 565/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 566/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 567/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 568/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 569/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 570/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 571/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 572/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 573/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 574/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 575/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 576/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 577/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 578/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 579/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 580/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 581/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 582/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 583/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 584/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 585/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 586/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 587/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 588/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 589/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 590/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 591/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 592/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 593/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 594/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 595/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 596/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 597/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 598/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 599/800, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 600/800, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 601/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 602/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 603/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 604/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 605/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 606/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 607/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 608/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 609/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 610/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 611/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 612/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 613/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 614/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 615/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 616/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 617/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 618/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 619/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 620/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 621/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 622/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 623/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 624/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 625/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 626/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 627/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 628/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 629/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 630/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 631/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 632/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 633/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 634/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 635/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 636/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 637/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 638/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 639/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 640/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 641/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 642/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 643/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 644/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 645/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 646/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 647/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 648/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 649/800, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 650/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 651/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 652/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 653/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 654/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 655/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 656/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 657/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 658/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 659/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 660/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 661/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 662/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 663/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 664/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 665/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 666/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 667/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 668/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 669/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 670/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 671/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 672/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 673/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 674/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 675/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 676/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 677/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 678/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 679/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 680/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 681/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 682/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 683/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 684/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 685/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 686/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 687/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 688/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 689/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 690/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 691/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 692/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 693/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 694/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 695/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 696/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 697/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 698/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 699/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 700/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 701/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 702/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 703/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 704/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 705/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 706/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 707/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 708/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 709/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 710/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 711/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 712/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 713/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 714/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 715/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 716/800, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 717/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 718/800, Reward: -117.00, Steps:18, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 719/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 720/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 721/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 722/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 723/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 724/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 725/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 726/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 727/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 728/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 729/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 730/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 731/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 732/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 733/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 734/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 735/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 736/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 737/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 738/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 739/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 740/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 741/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 742/800, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 743/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 744/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 745/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 746/800, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 747/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 748/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 749/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 750/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 751/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 752/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 753/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 754/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 755/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 756/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 757/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 758/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 759/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 760/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 761/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 762/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 763/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 764/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 765/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 766/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 767/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 768/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 769/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 770/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 771/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 772/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 773/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 774/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 775/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 776/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 777/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 778/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 779/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 780/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 781/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 782/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 783/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 784/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 785/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 786/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 787/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 788/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 789/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 790/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 791/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 792/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 793/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 794/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 795/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 796/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 797/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 798/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 799/800, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Episode: 800/800, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:11:48 - r - INFO: - Finish training! diff --git a/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/models/checkpoint.pkl b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/models/checkpoint.pkl new file mode 100644 index 0000000..d226d4c Binary files /dev/null and b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/models/checkpoint.pkl differ diff --git a/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/results/learning_curve.png b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/results/learning_curve.png new file mode 100644 index 0000000..3c4dd0f Binary files /dev/null and b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/results/learning_curve.png differ diff --git a/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/results/res.csv b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/results/res.csv new file mode 100644 index 0000000..16858a4 --- /dev/null +++ b/projects/codes/Sarsa/Train_CliffWalking-v0_Sarsa_20221030-021146/results/res.csv @@ -0,0 +1,801 @@ +episodes,rewards,steps +0,-1091,200 +1,-320,122 +2,-794,200 +3,-596,200 +4,-398,200 +5,-59,59 +6,-299,200 +7,-82,82 +8,-125,125 +9,-75,75 +10,-285,186 +11,-103,103 +12,-103,103 +13,-131,131 +14,-53,53 +15,-113,113 +16,-125,125 +17,-95,95 +18,-97,97 +19,-145,145 +20,-89,89 +21,-97,97 +22,-115,115 +23,-121,121 +24,-53,53 +25,-111,111 +26,-97,97 +27,-206,107 +28,-147,147 +29,-36,36 +30,-216,117 +31,-103,103 +32,-87,87 +33,-80,80 +34,-73,73 +35,-83,83 +36,-143,44 +37,-241,142 +38,-77,77 +39,-49,49 +40,-87,87 +41,-47,47 +42,-89,89 +43,-31,31 +44,-192,93 +45,-85,85 +46,-55,55 +47,-59,59 +48,-60,60 +49,-50,50 +50,-23,23 +51,-101,101 +52,-43,43 +53,-70,70 +54,-35,35 +55,-47,47 +56,-80,80 +57,-61,61 +58,-35,35 +59,-73,73 +60,-54,54 +61,-37,37 +62,-65,65 +63,-41,41 +64,-81,81 +65,-39,39 +66,-35,35 +67,-61,61 +68,-57,57 +69,-43,43 +70,-59,59 +71,-43,43 +72,-51,51 +73,-43,43 +74,-69,69 +75,-41,41 +76,-194,95 +77,-35,35 +78,-35,35 +79,-81,81 +80,-65,65 +81,-35,35 +82,-47,47 +83,-53,53 +84,-165,66 +85,-69,69 +86,-35,35 +87,-56,56 +88,-164,65 +89,-45,45 +90,-43,43 +91,-43,43 +92,-29,29 +93,-69,69 +94,-33,33 +95,-57,57 +96,-29,29 +97,-55,55 +98,-61,61 +99,-162,63 +100,-55,55 +101,-31,31 +102,-53,53 +103,-39,39 +104,-55,55 +105,-25,25 +106,-33,33 +107,-49,49 +108,-65,65 +109,-45,45 +110,-29,29 +111,-25,25 +112,-51,51 +113,-43,43 +114,-47,47 +115,-41,41 +116,-27,27 +117,-31,31 +118,-180,81 +119,-43,43 +120,-25,25 +121,-47,47 +122,-65,65 +123,-29,29 +124,-31,31 +125,-49,49 +126,-25,25 +127,-45,45 +128,-49,49 +129,-37,37 +130,-49,49 +131,-25,25 +132,-29,29 +133,-35,35 +134,-37,37 +135,-43,43 +136,-31,31 +137,-51,51 +138,-25,25 +139,-51,51 +140,-21,21 +141,-35,35 +142,-31,31 +143,-41,41 +144,-29,29 +145,-27,27 +146,-47,47 +147,-27,27 +148,-23,23 +149,-45,45 +150,-31,31 +151,-33,33 +152,-31,31 +153,-148,49 +154,-41,41 +155,-25,25 +156,-29,29 +157,-31,31 +158,-33,33 +159,-27,27 +160,-27,27 +161,-29,29 +162,-27,27 +163,-27,27 +164,-23,23 +165,-35,35 +166,-21,21 +167,-23,23 +168,-23,23 +169,-41,41 +170,-39,39 +171,-21,21 +172,-25,25 +173,-23,23 +174,-31,31 +175,-21,21 +176,-155,56 +177,-21,21 +178,-37,37 +179,-17,17 +180,-19,19 +181,-39,39 +182,-25,25 +183,-25,25 +184,-19,19 +185,-29,29 +186,-29,29 +187,-25,25 +188,-25,25 +189,-42,42 +190,-21,21 +191,-21,21 +192,-25,25 +193,-29,29 +194,-15,15 +195,-21,21 +196,-17,17 +197,-29,29 +198,-25,25 +199,-15,15 +200,-33,33 +201,-37,37 +202,-17,17 +203,-29,29 +204,-17,17 +205,-25,25 +206,-23,23 +207,-25,25 +208,-25,25 +209,-25,25 +210,-21,21 +211,-37,37 +212,-17,17 +213,-17,17 +214,-23,23 +215,-31,31 +216,-21,21 +217,-21,21 +218,-21,21 +219,-19,19 +220,-17,17 +221,-27,27 +222,-23,23 +223,-15,15 +224,-19,19 +225,-43,43 +226,-15,15 +227,-25,25 +228,-19,19 +229,-19,19 +230,-19,19 +231,-19,19 +232,-21,21 +233,-23,23 +234,-31,31 +235,-23,23 +236,-19,19 +237,-29,29 +238,-30,30 +239,-19,19 +240,-17,17 +241,-24,24 +242,-15,15 +243,-23,23 +244,-21,21 +245,-15,15 +246,-29,29 +247,-19,19 +248,-17,17 +249,-29,29 +250,-21,21 +251,-25,25 +252,-25,25 +253,-19,19 +254,-25,25 +255,-21,21 +256,-19,19 +257,-19,19 +258,-15,15 +259,-21,21 +260,-19,19 +261,-23,23 +262,-27,27 +263,-19,19 +264,-21,21 +265,-21,21 +266,-23,23 +267,-17,17 +268,-25,25 +269,-27,27 +270,-19,19 +271,-19,19 +272,-21,21 +273,-15,15 +274,-21,21 +275,-17,17 +276,-15,15 +277,-23,23 +278,-17,17 +279,-19,19 +280,-23,23 +281,-27,27 +282,-17,17 +283,-23,23 +284,-19,19 +285,-17,17 +286,-17,17 +287,-15,15 +288,-21,21 +289,-15,15 +290,-21,21 +291,-19,19 +292,-17,17 +293,-120,21 +294,-21,21 +295,-15,15 +296,-19,19 +297,-15,15 +298,-15,15 +299,-35,35 +300,-21,21 +301,-21,21 +302,-15,15 +303,-15,15 +304,-23,23 +305,-17,17 +306,-21,21 +307,-17,17 +308,-15,15 +309,-15,15 +310,-15,15 +311,-17,17 +312,-19,19 +313,-25,25 +314,-19,19 +315,-32,32 +316,-15,15 +317,-17,17 +318,-21,21 +319,-15,15 +320,-17,17 +321,-19,19 +322,-17,17 +323,-17,17 +324,-17,17 +325,-17,17 +326,-19,19 +327,-15,15 +328,-15,15 +329,-21,21 +330,-19,19 +331,-15,15 +332,-17,17 +333,-17,17 +334,-15,15 +335,-19,19 +336,-26,26 +337,-17,17 +338,-15,15 +339,-21,21 +340,-17,17 +341,-15,15 +342,-19,19 +343,-17,17 +344,-27,27 +345,-15,15 +346,-17,17 +347,-15,15 +348,-17,17 +349,-17,17 +350,-19,19 +351,-15,15 +352,-15,15 +353,-15,15 +354,-15,15 +355,-17,17 +356,-17,17 +357,-15,15 +358,-19,19 +359,-15,15 +360,-17,17 +361,-17,17 +362,-19,19 +363,-17,17 +364,-17,17 +365,-21,21 +366,-17,17 +367,-15,15 +368,-17,17 +369,-21,21 +370,-19,19 +371,-17,17 +372,-15,15 +373,-15,15 +374,-25,25 +375,-15,15 +376,-15,15 +377,-17,17 +378,-17,17 +379,-17,17 +380,-15,15 +381,-15,15 +382,-15,15 +383,-15,15 +384,-17,17 +385,-17,17 +386,-25,25 +387,-17,17 +388,-15,15 +389,-15,15 +390,-17,17 +391,-15,15 +392,-15,15 +393,-122,23 +394,-15,15 +395,-15,15 +396,-15,15 +397,-15,15 +398,-21,21 +399,-15,15 +400,-17,17 +401,-17,17 +402,-17,17 +403,-15,15 +404,-15,15 +405,-15,15 +406,-17,17 +407,-15,15 +408,-15,15 +409,-17,17 +410,-15,15 +411,-15,15 +412,-17,17 +413,-19,19 +414,-17,17 +415,-17,17 +416,-17,17 +417,-15,15 +418,-15,15 +419,-17,17 +420,-15,15 +421,-15,15 +422,-15,15 +423,-21,21 +424,-15,15 +425,-15,15 +426,-17,17 +427,-15,15 +428,-17,17 +429,-15,15 +430,-15,15 +431,-15,15 +432,-15,15 +433,-15,15 +434,-21,21 +435,-15,15 +436,-15,15 +437,-17,17 +438,-15,15 +439,-15,15 +440,-15,15 +441,-17,17 +442,-15,15 +443,-15,15 +444,-17,17 +445,-15,15 +446,-17,17 +447,-17,17 +448,-15,15 +449,-17,17 +450,-15,15 +451,-17,17 +452,-15,15 +453,-15,15 +454,-15,15 +455,-15,15 +456,-15,15 +457,-22,22 +458,-15,15 +459,-15,15 +460,-15,15 +461,-15,15 +462,-15,15 +463,-15,15 +464,-15,15 +465,-15,15 +466,-15,15 +467,-15,15 +468,-15,15 +469,-15,15 +470,-15,15 +471,-17,17 +472,-21,21 +473,-15,15 +474,-15,15 +475,-15,15 +476,-15,15 +477,-17,17 +478,-15,15 +479,-17,17 +480,-17,17 +481,-15,15 +482,-15,15 +483,-15,15 +484,-17,17 +485,-21,21 +486,-15,15 +487,-15,15 +488,-15,15 +489,-15,15 +490,-15,15 +491,-17,17 +492,-15,15 +493,-17,17 +494,-19,19 +495,-15,15 +496,-15,15 +497,-15,15 +498,-15,15 +499,-15,15 +500,-15,15 +501,-15,15 +502,-15,15 +503,-15,15 +504,-15,15 +505,-15,15 +506,-15,15 +507,-15,15 +508,-17,17 +509,-15,15 +510,-15,15 +511,-15,15 +512,-15,15 +513,-15,15 +514,-15,15 +515,-15,15 +516,-17,17 +517,-15,15 +518,-15,15 +519,-15,15 +520,-15,15 +521,-15,15 +522,-15,15 +523,-15,15 +524,-15,15 +525,-15,15 +526,-15,15 +527,-15,15 +528,-15,15 +529,-15,15 +530,-15,15 +531,-17,17 +532,-17,17 +533,-15,15 +534,-17,17 +535,-15,15 +536,-15,15 +537,-15,15 +538,-15,15 +539,-15,15 +540,-15,15 +541,-15,15 +542,-19,19 +543,-15,15 +544,-15,15 +545,-15,15 +546,-17,17 +547,-15,15 +548,-15,15 +549,-15,15 +550,-15,15 +551,-15,15 +552,-15,15 +553,-15,15 +554,-15,15 +555,-15,15 +556,-15,15 +557,-15,15 +558,-15,15 +559,-15,15 +560,-15,15 +561,-15,15 +562,-15,15 +563,-20,20 +564,-17,17 +565,-15,15 +566,-15,15 +567,-15,15 +568,-15,15 +569,-15,15 +570,-17,17 +571,-17,17 +572,-15,15 +573,-15,15 +574,-15,15 +575,-15,15 +576,-17,17 +577,-15,15 +578,-15,15 +579,-15,15 +580,-15,15 +581,-15,15 +582,-15,15 +583,-17,17 +584,-15,15 +585,-15,15 +586,-15,15 +587,-15,15 +588,-15,15 +589,-15,15 +590,-15,15 +591,-15,15 +592,-15,15 +593,-15,15 +594,-17,17 +595,-15,15 +596,-15,15 +597,-15,15 +598,-16,16 +599,-16,16 +600,-15,15 +601,-15,15 +602,-15,15 +603,-15,15 +604,-15,15 +605,-17,17 +606,-15,15 +607,-15,15 +608,-15,15 +609,-15,15 +610,-15,15 +611,-15,15 +612,-15,15 +613,-15,15 +614,-15,15 +615,-15,15 +616,-15,15 +617,-15,15 +618,-15,15 +619,-15,15 +620,-15,15 +621,-15,15 +622,-15,15 +623,-15,15 +624,-15,15 +625,-15,15 +626,-15,15 +627,-15,15 +628,-15,15 +629,-15,15 +630,-15,15 +631,-15,15 +632,-15,15 +633,-21,21 +634,-15,15 +635,-15,15 +636,-15,15 +637,-15,15 +638,-15,15 +639,-15,15 +640,-15,15 +641,-15,15 +642,-15,15 +643,-15,15 +644,-15,15 +645,-15,15 +646,-17,17 +647,-15,15 +648,-21,21 +649,-15,15 +650,-15,15 +651,-15,15 +652,-15,15 +653,-17,17 +654,-15,15 +655,-15,15 +656,-15,15 +657,-15,15 +658,-15,15 +659,-15,15 +660,-15,15 +661,-15,15 +662,-15,15 +663,-15,15 +664,-17,17 +665,-15,15 +666,-15,15 +667,-15,15 +668,-15,15 +669,-15,15 +670,-17,17 +671,-15,15 +672,-15,15 +673,-15,15 +674,-15,15 +675,-15,15 +676,-15,15 +677,-17,17 +678,-15,15 +679,-15,15 +680,-15,15 +681,-15,15 +682,-15,15 +683,-15,15 +684,-15,15 +685,-15,15 +686,-15,15 +687,-15,15 +688,-15,15 +689,-15,15 +690,-15,15 +691,-15,15 +692,-15,15 +693,-15,15 +694,-15,15 +695,-15,15 +696,-15,15 +697,-15,15 +698,-15,15 +699,-15,15 +700,-15,15 +701,-15,15 +702,-15,15 +703,-17,17 +704,-15,15 +705,-15,15 +706,-15,15 +707,-15,15 +708,-15,15 +709,-15,15 +710,-17,17 +711,-15,15 +712,-15,15 +713,-15,15 +714,-15,15 +715,-16,16 +716,-15,15 +717,-117,18 +718,-15,15 +719,-17,17 +720,-15,15 +721,-15,15 +722,-15,15 +723,-15,15 +724,-15,15 +725,-15,15 +726,-15,15 +727,-15,15 +728,-15,15 +729,-15,15 +730,-15,15 +731,-15,15 +732,-15,15 +733,-15,15 +734,-15,15 +735,-15,15 +736,-15,15 +737,-15,15 +738,-15,15 +739,-15,15 +740,-15,15 +741,-16,16 +742,-15,15 +743,-17,17 +744,-15,15 +745,-19,19 +746,-15,15 +747,-15,15 +748,-15,15 +749,-17,17 +750,-15,15 +751,-15,15 +752,-17,17 +753,-15,15 +754,-15,15 +755,-15,15 +756,-15,15 +757,-17,17 +758,-15,15 +759,-15,15 +760,-15,15 +761,-17,17 +762,-15,15 +763,-15,15 +764,-15,15 +765,-15,15 +766,-15,15 +767,-17,17 +768,-15,15 +769,-15,15 +770,-15,15 +771,-15,15 +772,-15,15 +773,-15,15 +774,-17,17 +775,-15,15 +776,-15,15 +777,-15,15 +778,-15,15 +779,-15,15 +780,-15,15 +781,-15,15 +782,-15,15 +783,-15,15 +784,-15,15 +785,-15,15 +786,-15,15 +787,-15,15 +788,-15,15 +789,-15,15 +790,-15,15 +791,-15,15 +792,-17,17 +793,-15,15 +794,-15,15 +795,-15,15 +796,-15,15 +797,-15,15 +798,-17,17 +799,-15,15 diff --git a/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/config.yaml b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/config.yaml new file mode 100644 index 0000000..79e3694 --- /dev/null +++ b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/config.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: Racetrack-v0 + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + mode: train + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 200 + epsilon_end: 0.01 + epsilon_start: 0.9 + gamma: 0.99 + lr: 0.1 diff --git a/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/logs/log.txt b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/logs/log.txt new file mode 100644 index 0000000..ffa79ca --- /dev/null +++ b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/logs/log.txt @@ -0,0 +1,404 @@ +2022-10-30 02:13:15 - r - INFO: - n_states: 4, n_actions: 9 +2022-10-30 02:13:15 - r - INFO: - Start training! +2022-10-30 02:13:15 - r - INFO: - Env: Racetrack-v0, Algorithm: Sarsa, Device: cpu +2022-10-30 02:13:15 - r - INFO: - Episode: 1/400, Reward: -870.00, Steps:200, Epislon: 0.336 +2022-10-30 02:13:15 - r - INFO: - Episode: 2/400, Reward: -740.00, Steps:200, Epislon: 0.129 +2022-10-30 02:13:15 - r - INFO: - Episode: 3/400, Reward: -710.00, Steps:200, Epislon: 0.054 +2022-10-30 02:13:15 - r - INFO: - Episode: 4/400, Reward: -600.00, Steps:200, Epislon: 0.026 +2022-10-30 02:13:15 - r - INFO: - Episode: 5/400, Reward: -580.00, Steps:200, Epislon: 0.016 +2022-10-30 02:13:15 - r - INFO: - Episode: 6/400, Reward: -620.00, Steps:200, Epislon: 0.012 +2022-10-30 02:13:16 - r - INFO: - Episode: 7/400, Reward: -590.00, Steps:200, Epislon: 0.011 +2022-10-30 02:13:16 - r - INFO: - Episode: 8/400, Reward: -590.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 9/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 10/400, Reward: -570.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 11/400, Reward: -580.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 12/400, Reward: -580.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 13/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 14/400, Reward: -540.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 15/400, Reward: -510.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 16/400, Reward: -570.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 17/400, Reward: -560.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 18/400, Reward: -540.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 19/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 20/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 21/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 22/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 23/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 24/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 25/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 26/400, Reward: -510.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 27/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:16 - r - INFO: - Episode: 28/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 29/400, Reward: -560.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 30/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 31/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 32/400, Reward: -359.00, Steps:149, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 33/400, Reward: -470.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 34/400, Reward: -510.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 35/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 36/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 37/400, Reward: -540.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 38/400, Reward: -560.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 39/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 40/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 41/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 42/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 43/400, Reward: -540.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 44/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 45/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 46/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 47/400, Reward: -550.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 48/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 49/400, Reward: -540.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 50/400, Reward: -420.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 51/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:17 - r - INFO: - Episode: 52/400, Reward: -510.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 53/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 54/400, Reward: -460.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 55/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 56/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 57/400, Reward: -470.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 58/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 59/400, Reward: -470.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 60/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 61/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 62/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 63/400, Reward: -450.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 64/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 65/400, Reward: -420.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 66/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 67/400, Reward: -440.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 68/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 69/400, Reward: -188.00, Steps:88, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 70/400, Reward: -327.00, Steps:167, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 71/400, Reward: -530.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 72/400, Reward: -48.00, Steps:28, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 73/400, Reward: -460.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 74/400, Reward: -460.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 75/400, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 76/400, Reward: -428.00, Steps:178, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 77/400, Reward: -460.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 78/400, Reward: -341.00, Steps:151, Epislon: 0.010 +2022-10-30 02:13:18 - r - INFO: - Episode: 79/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 80/400, Reward: -346.00, Steps:156, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 81/400, Reward: -34.00, Steps:24, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 82/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 83/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 84/400, Reward: -222.00, Steps:112, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 85/400, Reward: -470.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 86/400, Reward: -409.00, Steps:169, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 87/400, Reward: -139.00, Steps:59, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 88/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 89/400, Reward: -108.00, Steps:58, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 90/400, Reward: -3.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 91/400, Reward: -131.00, Steps:71, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 92/400, Reward: -355.00, Steps:145, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 93/400, Reward: -470.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 94/400, Reward: -450.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 95/400, Reward: -490.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 96/400, Reward: -425.00, Steps:185, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 97/400, Reward: -130.00, Steps:70, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 98/400, Reward: -246.00, Steps:116, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 99/400, Reward: -480.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 100/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 101/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 102/400, Reward: -63.00, Steps:33, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 103/400, Reward: -311.00, Steps:131, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 104/400, Reward: -450.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 105/400, Reward: -520.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 106/400, Reward: -430.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 107/400, Reward: -79.00, Steps:39, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 108/400, Reward: -94.00, Steps:44, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 109/400, Reward: -37.00, Steps:27, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 110/400, Reward: -235.00, Steps:115, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 111/400, Reward: -440.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 112/400, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 113/400, Reward: -424.00, Steps:194, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 114/400, Reward: -470.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:19 - r - INFO: - Episode: 115/400, Reward: -344.00, Steps:164, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 116/400, Reward: -307.00, Steps:147, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 117/400, Reward: -82.00, Steps:52, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 118/400, Reward: -387.00, Steps:177, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 119/400, Reward: -500.00, Steps:200, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 120/400, Reward: -315.00, Steps:145, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 121/400, Reward: -289.00, Steps:119, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 122/400, Reward: -139.00, Steps:79, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 123/400, Reward: -392.00, Steps:192, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 124/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 125/400, Reward: -35.00, Steps:25, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 126/400, Reward: -82.00, Steps:42, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 127/400, Reward: -134.00, Steps:64, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 128/400, Reward: -93.00, Steps:53, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 129/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 130/400, Reward: -212.00, Steps:102, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 131/400, Reward: -87.00, Steps:47, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 132/400, Reward: -70.00, Steps:40, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 133/400, Reward: -109.00, Steps:49, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 134/400, Reward: -77.00, Steps:47, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 135/400, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 136/400, Reward: -118.00, Steps:58, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 137/400, Reward: -132.00, Steps:62, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 138/400, Reward: -76.00, Steps:36, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 139/400, Reward: -93.00, Steps:63, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 140/400, Reward: -357.00, Steps:157, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 141/400, Reward: -129.00, Steps:69, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 142/400, Reward: -46.00, Steps:26, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 143/400, Reward: -60.00, Steps:30, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 144/400, Reward: -339.00, Steps:159, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 145/400, Reward: -10.00, Steps:10, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 146/400, Reward: -164.00, Steps:84, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 147/400, Reward: -145.00, Steps:75, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 148/400, Reward: -53.00, Steps:33, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 149/400, Reward: -3.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 150/400, Reward: -55.00, Steps:35, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 151/400, Reward: -398.00, Steps:178, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 152/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 153/400, Reward: -20.00, Steps:20, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 154/400, Reward: -354.00, Steps:154, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 155/400, Reward: -439.00, Steps:189, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 156/400, Reward: -122.00, Steps:62, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 157/400, Reward: -80.00, Steps:40, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 158/400, Reward: -29.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 159/400, Reward: -185.00, Steps:85, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 160/400, Reward: -354.00, Steps:154, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 161/400, Reward: -35.00, Steps:25, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 162/400, Reward: -132.00, Steps:62, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 163/400, Reward: -155.00, Steps:75, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 164/400, Reward: -261.00, Steps:111, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 165/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 166/400, Reward: -135.00, Steps:65, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 167/400, Reward: -57.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 168/400, Reward: -432.00, Steps:182, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 169/400, Reward: -63.00, Steps:33, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 170/400, Reward: -119.00, Steps:59, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 171/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 172/400, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 173/400, Reward: -112.00, Steps:62, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 174/400, Reward: 1.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 175/400, Reward: -354.00, Steps:164, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 176/400, Reward: -101.00, Steps:61, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 177/400, Reward: -86.00, Steps:46, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 178/400, Reward: -33.00, Steps:23, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 179/400, Reward: -339.00, Steps:139, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 180/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 181/400, Reward: -9.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 182/400, Reward: -224.00, Steps:104, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 183/400, Reward: -11.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 184/400, Reward: -52.00, Steps:32, Epislon: 0.010 +2022-10-30 02:13:20 - r - INFO: - Episode: 185/400, Reward: -98.00, Steps:48, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 186/400, Reward: -26.00, Steps:16, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 187/400, Reward: -89.00, Steps:39, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 188/400, Reward: 1.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 189/400, Reward: -66.00, Steps:36, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 190/400, Reward: -77.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 191/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 192/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 193/400, Reward: -64.00, Steps:34, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 194/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 195/400, Reward: -10.00, Steps:10, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 196/400, Reward: -79.00, Steps:39, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 197/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 198/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 199/400, Reward: 0.00, Steps:10, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 200/400, Reward: -33.00, Steps:23, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 201/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 202/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 203/400, Reward: -110.00, Steps:50, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 204/400, Reward: -43.00, Steps:23, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 205/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 206/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 207/400, Reward: 1.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 208/400, Reward: -32.00, Steps:22, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 209/400, Reward: -77.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 210/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 211/400, Reward: -23.00, Steps:23, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 212/400, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 213/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 214/400, Reward: 1.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 215/400, Reward: -42.00, Steps:22, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 216/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 217/400, Reward: -64.00, Steps:34, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 218/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 219/400, Reward: -2.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 220/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 221/400, Reward: -129.00, Steps:69, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 222/400, Reward: -133.00, Steps:63, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 223/400, Reward: -47.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 224/400, Reward: -11.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 225/400, Reward: -25.00, Steps:25, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 226/400, Reward: -1.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 227/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 228/400, Reward: -103.00, Steps:53, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 229/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 230/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 231/400, Reward: -67.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 232/400, Reward: -65.00, Steps:35, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 233/400, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 234/400, Reward: -30.00, Steps:20, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 235/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 236/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 237/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 238/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 239/400, Reward: 1.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 240/400, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 241/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 242/400, Reward: -39.00, Steps:29, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 243/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 244/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 245/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 246/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 247/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 248/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 249/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 250/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 251/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 252/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 253/400, Reward: -57.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 254/400, Reward: -29.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 255/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 256/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 257/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 258/400, Reward: -40.00, Steps:30, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 259/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 260/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 261/400, Reward: -30.00, Steps:20, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 262/400, Reward: -34.00, Steps:24, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 263/400, Reward: -1.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 264/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 265/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 266/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 267/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 268/400, Reward: -42.00, Steps:32, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 269/400, Reward: -17.00, Steps:17, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 270/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 271/400, Reward: -28.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 272/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 273/400, Reward: -2.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 274/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 275/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 276/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 277/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 278/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 279/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 280/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 281/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 282/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 283/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 284/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 285/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 286/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 287/400, Reward: -1.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 288/400, Reward: -39.00, Steps:29, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 289/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 290/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 291/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 292/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 293/400, Reward: -11.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 294/400, Reward: -30.00, Steps:20, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 295/400, Reward: -18.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 296/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 297/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 298/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 299/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 300/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 301/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 302/400, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 303/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 304/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 305/400, Reward: -55.00, Steps:35, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 306/400, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 307/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 308/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 309/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 310/400, Reward: -67.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 311/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 312/400, Reward: -20.00, Steps:20, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 313/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 314/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 315/400, Reward: -20.00, Steps:20, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 316/400, Reward: -36.00, Steps:26, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 317/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 318/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 319/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 320/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 321/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 322/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 323/400, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 324/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 325/400, Reward: -18.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 326/400, Reward: -36.00, Steps:26, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 327/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 328/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 329/400, Reward: -28.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 330/400, Reward: -31.00, Steps:21, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 331/400, Reward: -1.00, Steps:11, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 332/400, Reward: -109.00, Steps:59, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 333/400, Reward: -29.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 334/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 335/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 336/400, Reward: 0.00, Steps:10, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 337/400, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 338/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 339/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 340/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 341/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 342/400, Reward: -35.00, Steps:25, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 343/400, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 344/400, Reward: -21.00, Steps:21, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 345/400, Reward: -28.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 346/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 347/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 348/400, Reward: -28.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 349/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 350/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 351/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 352/400, Reward: -10.00, Steps:10, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 353/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 354/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 355/400, Reward: -62.00, Steps:32, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 356/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 357/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 358/400, Reward: -28.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 359/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 360/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 361/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 362/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 363/400, Reward: -16.00, Steps:16, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 364/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 365/400, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 366/400, Reward: -18.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 367/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 368/400, Reward: -18.00, Steps:18, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 369/400, Reward: -15.00, Steps:15, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 370/400, Reward: 5.00, Steps:5, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 371/400, Reward: -29.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 372/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 373/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 374/400, Reward: 1.00, Steps:9, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 375/400, Reward: -19.00, Steps:19, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 376/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 377/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 378/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 379/400, Reward: -31.00, Steps:21, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 380/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 381/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 382/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 383/400, Reward: -14.00, Steps:14, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 384/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 385/400, Reward: 2.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 386/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 387/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 388/400, Reward: -8.00, Steps:8, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 389/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 390/400, Reward: 4.00, Steps:6, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 391/400, Reward: -13.00, Steps:13, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 392/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 393/400, Reward: -12.00, Steps:12, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 394/400, Reward: -32.00, Steps:22, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 395/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 396/400, Reward: -27.00, Steps:17, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 397/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 398/400, Reward: 3.00, Steps:7, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 399/400, Reward: -37.00, Steps:27, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Episode: 400/400, Reward: -57.00, Steps:37, Epislon: 0.010 +2022-10-30 02:13:21 - r - INFO: - Finish training! diff --git a/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/models/checkpoint.pkl b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/models/checkpoint.pkl new file mode 100644 index 0000000..d950b3f Binary files /dev/null and b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/models/checkpoint.pkl differ diff --git a/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/results/learning_curve.png b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/results/learning_curve.png new file mode 100644 index 0000000..0626795 Binary files /dev/null and b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/results/learning_curve.png differ diff --git a/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/results/res.csv b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/results/res.csv new file mode 100644 index 0000000..d251623 --- /dev/null +++ b/projects/codes/Sarsa/Train_Racetrack-v0_Sarsa_20221030-021315/results/res.csv @@ -0,0 +1,401 @@ +episodes,rewards,steps +0,-870,200 +1,-740,200 +2,-710,200 +3,-600,200 +4,-580,200 +5,-620,200 +6,-590,200 +7,-590,200 +8,-520,200 +9,-570,200 +10,-580,200 +11,-580,200 +12,-500,200 +13,-540,200 +14,-510,200 +15,-570,200 +16,-560,200 +17,-540,200 +18,-490,200 +19,-490,200 +20,-530,200 +21,-520,200 +22,-530,200 +23,-520,200 +24,-500,200 +25,-510,200 +26,-520,200 +27,-530,200 +28,-560,200 +29,-490,200 +30,-530,200 +31,-359,149 +32,-470,200 +33,-510,200 +34,-520,200 +35,-500,200 +36,-540,200 +37,-560,200 +38,-500,200 +39,-480,200 +40,-490,200 +41,-480,200 +42,-540,200 +43,-500,200 +44,-500,200 +45,-480,200 +46,-550,200 +47,-490,200 +48,-540,200 +49,-420,200 +50,-530,200 +51,-510,200 +52,-530,200 +53,-460,200 +54,-480,200 +55,-480,200 +56,-470,200 +57,-490,200 +58,-470,200 +59,-500,200 +60,-500,200 +61,-480,200 +62,-450,200 +63,-490,200 +64,-420,200 +65,-480,200 +66,-440,200 +67,-490,200 +68,-188,88 +69,-327,167 +70,-530,200 +71,-48,28 +72,-460,200 +73,-460,200 +74,-25,25 +75,-428,178 +76,-460,200 +77,-341,151 +78,-480,200 +79,-346,156 +80,-34,24 +81,-480,200 +82,-480,200 +83,-222,112 +84,-470,200 +85,-409,169 +86,-139,59 +87,-520,200 +88,-108,58 +89,-3,13 +90,-131,71 +91,-355,145 +92,-470,200 +93,-450,200 +94,-490,200 +95,-425,185 +96,-130,70 +97,-246,116 +98,-480,200 +99,-500,200 +100,-13,13 +101,-63,33 +102,-311,131 +103,-450,200 +104,-520,200 +105,-430,200 +106,-79,39 +107,-94,44 +108,-37,27 +109,-235,115 +110,-440,200 +111,-19,19 +112,-424,194 +113,-470,200 +114,-344,164 +115,-307,147 +116,-82,52 +117,-387,177 +118,-500,200 +119,-315,145 +120,-289,119 +121,-139,79 +122,-392,192 +123,-13,13 +124,-35,25 +125,-82,42 +126,-134,64 +127,-93,53 +128,2,8 +129,-212,102 +130,-87,47 +131,-70,40 +132,-109,49 +133,-77,47 +134,-17,17 +135,-118,58 +136,-132,62 +137,-76,36 +138,-93,63 +139,-357,157 +140,-129,69 +141,-46,26 +142,-60,30 +143,-339,159 +144,-10,10 +145,-164,84 +146,-145,75 +147,-53,33 +148,-3,13 +149,-55,35 +150,-398,178 +151,3,7 +152,-20,20 +153,-354,154 +154,-439,189 +155,-122,62 +156,-80,40 +157,-29,19 +158,-185,85 +159,-354,154 +160,-35,25 +161,-132,62 +162,-155,75 +163,-261,111 +164,3,7 +165,-135,65 +166,-57,37 +167,-432,182 +168,-63,33 +169,-119,59 +170,3,7 +171,-16,16 +172,-112,62 +173,1,9 +174,-354,164 +175,-101,61 +176,-86,46 +177,-33,23 +178,-339,139 +179,3,7 +180,-9,9 +181,-224,104 +182,-11,11 +183,-52,32 +184,-98,48 +185,-26,16 +186,-89,39 +187,1,9 +188,-66,36 +189,-77,37 +190,5,5 +191,2,8 +192,-64,34 +193,5,5 +194,-10,10 +195,-79,39 +196,3,7 +197,3,7 +198,0,10 +199,-33,23 +200,2,8 +201,5,5 +202,-110,50 +203,-43,23 +204,3,7 +205,-13,13 +206,1,9 +207,-32,22 +208,-77,37 +209,5,5 +210,-23,23 +211,-15,15 +212,4,6 +213,1,9 +214,-42,22 +215,-13,13 +216,-64,34 +217,-13,13 +218,-2,12 +219,5,5 +220,-129,69 +221,-133,63 +222,-47,37 +223,-11,11 +224,-25,25 +225,-1,11 +226,5,5 +227,-103,53 +228,3,7 +229,2,8 +230,-67,37 +231,-65,35 +232,-15,15 +233,-30,20 +234,3,7 +235,4,6 +236,3,7 +237,-13,13 +238,1,9 +239,-16,16 +240,3,7 +241,-39,29 +242,3,7 +243,3,7 +244,3,7 +245,-13,13 +246,5,5 +247,3,7 +248,2,8 +249,-12,12 +250,-14,14 +251,2,8 +252,-57,37 +253,-29,19 +254,4,6 +255,2,8 +256,-13,13 +257,-40,30 +258,3,7 +259,3,7 +260,-30,20 +261,-34,24 +262,-1,11 +263,-13,13 +264,2,8 +265,5,5 +266,3,7 +267,-42,32 +268,-17,17 +269,-12,12 +270,-28,18 +271,-13,13 +272,-2,12 +273,3,7 +274,3,7 +275,3,7 +276,-14,14 +277,-14,14 +278,3,7 +279,4,6 +280,3,7 +281,5,5 +282,-13,13 +283,3,7 +284,2,8 +285,5,5 +286,-1,11 +287,-39,29 +288,5,5 +289,3,7 +290,3,7 +291,3,7 +292,-11,11 +293,-30,20 +294,-18,18 +295,-13,13 +296,2,8 +297,5,5 +298,3,7 +299,4,6 +300,2,8 +301,-15,15 +302,-14,14 +303,-13,13 +304,-55,35 +305,-19,19 +306,3,7 +307,-12,12 +308,3,7 +309,-67,37 +310,3,7 +311,-20,20 +312,4,6 +313,5,5 +314,-20,20 +315,-36,26 +316,3,7 +317,4,6 +318,2,8 +319,-12,12 +320,5,5 +321,4,6 +322,-16,16 +323,4,6 +324,-18,18 +325,-36,26 +326,3,7 +327,3,7 +328,-28,18 +329,-31,21 +330,-1,11 +331,-109,59 +332,-29,19 +333,3,7 +334,3,7 +335,0,10 +336,-15,15 +337,-12,12 +338,3,7 +339,3,7 +340,-14,14 +341,-35,25 +342,-16,16 +343,-21,21 +344,-28,18 +345,2,8 +346,-12,12 +347,-28,18 +348,3,7 +349,3,7 +350,3,7 +351,-10,10 +352,3,7 +353,3,7 +354,-62,32 +355,5,5 +356,4,6 +357,-28,18 +358,3,7 +359,3,7 +360,2,8 +361,2,8 +362,-16,16 +363,2,8 +364,-15,15 +365,-18,18 +366,3,7 +367,-18,18 +368,-15,15 +369,5,5 +370,-29,19 +371,3,7 +372,-14,14 +373,1,9 +374,-19,19 +375,3,7 +376,3,7 +377,3,7 +378,-31,21 +379,2,8 +380,3,7 +381,3,7 +382,-14,14 +383,3,7 +384,2,8 +385,3,7 +386,4,6 +387,-8,8 +388,3,7 +389,4,6 +390,-13,13 +391,3,7 +392,-12,12 +393,-32,22 +394,3,7 +395,-27,17 +396,3,7 +397,3,7 +398,-37,27 +399,-57,37 diff --git a/projects/codes/Sarsa/config/CliffWalking-v0_Sarsa_Test.yaml b/projects/codes/Sarsa/config/CliffWalking-v0_Sarsa_Test.yaml new file mode 100644 index 0000000..f39b31b --- /dev/null +++ b/projects/codes/Sarsa/config/CliffWalking-v0_Sarsa_Test.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: CliffWalking-v0 + mode: test + load_checkpoint: true + load_path: Train_CliffWalking-v0_Sarsa_20221030-021146 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/Sarsa/config/CliffWalking-v0_Sarsa_Train.yaml b/projects/codes/Sarsa/config/CliffWalking-v0_Sarsa_Train.yaml new file mode 100644 index 0000000..630ead8 --- /dev/null +++ b/projects/codes/Sarsa/config/CliffWalking-v0_Sarsa_Train.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: CliffWalking-v0 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 1 + show_fig: false + test_eps: 20 + train_eps: 800 +algo_cfg: + epsilon_decay: 300 + epsilon_end: 0.01 + epsilon_start: 0.95 + gamma: 0.95 + lr: 0.1 diff --git a/projects/codes/Sarsa/config/Racetrack-v0_Sarsa_Test.yaml b/projects/codes/Sarsa/config/Racetrack-v0_Sarsa_Test.yaml new file mode 100644 index 0000000..e07a7e2 --- /dev/null +++ b/projects/codes/Sarsa/config/Racetrack-v0_Sarsa_Test.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: Racetrack-v0 + mode: test + load_checkpoint: true + load_path: Train_Racetrack-v0_Sarsa_20221030-021315 + max_steps: 200 + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 200 + epsilon_end: 0.01 + epsilon_start: 0.9 + gamma: 0.99 + lr: 0.1 diff --git a/projects/codes/Sarsa/config/Racetrack-v0_Sarsa_Train.yaml b/projects/codes/Sarsa/config/Racetrack-v0_Sarsa_Train.yaml new file mode 100644 index 0000000..da6299f --- /dev/null +++ b/projects/codes/Sarsa/config/Racetrack-v0_Sarsa_Train.yaml @@ -0,0 +1,19 @@ +general_cfg: + algo_name: Sarsa + device: cpu + env_name: Racetrack-v0 + mode: train + load_checkpoint: false + load_path: Train_CartPole-v1_DQN_20221026-054757 + max_steps: 200 + save_fig: true + seed: 10 + show_fig: false + test_eps: 20 + train_eps: 400 +algo_cfg: + epsilon_decay: 200 + epsilon_end: 0.01 + epsilon_start: 0.9 + gamma: 0.99 + lr: 0.1 diff --git a/projects/codes/Sarsa/config/config.py b/projects/codes/Sarsa/config/config.py new file mode 100644 index 0000000..9980c04 --- /dev/null +++ b/projects/codes/Sarsa/config/config.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-10-30 01:23:07 +LastEditor: JiangJi +LastEditTime: 2022-10-30 02:01:54 +Discription: default parameters of QLearning +''' +from common.config import GeneralConfig,AlgoConfig + +class GeneralConfigSarsa(GeneralConfig): + def __init__(self) -> None: + self.env_name = "CliffWalking-v0" # name of environment + self.algo_name = "Sarsa" # name of algorithm + self.mode = "train" # train or test + self.seed = 1 # random seed + self.device = "cpu" # device to use + self.train_eps = 400 # number of episodes for training + self.test_eps = 20 # number of episodes for testing + self.max_steps = 200 # max steps for each episode + self.load_checkpoint = False + self.load_path = "tasks" # path to load model + self.show_fig = False # show figure or not + self.save_fig = True # save figure or not + +class AlgoConfigSarsa(AlgoConfig): + def __init__(self) -> None: + # set epsilon_start=epsilon_end can obtain fixed epsilon=epsilon_end + self.epsilon_start = 0.95 # epsilon start value + self.epsilon_end = 0.01 # epsilon end value + self.epsilon_decay = 300 # epsilon decay rate + self.gamma = 0.90 # discount factor + self.lr = 0.1 # learning rate \ No newline at end of file diff --git a/projects/codes/Sarsa/main.py b/projects/codes/Sarsa/main.py deleted file mode 100644 index cb1b22c..0000000 --- a/projects/codes/Sarsa/main.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -''' -Author: John -Email: johnjim0816@gmail.com -Date: 2021-03-11 17:59:16 -LastEditor: John -LastEditTime: 2022-08-26 23:03:39 -Discription: -Environment: -''' -import sys,os -os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." -curr_path = os.path.dirname(os.path.abspath(__file__)) # current path -parent_path = os.path.dirname(curr_path) # parent path -sys.path.append(parent_path) # add path to system path -import gym -import datetime -import argparse -from envs.register import register_env -from envs.wrappers import CliffWalkingWapper -from Sarsa.sarsa import Sarsa -from common.utils import all_seed -from common.launcher import Launcher - -class Main(Launcher): - def get_args(self): - curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # obtain current time - parser = argparse.ArgumentParser(description="hyperparameters") - parser.add_argument('--algo_name',default = 'Sarsa',type=str,help="name of algorithm") - parser.add_argument('--env_name',default = 'Racetrack-v0',type=str,help="name of environment") - parser.add_argument('--train_eps',default = 300,type=int,help="episodes of training") - parser.add_argument('--test_eps',default = 20,type=int,help="episodes of testing") - parser.add_argument('--ep_max_steps',default = 100000,type=int,help="steps per episode, much larger value can simulate infinite steps") - parser.add_argument('--gamma',default=0.99,type=float,help="discounted factor") - parser.add_argument('--epsilon_start',default=0.90,type=float,help="initial value of epsilon") - parser.add_argument('--epsilon_end',default=0.01,type=float,help="final value of epsilon") - parser.add_argument('--epsilon_decay',default=200,type=int,help="decay rate of epsilon") - parser.add_argument('--lr',default=0.2,type=float,help="learning rate") - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--seed',default=10,type=int,help="seed") - parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") - parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") - args = parser.parse_args() - default_args = {'result_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/results/", - 'model_path':f"{curr_path}/outputs/{args.env_name}/{curr_time}/models/", - } - args = {**vars(args),**default_args} # type(dict) - return args - - def env_agent_config(self,cfg): - register_env(cfg['env_name']) - env = gym.make(cfg['env_name']) - if cfg['seed'] !=0: # set random seed - all_seed(env,seed= cfg['seed']) - if cfg['env_name'] == 'CliffWalking-v0': - env = CliffWalkingWapper(env) - try: # state dimension - n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) - except AttributeError: - n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) - n_actions = env.action_space.n # action dimension - print(f"n_states: {n_states}, n_actions: {n_actions}") - cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters - agent = Sarsa(cfg) - return env,agent - - def train(self,cfg,env,agent): - print("Start training!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # record rewards for all episodes - steps = [] # record steps for all episodes - for i_ep in range(cfg['train_eps']): - ep_reward = 0 # reward per episode - ep_step = 0 # step per episode - state = env.reset() # reset and obtain initial state - action = agent.sample_action(state) - # while True: - for _ in range(cfg['ep_max_steps']): - next_state, reward, done, _ = env.step(action) # update env and return transitions - next_action = agent.sample_action(next_state) - agent.update(state, action, reward, next_state, next_action,done) # update agent - state = next_state # update state - action = next_action - ep_reward += reward - ep_step += 1 - if done: - break - rewards.append(ep_reward) - steps.append(ep_step) - if (i_ep+1)%10==0: - print(f'Episode: {i_ep+1}/{cfg["train_eps"]}, Reward: {ep_reward:.2f}, Steps: {ep_step}, Epislon: {agent.epsilon:.3f}') - print("Finish training!") - return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} - - def test(self,cfg,env,agent): - print("Start testing!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # record rewards for all episodes - steps = [] # record steps for all episodes - for i_ep in range(cfg['test_eps']): - ep_reward = 0 # reward per episode - ep_step = 0 - state = env.reset() # reset and obtain initial state - for _ in range(cfg['ep_max_steps']): - action = agent.predict_action(state) - next_state, reward, done, _ = env.step(action) - state = next_state - ep_reward+=reward - ep_step+=1 - if done: - break - rewards.append(ep_reward) - steps.append(ep_step) - print(f"Episode: {i_ep+1}/{cfg['test_eps']}, Steps: {ep_step}, Reward: {ep_reward:.2f}") - print("Finish testing!") - return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} - -if __name__ == "__main__": - main = Main() - main.run() - - - diff --git a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/models/checkpoint.pkl b/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/models/checkpoint.pkl deleted file mode 100644 index fb8efd6..0000000 Binary files a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/models/checkpoint.pkl and /dev/null differ diff --git a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/params.json b/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/params.json deleted file mode 100644 index e16e735..0000000 --- a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/params.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "algo_name": "Sarsa", - "env_name": "CliffWalking-v0", - "train_eps": 400, - "test_eps": 20, - "gamma": 0.9, - "epsilon_start": 0.95, - "epsilon_end": 0.01, - "epsilon_decay": 300, - "lr": 0.1, - "device": "cpu", - "seed": 10, - "show_fig": false, - "save_fig": true, - "result_path": "/Users/jj/Desktop/rl-tutorials/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/", - "model_path": "/Users/jj/Desktop/rl-tutorials/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/models/", - "n_states": 48, - "n_actions": 4 -} \ No newline at end of file diff --git a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/training_curve.png b/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/training_curve.png deleted file mode 100644 index 14dbf39..0000000 Binary files a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/training_curve.png and /dev/null differ diff --git a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/training_results.csv b/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/training_results.csv deleted file mode 100644 index c51b354..0000000 --- a/projects/codes/Sarsa/outputs/CliffWalking-v0/20220825-213316/results/training_results.csv +++ /dev/null @@ -1,401 +0,0 @@ -episodes,rewards,steps -0,-649,154 -1,-2822,842 -2,-176,176 -3,-139,139 -4,-221,221 -5,-51,51 -6,-219,219 -7,-247,148 -8,-90,90 -9,-145,145 -10,-104,104 -11,-162,162 -12,-49,49 -13,-129,129 -14,-140,140 -15,-19,19 -16,-131,131 -17,-115,115 -18,-43,43 -19,-133,133 -20,-73,73 -21,-89,89 -22,-131,131 -23,-61,61 -24,-113,113 -25,-119,119 -26,-119,119 -27,-71,71 -28,-132,132 -29,-47,47 -30,-79,79 -31,-57,57 -32,-125,125 -33,-77,77 -34,-87,87 -35,-49,49 -36,-57,57 -37,-81,81 -38,-81,81 -39,-97,97 -40,-61,61 -41,-85,85 -42,-217,118 -43,-39,39 -44,-117,117 -45,-41,41 -46,-71,71 -47,-105,105 -48,-73,73 -49,-68,68 -50,-95,95 -51,-41,41 -52,-41,41 -53,-67,67 -54,-71,71 -55,-65,65 -56,-41,41 -57,-61,61 -58,-81,81 -59,-21,21 -60,-76,76 -61,-80,80 -62,-23,23 -63,-53,53 -64,-67,67 -65,-33,33 -66,-41,41 -67,-59,59 -68,-33,33 -69,-64,64 -70,-188,89 -71,-47,47 -72,-57,57 -73,-45,45 -74,-33,33 -75,-79,79 -76,-45,45 -77,-23,23 -78,-47,47 -79,-57,57 -80,-47,47 -81,-45,45 -82,-53,53 -83,-29,29 -84,-33,33 -85,-69,69 -86,-61,61 -87,-35,35 -88,-59,59 -89,-43,43 -90,-17,17 -91,-39,39 -92,-59,59 -93,-29,29 -94,-31,31 -95,-55,55 -96,-35,35 -97,-45,45 -98,-29,29 -99,-59,59 -100,-25,25 -101,-29,29 -102,-33,33 -103,-39,39 -104,-19,19 -105,-47,47 -106,-57,57 -107,-19,19 -108,-47,47 -109,-25,25 -110,-23,23 -111,-53,53 -112,-39,39 -113,-34,34 -114,-27,27 -115,-27,27 -116,-63,63 -117,-33,33 -118,-17,17 -119,-21,21 -120,-19,19 -121,-49,49 -122,-25,25 -123,-39,39 -124,-25,25 -125,-167,68 -126,-35,35 -127,-29,29 -128,-31,31 -129,-44,44 -130,-33,33 -131,-23,23 -132,-37,37 -133,-134,35 -134,-31,31 -135,-19,19 -136,-29,29 -137,-37,37 -138,-25,25 -139,-39,39 -140,-47,47 -141,-29,29 -142,-27,27 -143,-21,21 -144,-41,41 -145,-29,29 -146,-25,25 -147,-25,25 -148,-21,21 -149,-29,29 -150,-39,39 -151,-35,35 -152,-35,35 -153,-32,32 -154,-31,31 -155,-19,19 -156,-21,21 -157,-35,35 -158,-33,33 -159,-37,37 -160,-25,25 -161,-41,41 -162,-25,25 -163,-23,23 -164,-27,27 -165,-25,25 -166,-39,39 -167,-28,28 -168,-24,24 -169,-23,23 -170,-41,41 -171,-17,17 -172,-35,35 -173,-23,23 -174,-29,29 -175,-17,17 -176,-39,39 -177,-33,33 -178,-29,29 -179,-24,24 -180,-23,23 -181,-19,19 -182,-15,15 -183,-23,23 -184,-39,39 -185,-25,25 -186,-35,35 -187,-33,33 -188,-19,19 -189,-35,35 -190,-21,21 -191,-131,32 -192,-15,15 -193,-23,23 -194,-21,21 -195,-17,17 -196,-23,23 -197,-31,31 -198,-21,21 -199,-31,31 -200,-35,35 -201,-27,27 -202,-19,19 -203,-21,21 -204,-23,23 -205,-23,23 -206,-21,21 -207,-31,31 -208,-25,25 -209,-23,23 -210,-17,17 -211,-19,19 -212,-25,25 -213,-23,23 -214,-19,19 -215,-19,19 -216,-25,25 -217,-25,25 -218,-25,25 -219,-25,25 -220,-23,23 -221,-19,19 -222,-19,19 -223,-149,50 -224,-41,41 -225,-19,19 -226,-29,29 -227,-37,37 -228,-17,17 -229,-17,17 -230,-19,19 -231,-27,27 -232,-19,19 -233,-33,33 -234,-23,23 -235,-23,23 -236,-34,34 -237,-15,15 -238,-33,33 -239,-29,29 -240,-17,17 -241,-23,23 -242,-17,17 -243,-19,19 -244,-21,21 -245,-23,23 -246,-17,17 -247,-15,15 -248,-39,39 -249,-21,21 -250,-23,23 -251,-29,29 -252,-15,15 -253,-17,17 -254,-29,29 -255,-15,15 -256,-21,21 -257,-19,19 -258,-19,19 -259,-21,21 -260,-17,17 -261,-21,21 -262,-27,27 -263,-27,27 -264,-21,21 -265,-19,19 -266,-17,17 -267,-23,23 -268,-19,19 -269,-17,17 -270,-19,19 -271,-19,19 -272,-17,17 -273,-23,23 -274,-17,17 -275,-22,22 -276,-31,31 -277,-19,19 -278,-17,17 -279,-33,33 -280,-19,19 -281,-17,17 -282,-31,31 -283,-15,15 -284,-15,15 -285,-15,15 -286,-29,29 -287,-19,19 -288,-17,17 -289,-26,26 -290,-17,17 -291,-19,19 -292,-15,15 -293,-21,21 -294,-21,21 -295,-15,15 -296,-19,19 -297,-15,15 -298,-17,17 -299,-19,19 -300,-17,17 -301,-21,21 -302,-17,17 -303,-27,27 -304,-17,17 -305,-19,19 -306,-15,15 -307,-19,19 -308,-33,33 -309,-17,17 -310,-20,20 -311,-19,19 -312,-17,17 -313,-15,15 -314,-23,23 -315,-15,15 -316,-15,15 -317,-17,17 -318,-25,25 -319,-15,15 -320,-17,17 -321,-19,19 -322,-17,17 -323,-15,15 -324,-23,23 -325,-19,19 -326,-17,17 -327,-23,23 -328,-15,15 -329,-19,19 -330,-15,15 -331,-17,17 -332,-19,19 -333,-15,15 -334,-17,17 -335,-17,17 -336,-19,19 -337,-15,15 -338,-19,19 -339,-19,19 -340,-17,17 -341,-15,15 -342,-21,21 -343,-19,19 -344,-17,17 -345,-17,17 -346,-15,15 -347,-21,21 -348,-20,20 -349,-15,15 -350,-15,15 -351,-15,15 -352,-19,19 -353,-17,17 -354,-15,15 -355,-27,27 -356,-15,15 -357,-15,15 -358,-23,23 -359,-125,26 -360,-132,33 -361,-17,17 -362,-15,15 -363,-17,17 -364,-23,23 -365,-17,17 -366,-15,15 -367,-15,15 -368,-17,17 -369,-15,15 -370,-17,17 -371,-15,15 -372,-15,15 -373,-15,15 -374,-15,15 -375,-15,15 -376,-15,15 -377,-15,15 -378,-15,15 -379,-15,15 -380,-17,17 -381,-15,15 -382,-15,15 -383,-19,19 -384,-15,15 -385,-17,17 -386,-27,27 -387,-15,15 -388,-21,21 -389,-125,26 -390,-15,15 -391,-15,15 -392,-15,15 -393,-27,27 -394,-15,15 -395,-15,15 -396,-17,17 -397,-15,15 -398,-15,15 -399,-15,15 diff --git a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/models/checkpoint.pkl b/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/models/checkpoint.pkl deleted file mode 100644 index 81268a4..0000000 Binary files a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/models/checkpoint.pkl and /dev/null differ diff --git a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/params.json b/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/params.json deleted file mode 100644 index accb050..0000000 --- a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/params.json +++ /dev/null @@ -1 +0,0 @@ -{"algo_name": "Sarsa", "env_name": "Racetrack-v0", "train_eps": 300, "test_eps": 20, "gamma": 0.99, "epsilon_start": 0.9, "epsilon_end": 0.01, "epsilon_decay": 200, "lr": 0.2, "device": "cpu", "seed": 10, "show_fig": false, "save_fig": true, "result_path": "/Users/jj/Desktop/rl-tutorials/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/", "model_path": "/Users/jj/Desktop/rl-tutorials/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/models/", "n_states": 4, "n_actions": 9} \ No newline at end of file diff --git a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/testing_curve.png b/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/testing_curve.png deleted file mode 100644 index c78b938..0000000 Binary files a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/testing_curve.png and /dev/null differ diff --git a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/testing_results.csv b/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/testing_results.csv deleted file mode 100644 index 2cb817f..0000000 --- a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/testing_results.csv +++ /dev/null @@ -1,21 +0,0 @@ -episodes,rewards,steps -0,4,6 -1,4,6 -2,-1010,1000 -3,-14,14 -4,4,6 -5,4,6 -6,4,6 -7,-1060,1000 -8,2,8 -9,-12,12 -10,3,7 -11,-15,15 -12,3,7 -13,4,6 -14,-14,14 -15,3,7 -16,-18,18 -17,4,6 -18,4,6 -19,-1020,1000 diff --git a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/training_curve.png b/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/training_curve.png deleted file mode 100644 index 5c612d6..0000000 Binary files a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/training_curve.png and /dev/null differ diff --git a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/training_results.csv b/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/training_results.csv deleted file mode 100644 index 0912f70..0000000 --- a/projects/codes/Sarsa/outputs/Racetrack-v0/20220825-212738/results/training_results.csv +++ /dev/null @@ -1,301 +0,0 @@ -episodes,rewards,steps -0,-3460,1000 -1,-2800,1000 -2,-2910,1000 -3,-2620,1000 -4,-2620,1000 -5,-2590,1000 -6,-2390,1000 -7,-2510,1000 -8,-2470,1000 -9,-611,251 -10,-891,371 -11,-265,125 -12,-2281,911 -13,-1203,523 -14,-616,266 -15,-213,113 -16,-633,273 -17,-1112,482 -18,-350,160 -19,-852,342 -20,-87,47 -21,-11,11 -22,-27,17 -23,-117,57 -24,-15,15 -25,4,6 -26,-27,17 -27,-94,44 -28,-184,84 -29,-44,24 -30,-150,80 -31,-14,14 -32,-219,89 -33,-50,30 -34,-111,61 -35,-10,10 -36,-28,18 -37,-34,24 -38,-12,12 -39,-19,19 -40,-136,66 -41,-171,71 -42,-51,31 -43,4,6 -44,-117,57 -45,4,6 -46,4,6 -47,-127,67 -48,-78,48 -49,-311,131 -50,-25,15 -51,4,6 -52,-49,29 -53,-25,15 -54,-78,48 -55,-238,108 -56,4,6 -57,-17,17 -58,-29,19 -59,-218,98 -60,4,6 -61,-129,59 -62,-344,144 -63,-25,15 -64,-15,15 -65,-77,37 -66,2,8 -67,0,10 -68,4,6 -69,4,6 -70,-242,102 -71,3,7 -72,4,6 -73,-53,33 -74,-14,14 -75,4,6 -76,4,6 -77,-30,20 -78,-12,12 -79,2,8 -80,-12,12 -81,-150,70 -82,-48,28 -83,-102,52 -84,4,6 -85,-97,47 -86,-10,10 -87,-125,55 -88,-28,18 -89,-26,16 -90,-107,57 -91,4,6 -92,-16,16 -93,-84,44 -94,-13,13 -95,-43,23 -96,-14,14 -97,-12,12 -98,-13,13 -99,-2,12 -100,-14,14 -101,-47,27 -102,4,6 -103,4,6 -104,-91,51 -105,-65,35 -106,4,6 -107,-12,12 -108,-14,14 -109,-13,13 -110,4,6 -111,-41,31 -112,-13,13 -113,4,6 -114,-4,14 -115,-74,34 -116,4,6 -117,-60,30 -118,4,6 -119,-15,15 -120,3,7 -121,4,6 -122,4,6 -123,-19,19 -124,4,6 -125,-49,29 -126,-13,13 -127,-30,20 -128,2,8 -129,-21,21 -130,-45,25 -131,-32,22 -132,-67,37 -133,-46,26 -134,0,10 -135,-12,12 -136,-9,9 -137,-10,10 -138,-14,14 -139,4,6 -140,-11,11 -141,-12,12 -142,2,8 -143,-35,25 -144,4,6 -145,-73,43 -146,4,6 -147,-20,20 -148,4,6 -149,2,8 -150,-29,19 -151,-20,20 -152,4,6 -153,-28,18 -154,4,6 -155,4,6 -156,4,6 -157,4,6 -158,-34,24 -159,4,6 -160,4,6 -161,4,6 -162,-25,15 -163,4,6 -164,3,7 -165,-48,28 -166,4,6 -167,-58,38 -168,-20,20 -169,-9,9 -170,3,7 -171,4,6 -172,3,7 -173,-33,23 -174,-50,30 -175,-16,16 -176,-32,22 -177,-65,35 -178,4,6 -179,-13,13 -180,-11,11 -181,3,7 -182,4,6 -183,-16,16 -184,-12,12 -185,4,6 -186,-48,28 -187,-13,13 -188,2,8 -189,3,7 -190,-27,17 -191,3,7 -192,4,6 -193,4,6 -194,4,6 -195,4,6 -196,4,6 -197,-13,13 -198,-14,14 -199,4,6 -200,4,6 -201,-13,13 -202,-33,23 -203,4,6 -204,-32,22 -205,4,6 -206,-48,28 -207,4,6 -208,4,6 -209,3,7 -210,4,6 -211,-34,24 -212,3,7 -213,4,6 -214,4,6 -215,4,6 -216,3,7 -217,-12,12 -218,3,7 -219,-8,8 -220,3,7 -221,4,6 -222,-46,26 -223,-33,23 -224,4,6 -225,1,9 -226,3,7 -227,2,8 -228,-34,24 -229,4,6 -230,4,6 -231,4,6 -232,4,6 -233,-55,35 -234,-37,27 -235,4,6 -236,-14,14 -237,-65,35 -238,4,6 -239,-13,13 -240,4,6 -241,4,6 -242,-13,13 -243,-30,20 -244,3,7 -245,-13,13 -246,4,6 -247,4,6 -248,-13,13 -249,-32,22 -250,4,6 -251,-55,35 -252,-12,12 -253,3,7 -254,3,7 -255,3,7 -256,4,6 -257,2,8 -258,-12,12 -259,3,7 -260,-10,10 -261,-12,12 -262,4,6 -263,3,7 -264,3,7 -265,-16,16 -266,3,7 -267,-47,27 -268,-13,13 -269,4,6 -270,3,7 -271,-13,13 -272,4,6 -273,4,6 -274,-17,17 -275,4,6 -276,3,7 -277,3,7 -278,4,6 -279,-41,31 -280,3,7 -281,-47,27 -282,-32,22 -283,4,6 -284,3,7 -285,-17,17 -286,3,7 -287,3,7 -288,3,7 -289,-12,12 -290,4,6 -291,3,7 -292,3,7 -293,-24,14 -294,3,7 -295,4,6 -296,3,7 -297,3,7 -298,3,7 -299,-13,13 diff --git a/projects/codes/Sarsa/sarsa.py b/projects/codes/Sarsa/sarsa.py index 37ed818..753ee95 100644 --- a/projects/codes/Sarsa/sarsa.py +++ b/projects/codes/Sarsa/sarsa.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2021-03-12 16:58:16 LastEditor: John -LastEditTime: 2022-08-25 21:26:08 +LastEditTime: 2022-10-30 02:00:51 Discription: Environment: ''' @@ -15,14 +15,14 @@ import torch import math class Sarsa(object): def __init__(self,cfg): - self.n_actions = cfg['n_actions'] - self.lr = cfg['lr'] - self.gamma = cfg['gamma'] - self.epsilon = cfg['epsilon_start'] + self.n_actions = cfg.n_actions + self.lr = cfg.lr + self.gamma = cfg.gamma + self.epsilon = cfg.epsilon_start self.sample_count = 0 - self.epsilon_start = cfg['epsilon_start'] - self.epsilon_end = cfg['epsilon_end'] - self.epsilon_decay = cfg['epsilon_decay'] + self.epsilon_start = cfg.epsilon_start + self.epsilon_end = cfg.epsilon_end + self.epsilon_decay = cfg.epsilon_decay self.Q_table = defaultdict(lambda: np.zeros(self.n_actions)) # Q table def sample_action(self, state): ''' another way to represent e-greedy policy diff --git a/projects/codes/Sarsa/task0.py b/projects/codes/Sarsa/task0.py new file mode 100644 index 0000000..bdd5fda --- /dev/null +++ b/projects/codes/Sarsa/task0.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: JiangJi +Email: johnjim0816@gmail.com +Date: 2022-09-19 14:48:16 +LastEditor: JiangJi +LastEditTime: 2022-10-30 02:11:31 +Discription: +''' +import sys,os +os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # avoid "OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized." +curr_path = os.path.dirname(os.path.abspath(__file__)) # current path +parent_path = os.path.dirname(curr_path) # parent path +sys.path.append(parent_path) # add path to system path +import gym +import datetime +import argparse +from envs.register import register_env +from envs.wrappers import CliffWalkingWapper +from Sarsa.sarsa import Sarsa +from common.utils import all_seed,merge_class_attrs +from common.launcher import Launcher +from config.config import GeneralConfigSarsa,AlgoConfigSarsa + +class Main(Launcher): + def __init__(self) -> None: + super().__init__() + self.cfgs['general_cfg'] = merge_class_attrs(self.cfgs['general_cfg'],GeneralConfigSarsa()) + self.cfgs['algo_cfg'] = merge_class_attrs(self.cfgs['algo_cfg'],AlgoConfigSarsa()) + + def env_agent_config(self,cfg,logger): + register_env(cfg.env_name) + env = gym.make(cfg.env_name,new_step_api=False) # create env + if cfg.env_name == 'CliffWalking-v0': + env = CliffWalkingWapper(env) + if cfg.seed !=0: # set random seed + all_seed(env,seed=cfg.seed) + try: # state dimension + n_states = env.observation_space.n # print(hasattr(env.observation_space, 'n')) + except AttributeError: + n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'shape')) + n_actions = env.action_space.n # action dimension + logger.info(f"n_states: {n_states}, n_actions: {n_actions}") # print info + # update to cfg paramters + setattr(cfg, 'n_states', n_states) + setattr(cfg, 'n_actions', n_actions) + agent = Sarsa(cfg) + return env,agent + + def train(self,cfg,env,agent,logger): + logger.info("Start training!") + logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + rewards = [] # record rewards for all episodes + steps = [] # record steps for all episodes + for i_ep in range(cfg.train_eps): + ep_reward = 0 # reward per episode + ep_step = 0 # step per episode + state = env.reset() # reset and obtain initial state + action = agent.sample_action(state) + # while True: + for _ in range(cfg.max_steps): + next_state, reward, done, _ = env.step(action) # update env and return transitions + next_action = agent.sample_action(next_state) + agent.update(state, action, reward, next_state, next_action,done) # update agent + state = next_state # update state + action = next_action + ep_reward += reward + ep_step += 1 + if done: + break + rewards.append(ep_reward) + steps.append(ep_step) + logger.info(f'Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step:d}, Epislon: {agent.epsilon:.3f}') + logger.info("Finish training!") + return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + + def test(self,cfg,env,agent,logger): + logger.info("Start testing!") + logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + rewards = [] # record rewards for all episodes + steps = [] # record steps for all episodes + for i_ep in range(cfg.test_eps): + ep_reward = 0 # reward per episode + ep_step = 0 + state = env.reset() # reset and obtain initial state + for _ in range(cfg.max_steps): + action = agent.predict_action(state) + next_state, reward, done, _ = env.step(action) + state = next_state + ep_reward+=reward + ep_step+=1 + if done: + break + rewards.append(ep_reward) + steps.append(ep_step) + logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.2f}, Steps:{ep_step:d}") + logger.info("Finish testing!") + return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + +if __name__ == "__main__": + main = Main() + main.run() + + + diff --git a/projects/codes/common/config.py b/projects/codes/common/config.py new file mode 100644 index 0000000..da0beb9 --- /dev/null +++ b/projects/codes/common/config.py @@ -0,0 +1,38 @@ + +class DefaultConfig: + def __init__(self) -> None: + pass + def print_cfg(self): + print(self.__dict__) +class GeneralConfig(DefaultConfig): + def __init__(self) -> None: + self.env_name = "CartPole-v1" # name of environment + self.algo_name = "DQN" # name of algorithm + self.mode = "train" # train or test + self.seed = 0 # random seed + self.device = "cuda" # device to use + self.train_eps = 200 # number of episodes for training + self.test_eps = 20 # number of episodes for testing + self.eval_eps = 10 # number of episodes for evaluation + self.eval_per_episode = 5 # evaluation per episode + self.max_steps = 200 # max steps for each episode + self.load_checkpoint = False + self.load_path = None # path to load model + self.show_fig = False # show figure or not + self.save_fig = True # save figure or not + +class AlgoConfig(DefaultConfig): + def __init__(self) -> None: + # set epsilon_start=epsilon_end can obtain fixed epsilon=epsilon_end + # self.epsilon_start = 0.95 # epsilon start value + # self.epsilon_end = 0.01 # epsilon end value + # self.epsilon_decay = 500 # epsilon decay rate + self.gamma = 0.95 # discount factor + # self.lr = 0.0001 # learning rate + # self.buffer_size = 100000 # size of replay buffer + # self.batch_size = 64 # batch size + # self.target_update = 4 # target network update frequency +class MergedConfig: + def __init__(self) -> None: + pass + \ No newline at end of file diff --git a/projects/codes/common/launcher.py b/projects/codes/common/launcher.py index 43f6f45..148d200 100644 --- a/projects/codes/common/launcher.py +++ b/projects/codes/common/launcher.py @@ -1,32 +1,124 @@ -from common.utils import save_args,save_results,plot_rewards +from common.utils import get_logger,save_results,save_cfgs,plot_rewards,merge_class_attrs,load_cfgs +from common.config import GeneralConfig,AlgoConfig,MergedConfig +import time +from pathlib import Path +import datetime +import argparse + class Launcher: def __init__(self) -> None: - pass - def get_args(self): - cfg = {} - return cfg - def env_agent_config(self,cfg): + self.get_cfg() + def get_cfg(self): + self.cfgs = {'general_cfg':GeneralConfig(),'algo_cfg':AlgoConfig()} # create config + def process_yaml_cfg(self): + ''' load yaml config + ''' + parser = argparse.ArgumentParser(description="hyperparameters") + parser.add_argument('--yaml', default = None, type=str,help='the path of config file') + args = parser.parse_args() + if args.yaml is not None: + load_cfgs(self.cfgs, args.yaml) + def print_cfg(self,cfg): + ''' print parameters + ''' + cfg_dict = vars(cfg) + print("Hyperparameters:") + print(''.join(['=']*80)) + tplt = "{:^20}\t{:^20}\t{:^20}" + print(tplt.format("Name", "Value", "Type")) + for k,v in cfg_dict.items(): + print(tplt.format(k,v,str(type(v)))) + print(''.join(['=']*80)) + def env_agent_config(self,cfg,logger): env,agent = None,None return env,agent - def train(self,cfg, env, agent): - res_dic = {} - return res_dic - def test(self,cfg, env, agent): - res_dic = {} - return res_dic - + def train_one_episode(self,env, agent, cfg): + ep_reward = 0 + ep_step = 0 + return agent,ep_reward,ep_step + def test_one_episode(self,env, agent, cfg): + ep_reward = 0 + ep_step = 0 + return agent,ep_reward,ep_step + def evaluate(self,env, agent, cfg): + sum_eval_reward = 0 + for _ in range(cfg.eval_eps): + _,eval_ep_reward,_ = self.test_one_episode(env, agent, cfg) + sum_eval_reward += eval_ep_reward + mean_eval_reward = sum_eval_reward/cfg.eval_eps + return mean_eval_reward + # def train(self,cfg, env, agent,logger): + # res_dic = {} + # return res_dic + # def test(self,cfg, env, agent,logger): + # res_dic = {} + # return res_dic + def create_path(self,cfg): + curr_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") # obtain current time + self.task_dir = f"{cfg.mode.capitalize()}_{cfg.env_name}_{cfg.algo_name}_{curr_time}" + Path(self.task_dir).mkdir(parents=True, exist_ok=True) + self.model_dir = f"{self.task_dir}/models/" + self.res_dir = f"{self.task_dir}/results/" + self.log_dir = f"{self.task_dir}/logs/" def run(self): - cfg = self.get_args() - env, agent = self.env_agent_config(cfg) - res_dic = self.train(cfg, env, agent) - save_args(cfg,path = cfg['result_path']) # save parameters - agent.save_model(path = cfg['model_path']) # save models - save_results(res_dic, tag = 'train', path = cfg['result_path']) # save results - plot_rewards(res_dic['rewards'], cfg, path = cfg['result_path'],tag = "train") # plot results - # testing - # env, agent = self.env_agent_config(cfg) # create new env for testing, sometimes can ignore this step - agent.load_model(path = cfg['model_path']) # load model - res_dic = self.test(cfg, env, agent) - save_results(res_dic, tag='test', - path = cfg['result_path']) - plot_rewards(res_dic['rewards'], cfg, path = cfg['result_path'],tag = "test") + self.process_yaml_cfg() # load yaml config + cfg = MergedConfig() # merge config + cfg = merge_class_attrs(cfg,self.cfgs['general_cfg']) + cfg = merge_class_attrs(cfg,self.cfgs['algo_cfg']) + self.print_cfg(cfg) # print the configuration + self.create_path(cfg) # create the path to save the results + logger = get_logger(self.log_dir) # create the logger + env, agent = self.env_agent_config(cfg,logger) + if cfg.load_checkpoint: + agent.load_model(f"{cfg.load_path}/models/") + logger.info(f"Start {cfg.mode}ing!") + logger.info(f"Env: {cfg.env_name}, Algorithm: {cfg.algo_name}, Device: {cfg.device}") + rewards = [] # record rewards for all episodes + steps = [] # record steps for all episodes + if cfg.mode.lower() == 'train': + best_ep_reward = -float('inf') + for i_ep in range(cfg.train_eps): + agent,ep_reward,ep_step = self.train_one_episode(env, agent, cfg) + logger.info(f"Episode: {i_ep+1}/{cfg.train_eps}, Reward: {ep_reward:.3f}, Step: {ep_step}") + rewards.append(ep_reward) + steps.append(ep_step) + # for _ in range + if (i_ep+1)%cfg.eval_per_episode == 0: + mean_eval_reward = self.evaluate(env, agent, cfg) + if mean_eval_reward >= best_ep_reward: # update best reward + logger.info(f"Current episode {i_ep+1} has the best eval reward: {mean_eval_reward:.3f}") + best_ep_reward = mean_eval_reward + agent.save_model(self.model_dir) # save models with best reward + # env.close() + elif cfg.mode.lower() == 'test': + for i_ep in range(cfg.test_eps): + agent,ep_reward,ep_step = self.test_one_episode(env, agent, cfg) + logger.info(f"Episode: {i_ep+1}/{cfg.test_eps}, Reward: {ep_reward:.3f}, Step: {ep_step}") + rewards.append(ep_reward) + steps.append(ep_step) + agent.save_model(self.model_dir) # save models + # env.close() + logger.info(f"Finish {cfg.mode}ing!") + res_dic = {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps} + save_results(res_dic, self.res_dir) # save results + save_cfgs(self.cfgs, self.task_dir) # save config + plot_rewards(rewards, title=f"{cfg.mode.lower()}ing curve on {cfg.device} of {cfg.algo_name} for {cfg.env_name}" ,fpath= self.res_dir) + # def run(self): + # self.process_yaml_cfg() # load yaml config + # cfg = MergedConfig() # merge config + # cfg = merge_class_attrs(cfg,self.cfgs['general_cfg']) + # cfg = merge_class_attrs(cfg,self.cfgs['algo_cfg']) + # self.print_cfg(cfg) # print the configuration + # self.create_path(cfg) # create the path to save the results + # logger = get_logger(self.log_dir) # create the logger + # env, agent = self.env_agent_config(cfg,logger) + # if cfg.load_checkpoint: + # agent.load_model(f"{cfg.load_path}/models/") + # if cfg.mode.lower() == 'train': + # res_dic = self.train(cfg, env, agent,logger) + # elif cfg.mode.lower() == 'test': + # res_dic = self.test(cfg, env, agent,logger) + # save_results(res_dic, self.res_dir) # save results + # save_cfgs(self.cfgs, self.task_dir) # save config + # agent.save_model(self.model_dir) # save models + # plot_rewards(res_dic['rewards'], title=f"{cfg.mode.lower()}ing curve on {cfg.device} of {cfg.algo_name} for {cfg.env_name}" ,fpath= self.res_dir) \ No newline at end of file diff --git a/projects/codes/common/models.py b/projects/codes/common/models.py index 3e3e562..41d1b17 100644 --- a/projects/codes/common/models.py +++ b/projects/codes/common/models.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2021-03-12 21:14:12 LastEditor: John -LastEditTime: 2022-08-29 14:24:44 +LastEditTime: 2022-10-31 23:53:06 Discription: Environment: ''' @@ -35,20 +35,65 @@ class ActorSoftmax(nn.Module): def __init__(self, input_dim, output_dim, hidden_dim=256): super(ActorSoftmax, self).__init__() self.fc1 = nn.Linear(input_dim, hidden_dim) - self.fc2 = nn.Linear(hidden_dim, output_dim) - def forward(self,state): - dist = F.relu(self.fc1(state)) - dist = F.softmax(self.fc2(dist),dim=1) - return dist + self.fc2 = nn.Linear(hidden_dim, hidden_dim) + self.fc3 = nn.Linear(hidden_dim, output_dim) + def forward(self,x): + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + probs = F.softmax(self.fc3(x),dim=1) + return probs + +class ActorSoftmaxTanh(nn.Module): + def __init__(self, input_dim, output_dim, hidden_dim=256): + super(ActorSoftmaxTanh, self).__init__() + self.fc1 = nn.Linear(input_dim, hidden_dim) + self.fc2 = nn.Linear(hidden_dim, hidden_dim) + self.fc3 = nn.Linear(hidden_dim, output_dim) + def forward(self,x): + x = F.tanh(self.fc1(x)) + x = F.tanh(self.fc2(x)) + probs = F.softmax(self.fc3(x),dim=1) + return probs +class ActorNormal(nn.Module): + def __init__(self, n_states,n_actions, hidden_dim=256): + super(ActorNormal, self).__init__() + self.fc1 = nn.Linear(n_states, hidden_dim) + self.fc2 = nn.Linear(hidden_dim, hidden_dim) + self.fc3 = nn.Linear(hidden_dim, n_actions) + self.fc4 = nn.Linear(hidden_dim, n_actions) + def forward(self,x): + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + mu = torch.tanh(self.fc3(x)) + sigma = F.softplus(self.fc4(x)) + 0.001 # avoid 0 + return mu,sigma +# class ActorSoftmax(nn.Module): +# def __init__(self,input_dim, output_dim, +# hidden_dim=256): +# super(ActorSoftmax, self).__init__() +# self.actor = nn.Sequential( +# nn.Linear(input_dim, hidden_dim), +# nn.ReLU(), +# nn.Linear(hidden_dim, hidden_dim), +# nn.ReLU(), +# nn.Linear(hidden_dim, output_dim), +# nn.Softmax(dim=-1) +# ) +# def forward(self, state): +# probs = self.actor(state) +# dist = Categorical(probs) +# return dist class Critic(nn.Module): def __init__(self,input_dim,output_dim,hidden_dim=256): super(Critic,self).__init__() assert output_dim == 1 # critic must output a single value self.fc1 = nn.Linear(input_dim, hidden_dim) - self.fc2 = nn.Linear(hidden_dim, output_dim) - def forward(self,state): - value = F.relu(self.fc1(state)) - value = self.fc2(value) + self.fc2 = nn.Linear(hidden_dim, hidden_dim) + self.fc3 = nn.Linear(hidden_dim, output_dim) + def forward(self,x): + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + value = self.fc3(x) return value class ActorCriticSoftmax(nn.Module): @@ -72,18 +117,18 @@ class ActorCriticSoftmax(nn.Module): return value, policy_dist class ActorCritic(nn.Module): - def __init__(self, n_states, n_actions, hidden_dim=256): + def __init__(self, input_dim, output_dim, hidden_dim=256): super(ActorCritic, self).__init__() self.critic = nn.Sequential( - nn.Linear(n_states, hidden_dim), + nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, 1) ) self.actor = nn.Sequential( - nn.Linear(n_states, hidden_dim), + nn.Linear(input_dim, hidden_dim), nn.ReLU(), - nn.Linear(hidden_dim, n_actions), + nn.Linear(hidden_dim, output_dim), nn.Softmax(dim=1), ) diff --git a/projects/codes/common/utils.py b/projects/codes/common/utils.py index e4f75ed..62c343d 100644 --- a/projects/codes/common/utils.py +++ b/projects/codes/common/utils.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2021-03-12 16:02:24 LastEditor: John -LastEditTime: 2022-08-24 10:31:30 +LastEditTime: 2022-10-26 07:38:17 Discription: Environment: ''' @@ -14,8 +14,13 @@ import numpy as np from pathlib import Path import matplotlib.pyplot as plt import seaborn as sns -import json +import yaml import pandas as pd +from functools import wraps +from time import time +import logging +from pathlib import Path + from matplotlib.font_manager import FontProperties # 导入字体模块 @@ -61,17 +66,17 @@ def smooth(data, weight=0.9): last = smoothed_val return smoothed -def plot_rewards(rewards,cfg,path=None,tag='train'): +def plot_rewards(rewards,title="learning curve",fpath=None,save_fig=True,show_fig=False): sns.set() plt.figure() # 创建一个图形实例,方便同时多画几个图 - plt.title(f"{tag}ing curve on {cfg['device']} of {cfg['algo_name']} for {cfg['env_name']}") + plt.title(f"{title}") plt.xlabel('epsiodes') plt.plot(rewards, label='rewards') plt.plot(smooth(rewards), label='smoothed') plt.legend() - if cfg['save_fig']: - plt.savefig(f"{path}/{tag}ing_curve.png") - if cfg['show_fig']: + if save_fig: + plt.savefig(f"{fpath}/learning_curve.png") + if show_fig: plt.show() def plot_losses(losses, algo="DQN", save=True, path='./'): @@ -85,48 +90,86 @@ def plot_losses(losses, algo="DQN", save=True, path='./'): plt.savefig(path+"losses_curve") plt.show() -def save_results(res_dic, tag='train', path = None): - ''' 保存奖励 +def save_results(res_dic,fpath = None): + ''' save results ''' - Path(path).mkdir(parents=True, exist_ok=True) + Path(fpath).mkdir(parents=True, exist_ok=True) df = pd.DataFrame(res_dic) - df.to_csv(f"{path}/{tag}ing_results.csv",index=None) - print('Results saved!') - - -def make_dir(*paths): - ''' 创建文件夹 + df.to_csv(f"{fpath}/res.csv",index=None) +def merge_class_attrs(ob1, ob2): + ob1.__dict__.update(ob2.__dict__) + return ob1 +def get_logger(fpath): + Path(fpath).mkdir(parents=True, exist_ok=True) + logger = logging.getLogger(name='r') # set root logger if not set name + logger.setLevel(logging.DEBUG) + formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s: - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + # output to file by using FileHandler + fh = logging.FileHandler(fpath+"log.txt") + fh.setLevel(logging.DEBUG) + fh.setFormatter(formatter) + # output to screen by using StreamHandler + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + ch.setFormatter(formatter) + # add Handler + logger.addHandler(ch) + logger.addHandler(fh) + return logger +def save_cfgs(cfgs, fpath): + ''' save config ''' - for path in paths: - Path(path).mkdir(parents=True, exist_ok=True) + Path(fpath).mkdir(parents=True, exist_ok=True) + + with open(f"{fpath}/config.yaml", 'w') as f: + for cfg_type in cfgs: + yaml.dump({cfg_type: cfgs[cfg_type].__dict__}, f, default_flow_style=False) +def load_cfgs(cfgs, fpath): + with open(fpath) as f: + load_cfg = yaml.load(f,Loader=yaml.FullLoader) + for cfg_type in cfgs: + for k, v in load_cfg[cfg_type].items(): + setattr(cfgs[cfg_type], k, v) +# def del_empty_dir(*paths): +# ''' 删除目录下所有空文件夹 +# ''' +# for path in paths: +# dirs = os.listdir(path) +# for dir in dirs: +# if not os.listdir(os.path.join(path, dir)): +# os.removedirs(os.path.join(path, dir)) - -def del_empty_dir(*paths): - ''' 删除目录下所有空文件夹 - ''' - for path in paths: - dirs = os.listdir(path) - for dir in dirs: - if not os.listdir(os.path.join(path, dir)): - os.removedirs(os.path.join(path, dir)) - -class NpEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, np.integer): - return int(obj) - if isinstance(obj, np.floating): - return float(obj) - if isinstance(obj, np.ndarray): - return obj.tolist() - return json.JSONEncoder.default(self, obj) +# class NpEncoder(json.JSONEncoder): +# def default(self, obj): +# if isinstance(obj, np.integer): +# return int(obj) +# if isinstance(obj, np.floating): +# return float(obj) +# if isinstance(obj, np.ndarray): +# return obj.tolist() +# return json.JSONEncoder.default(self, obj) -def save_args(args,path=None): - # save parameters - Path(path).mkdir(parents=True, exist_ok=True) - with open(f"{path}/params.json", 'w') as fp: - json.dump(args, fp,cls=NpEncoder) - print("Parameters saved!") +# def save_args(args,path=None): +# # save parameters +# Path(path).mkdir(parents=True, exist_ok=True) +# with open(f"{path}/params.json", 'w') as fp: +# json.dump(args, fp,cls=NpEncoder) +# print("Parameters saved!") + +def timing(func): + ''' a decorator to print the running time of a function + ''' + @wraps(func) + def wrap(*args, **kw): + ts = time() + result = func(*args, **kw) + te = time() + print(f"func: {func.__name__}, took: {te-ts:2.4f} seconds") + return result + return wrap def all_seed(env,seed = 1): ''' omnipotent seed for RL, attention the position of seed function, you'd better put it just following the env create function Args: @@ -136,7 +179,7 @@ def all_seed(env,seed = 1): import torch import numpy as np import random - print(f"seed = {seed}") + # print(f"seed = {seed}") env.seed(seed) # env config np.random.seed(seed) random.seed(seed) diff --git a/projects/codes/scripts/A2C_CartPole-v0.sh b/projects/codes/scripts/A2C_CartPole-v0.sh deleted file mode 100644 index 4fcc9a1..0000000 --- a/projects/codes/scripts/A2C_CartPole-v0.sh +++ /dev/null @@ -1,15 +0,0 @@ -# run A2C on CartPole-v0 -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" - -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created -codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path -python $codes_dir/A2C/main.py \ No newline at end of file diff --git a/projects/codes/scripts/DQN_Acrobot-v1.sh b/projects/codes/scripts/DQN_Acrobot-v1.sh index 83cd297..623a0cc 100644 --- a/projects/codes/scripts/DQN_Acrobot-v1.sh +++ b/projects/codes/scripts/DQN_Acrobot-v1.sh @@ -1,15 +1,3 @@ # run DQN on Acrobot-v1, not the best tuned parameters - -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/DQN/main.py --env_name Acrobot-v1 --train_eps 100 --epsilon_decay 1500 --lr 0.002 --memory_capacity 200000 --batch_size 128 --device cuda \ No newline at end of file diff --git a/projects/codes/scripts/DQN_CartPole-v0.sh b/projects/codes/scripts/DQN_CartPole-v0.sh deleted file mode 100644 index ead51b9..0000000 --- a/projects/codes/scripts/DQN_CartPole-v0.sh +++ /dev/null @@ -1,15 +0,0 @@ -# run DQN on CartPole-v0 -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" - -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created -codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path -python $codes_dir/DQN/main.py \ No newline at end of file diff --git a/projects/codes/scripts/DQN_CartPole-v1.sh b/projects/codes/scripts/DQN_CartPole-v1.sh index 8cac524..e4fe811 100644 --- a/projects/codes/scripts/DQN_CartPole-v1.sh +++ b/projects/codes/scripts/DQN_CartPole-v1.sh @@ -1,14 +1,3 @@ # run DQN on CartPole-v1, not finished yet -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/DQN/main.py --env_name CartPole-v1 --train_eps 2000 --gamma 0.99 --epsilon_decay 6000 --lr 0.00001 --memory_capacity 200000 --batch_size 64 --device cuda \ No newline at end of file diff --git a/projects/codes/scripts/DoubleDQN_CartPole-v0.sh b/projects/codes/scripts/DoubleDQN_CartPole-v0.sh index 0da88f2..0154227 100644 --- a/projects/codes/scripts/DoubleDQN_CartPole-v0.sh +++ b/projects/codes/scripts/DoubleDQN_CartPole-v0.sh @@ -1,15 +1,3 @@ # run Double DQN on CartPole-v0 -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" - -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/DoubleDQN/main.py --device cuda \ No newline at end of file diff --git a/projects/codes/scripts/Qlearning_CliffWalking-v0.sh b/projects/codes/scripts/Qlearning_CliffWalking-v0.sh index 233cec7..6ba8b53 100644 --- a/projects/codes/scripts/Qlearning_CliffWalking-v0.sh +++ b/projects/codes/scripts/Qlearning_CliffWalking-v0.sh @@ -1,12 +1,2 @@ -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/QLearning/main.py --env_name CliffWalking-v0 --train_eps 400 --gamma 0.90 --epsilon_start 0.95 --epsilon_end 0.01 --epsilon_decay 300 --lr 0.1 --device cpu \ No newline at end of file diff --git a/projects/codes/scripts/Qlearning_FrozenLakeNoSlippery-v1.sh b/projects/codes/scripts/Qlearning_FrozenLakeNoSlippery-v1.sh index 0df0547..c4638fe 100644 --- a/projects/codes/scripts/Qlearning_FrozenLakeNoSlippery-v1.sh +++ b/projects/codes/scripts/Qlearning_FrozenLakeNoSlippery-v1.sh @@ -1,14 +1,2 @@ - -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/QLearning/main.py --env_name FrozenLakeNoSlippery-v1 --train_eps 800 --epsilon_start 0.70 --epsilon_end 0.1 --epsilon_decay 2000 --gamma 0.9 --lr 0.9 --device cpu \ No newline at end of file diff --git a/projects/codes/scripts/Qlearning_Racetrack-v0.sh b/projects/codes/scripts/Qlearning_Racetrack-v0.sh index 00599fa..aba42b2 100644 --- a/projects/codes/scripts/Qlearning_Racetrack-v0.sh +++ b/projects/codes/scripts/Qlearning_Racetrack-v0.sh @@ -1,14 +1,2 @@ - -# source conda, if you are already in proper conda environment, then comment the codes util "conda activate easyrl" -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/QLearning/main.py --env_name Racetrack-v0 --device cpu \ No newline at end of file diff --git a/projects/codes/scripts/Sarsa_CliffWalking-v0.sh b/projects/codes/scripts/Sarsa_CliffWalking-v0.sh index c4f5e6a..9207c9d 100644 --- a/projects/codes/scripts/Sarsa_CliffWalking-v0.sh +++ b/projects/codes/scripts/Sarsa_CliffWalking-v0.sh @@ -1,12 +1,2 @@ -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/Sarsa/main.py --env_name CliffWalking-v0 --train_eps 400 --gamma 0.90 --epsilon_start 0.95 --epsilon_end 0.01 --epsilon_decay 300 --lr 0.1 --device cpu \ No newline at end of file diff --git a/projects/codes/scripts/Sarsa_FrozenLakeNoSlippery-v1.sh b/projects/codes/scripts/Sarsa_FrozenLakeNoSlippery-v1.sh index f215c94..9c77e75 100644 --- a/projects/codes/scripts/Sarsa_FrozenLakeNoSlippery-v1.sh +++ b/projects/codes/scripts/Sarsa_FrozenLakeNoSlippery-v1.sh @@ -1,13 +1,2 @@ -# Sarsa for FrozenLakeNoSlippery-v1, cannot converge like Qlearning! -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/Sarsa/main.py --env_name FrozenLakeNoSlippery-v1 --train_eps 800 --ep_max_steps 10 --epsilon_start 0.50 --epsilon_end 0.01 --epsilon_decay 2000 --gamma 0.9 --lr 0.1 --device cpu \ No newline at end of file diff --git a/projects/codes/scripts/Sarsa_Racetrack-v0.sh b/projects/codes/scripts/Sarsa_Racetrack-v0.sh index dcd6cac..ff8317e 100644 --- a/projects/codes/scripts/Sarsa_Racetrack-v0.sh +++ b/projects/codes/scripts/Sarsa_Racetrack-v0.sh @@ -1,12 +1,2 @@ -if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/anaconda3/etc/profile.d/conda.sh" - source ~/anaconda3/etc/profile.d/conda.sh -elif [ -f "$HOME/opt/anaconda3/etc/profile.d/conda.sh" ]; then - echo "source file at ~/opt/anaconda3/etc/profile.d/conda.sh" - source ~/opt/anaconda3/etc/profile.d/conda.sh -else - echo 'please manually config the conda source path' -fi -conda activate easyrl # easyrl here can be changed to another name of conda env that you have created codes_dir=$(dirname $(dirname $(readlink -f "$0"))) # "codes" path python $codes_dir/Sarsa/main.py --env_name Racetrack-v0 \ No newline at end of file diff --git a/projects/notebooks/1.QLearning.ipynb b/projects/notebooks/1.QLearning.ipynb index c5cc3f7..4116815 100644 --- a/projects/notebooks/1.QLearning.ipynb +++ b/projects/notebooks/1.QLearning.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -31,7 +31,7 @@ " self.epsilon_end = cfg.epsilon_end\n", " self.epsilon_decay = cfg.epsilon_decay\n", " self.Q_table = defaultdict(lambda: np.zeros(n_actions)) # 用嵌套字典存放状态->动作->状态-动作值(Q值)的映射,即Q表\n", - " def sample(self, state):\n", + " def sample_action(self, state):\n", " ''' 采样动作,训练时用\n", " '''\n", " self.sample_count += 1\n", @@ -43,7 +43,7 @@ " else:\n", " action = np.random.choice(self.n_actions) # 随机选择动作\n", " return action\n", - " def predict(self,state):\n", + " def predict_action(self,state):\n", " ''' 预测或选择动作,测试时用\n", " '''\n", " action = np.argmax(self.Q_table[str(state)])\n", @@ -54,19 +54,7 @@ " Q_target = reward \n", " else:\n", " Q_target = reward + self.gamma * np.max(self.Q_table[str(next_state)]) \n", - " self.Q_table[str(state)][action] += self.lr * (Q_target - Q_predict)\n", - " def save(self,path):\n", - " import dill\n", - " torch.save(\n", - " obj=self.Q_table,\n", - " f=path+\"Qleaning_model.pkl\",\n", - " pickle_module=dill\n", - " )\n", - " print(\"保存模型成功!\")\n", - " def load(self, path):\n", - " import dill\n", - " self.Q_table =torch.load(f=path+'Qleaning_model.pkl',pickle_module=dill)\n", - " print(\"加载模型成功!\")" + " self.Q_table[str(state)][action] += self.lr * (Q_target - Q_predict)" ] }, { @@ -99,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -111,7 +99,7 @@ " ep_reward = 0 # 记录每个回合的奖励\n", " state = env.reset() # 重置环境,即开始新的回合\n", " while True:\n", - " action = agent.sample(state) # 根据算法采样一个动作\n", + " action = agent.sample_action(state) # 根据算法采样一个动作\n", " next_state, reward, done, _ = env.step(action) # 与环境进行一次动作交互\n", " agent.update(state, action, reward, next_state, done) # Q学习算法更新\n", " state = next_state # 更新状态\n", @@ -119,7 +107,8 @@ " if done:\n", " break\n", " rewards.append(ep_reward)\n", - " print(f\"回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.1f},Epsilon:{agent.epsilon}\")\n", + " if (i_ep+1)%20==0:\n", + " print(f\"回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.1f},Epsilon:{agent.epsilon:.3f}\")\n", " print('完成训练!')\n", " return {\"rewards\":rewards}\n", "def test(cfg,env,agent):\n", @@ -130,7 +119,7 @@ " ep_reward = 0 # 记录每个episode的reward\n", " state = env.reset() # 重置环境, 重新开一局(即开始新的一个回合)\n", " while True:\n", - " action = agent.predict(state) # 根据算法选择一个动作\n", + " action = agent.predict_action(state) # 根据算法选择一个动作\n", " next_state, reward, done, _ = env.step(action) # 与环境进行一个交互\n", " state = next_state # 更新状态\n", " ep_reward += reward\n", @@ -153,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -163,74 +152,6 @@ "\n", "# turtle tutorial : https://docs.python.org/3.3/library/turtle.html\n", "\n", - "def GridWorld(gridmap=None, is_slippery=False):\n", - " if gridmap is None:\n", - " gridmap = ['SFFF', 'FHFH', 'FFFH', 'HFFG']\n", - " env = gym.make(\"FrozenLake-v0\", desc=gridmap, is_slippery=False)\n", - " env = FrozenLakeWapper(env)\n", - " return env\n", - "\n", - "\n", - "class FrozenLakeWapper(gym.Wrapper):\n", - " def __init__(self, env):\n", - " gym.Wrapper.__init__(self, env)\n", - " self.max_y = env.desc.shape[0]\n", - " self.max_x = env.desc.shape[1]\n", - " self.t = None\n", - " self.unit = 50\n", - "\n", - " def draw_box(self, x, y, fillcolor='', line_color='gray'):\n", - " self.t.up()\n", - " self.t.goto(x * self.unit, y * self.unit)\n", - " self.t.color(line_color)\n", - " self.t.fillcolor(fillcolor)\n", - " self.t.setheading(90)\n", - " self.t.down()\n", - " self.t.begin_fill()\n", - " for _ in range(4):\n", - " self.t.forward(self.unit)\n", - " self.t.right(90)\n", - " self.t.end_fill()\n", - "\n", - " def move_player(self, x, y):\n", - " self.t.up()\n", - " self.t.setheading(90)\n", - " self.t.fillcolor('red')\n", - " self.t.goto((x + 0.5) * self.unit, (y + 0.5) * self.unit)\n", - "\n", - " def render(self):\n", - " if self.t == None:\n", - " self.t = turtle.Turtle()\n", - " self.wn = turtle.Screen()\n", - " self.wn.setup(self.unit * self.max_x + 100,\n", - " self.unit * self.max_y + 100)\n", - " self.wn.setworldcoordinates(0, 0, self.unit * self.max_x,\n", - " self.unit * self.max_y)\n", - " self.t.shape('circle')\n", - " self.t.width(2)\n", - " self.t.speed(0)\n", - " self.t.color('gray')\n", - " for i in range(self.desc.shape[0]):\n", - " for j in range(self.desc.shape[1]):\n", - " x = j\n", - " y = self.max_y - 1 - i\n", - " if self.desc[i][j] == b'S': # Start\n", - " self.draw_box(x, y, 'white')\n", - " elif self.desc[i][j] == b'F': # Frozen ice\n", - " self.draw_box(x, y, 'white')\n", - " elif self.desc[i][j] == b'G': # Goal\n", - " self.draw_box(x, y, 'yellow')\n", - " elif self.desc[i][j] == b'H': # Hole\n", - " self.draw_box(x, y, 'black')\n", - " else:\n", - " self.draw_box(x, y, 'white')\n", - " self.t.shape('turtle')\n", - "\n", - " x_pos = self.s % self.max_x\n", - " y_pos = self.max_y - 1 - int(self.s / self.max_x)\n", - " self.move_player(x_pos, y_pos)\n", - "\n", - "\n", "class CliffWalkingWapper(gym.Wrapper):\n", " def __init__(self, env):\n", " gym.Wrapper.__init__(self, env)\n", @@ -312,7 +233,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -346,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -399,8 +320,7 @@ " plt.xlabel('epsiodes')\n", " plt.plot(rewards, label='rewards')\n", " plt.plot(smooth(rewards), label='smoothed')\n", - " plt.legend()\n", - " plt.show()" + " plt.legend()" ] }, { @@ -414,7 +334,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -423,425 +343,27 @@ "text": [ "开始训练!\n", "环境:CliffWalking-v0, 算法:Q-learning, 设备:cpu\n", - "回合:1/400,奖励:-1668.0,Epsilon:0.3771901652370099\n", - "回合:2/400,奖励:-2328.0,Epsilon:0.03210668110464856\n", - "回合:3/400,奖励:-152.0,Epsilon:0.02331928797825333\n", - "回合:4/400,奖励:-296.0,Epsilon:0.014965661602689185\n", - "回合:5/400,奖励:-168.0,Epsilon:0.012836430915462094\n", - "回合:6/400,奖励:-149.0,Epsilon:0.011726126490407173\n", - "回合:7/400,奖励:-274.0,Epsilon:0.010963239247691907\n", - "回合:8/400,奖励:-127.0,Epsilon:0.010630787152305933\n", - "回合:9/400,奖励:-356.0,Epsilon:0.010267816440118822\n", - "回合:10/400,奖励:-105.0,Epsilon:0.0101887270555826\n", - "回合:11/400,奖励:-162.0,Epsilon:0.01010998036181645\n", - "回合:12/400,奖励:-124.0,Epsilon:0.010072745604688937\n", - "回合:13/400,奖励:-125.0,Epsilon:0.010047956858279448\n", - "回合:14/400,奖励:-69.0,Epsilon:0.010038103335373512\n", - "回合:15/400,奖励:-146.0,Epsilon:0.010023421049147612\n", - "回合:16/400,奖励:-99.0,Epsilon:0.010016837948094095\n", - "回合:17/400,奖励:-102.0,Epsilon:0.010011984751749595\n", - "回合:18/400,奖励:-114.0,Epsilon:0.010008195909220538\n", - "回合:19/400,奖励:-95.0,Epsilon:0.010005971322860786\n", - "回合:20/400,奖励:-50.0,Epsilon:0.010005054615675078\n", - "回合:21/400,奖励:-179.0,Epsilon:0.010002783294099886\n", - "回合:22/400,奖励:-51.0,Epsilon:0.010002348167306314\n", - "回合:23/400,奖励:-53.0,Epsilon:0.010001967902958245\n", - "回合:24/400,奖励:-126.0,Epsilon:0.01000129300438042\n", - "回合:25/400,奖励:-105.0,Epsilon:0.010000911164786836\n", - "回合:26/400,奖励:-55.0,Epsilon:0.010000758536131584\n", - "回合:27/400,奖励:-112.0,Epsilon:0.010000522203364875\n", - "回合:28/400,奖励:-81.0,Epsilon:0.01000039863934062\n", - "回合:29/400,奖励:-187.0,Epsilon:0.010000297294659517\n", - "回合:30/400,奖励:-176.0,Epsilon:0.01000022999489198\n", - "回合:31/400,奖励:-71.0,Epsilon:0.010000181524464132\n", - "回合:32/400,奖励:-77.0,Epsilon:0.010000140432053464\n", - "回合:33/400,奖励:-82.0,Epsilon:0.010000106846201706\n", - "回合:34/400,奖励:-95.0,Epsilon:0.010000077845318887\n", - "回合:35/400,奖励:-53.0,Epsilon:0.010000065238977184\n", - "回合:36/400,奖励:-30.0,Epsilon:0.010000059030667672\n", - "回合:37/400,奖励:-122.0,Epsilon:0.010000039306520976\n", - "回合:38/400,奖励:-37.0,Epsilon:0.010000034745744355\n", - "回合:39/400,奖励:-100.0,Epsilon:0.01000002489641374\n", - "回合:40/400,奖励:-201.0,Epsilon:0.010000017720528442\n", - "回合:41/400,奖励:-62.0,Epsilon:0.010000014411941012\n", - "回合:42/400,奖励:-61.0,Epsilon:0.010000011760233133\n", - "回合:43/400,奖励:-57.0,Epsilon:0.010000009725232207\n", - "回合:44/400,奖励:-73.0,Epsilon:0.0100000076246806\n", - "回合:45/400,奖励:-39.0,Epsilon:0.010000006695197199\n", - "回合:46/400,奖励:-71.0,Epsilon:0.010000005284213373\n", - "回合:47/400,奖励:-77.0,Epsilon:0.010000004088005098\n", - "回合:48/400,奖励:-53.0,Epsilon:0.010000003425989836\n", - "回合:49/400,奖励:-88.0,Epsilon:0.010000002555012459\n", - "回合:50/400,奖励:-65.0,Epsilon:0.01000000205729175\n", - "回合:51/400,奖励:-41.0,Epsilon:0.010000001794495218\n", - "回合:52/400,奖励:-67.0,Epsilon:0.010000001435323749\n", - "回合:53/400,奖励:-38.0,Epsilon:0.010000001264559407\n", - "回合:54/400,奖励:-50.0,Epsilon:0.010000001070426428\n", - "回合:55/400,奖励:-35.0,Epsilon:0.010000000952552966\n", - "回合:56/400,奖励:-74.0,Epsilon:0.010000000744325952\n", - "回合:57/400,奖励:-75.0,Epsilon:0.010000000579681634\n", - "回合:58/400,奖励:-31.0,Epsilon:0.010000000522772152\n", - "回合:59/400,奖励:-38.0,Epsilon:0.010000000460576537\n", - "回合:60/400,奖励:-51.0,Epsilon:0.01000000038857222\n", - "回合:61/400,奖励:-64.0,Epsilon:0.010000000313922366\n", - "回合:62/400,奖励:-78.0,Epsilon:0.010000000242050338\n", - "回合:63/400,奖励:-41.0,Epsilon:0.010000000211131054\n", - "回合:64/400,奖励:-62.0,Epsilon:0.010000000171710922\n", - "回合:65/400,奖励:-58.0,Epsilon:0.010000000141525377\n", - "回合:66/400,奖励:-34.0,Epsilon:0.010000000126361357\n", - "回合:67/400,奖励:-52.0,Epsilon:0.010000000106251867\n", - "回合:68/400,奖励:-28.0,Epsilon:0.010000000096783744\n", - "回合:69/400,奖励:-57.0,Epsilon:0.010000000080036202\n", - "回合:70/400,奖励:-39.0,Epsilon:0.010000000070279423\n", - "回合:71/400,奖励:-55.0,Epsilon:0.01000000005850696\n", - "回合:72/400,奖励:-33.0,Epsilon:0.010000000052412531\n", - "回合:73/400,奖励:-62.0,Epsilon:0.010000000042626625\n", - "回合:74/400,奖励:-56.0,Epsilon:0.010000000035368174\n", - "回合:75/400,奖励:-34.0,Epsilon:0.01000000003157858\n", - "回合:76/400,奖励:-37.0,Epsilon:0.010000000027914485\n", - "回合:77/400,奖励:-149.0,Epsilon:0.0100000000236291\n", - "回合:78/400,奖励:-46.0,Epsilon:0.010000000020270076\n", - "回合:79/400,奖励:-28.0,Epsilon:0.010000000018463805\n", - "回合:80/400,奖励:-37.0,Epsilon:0.010000000016321432\n", - "回合:81/400,奖励:-64.0,Epsilon:0.01000000001318587\n", - "回合:82/400,奖励:-52.0,Epsilon:0.010000000011087433\n", - "回合:83/400,奖励:-22.0,Epsilon:0.010000000010303453\n", - "回合:84/400,奖励:-32.0,Epsilon:0.010000000009261004\n", - "回合:85/400,奖励:-74.0,Epsilon:0.010000000007236559\n", - "回合:86/400,奖励:-33.0,Epsilon:0.010000000006482756\n", - "回合:87/400,奖励:-39.0,Epsilon:0.010000000005692478\n", - "回合:88/400,奖励:-40.0,Epsilon:0.010000000004981906\n", - "回合:89/400,奖励:-33.0,Epsilon:0.010000000004462961\n", - "回合:90/400,奖励:-47.0,Epsilon:0.010000000003815783\n", - "回合:91/400,奖励:-45.0,Epsilon:0.010000000003284274\n", - "回合:92/400,奖励:-28.0,Epsilon:0.010000000002991612\n", - "回合:93/400,奖励:-45.0,Epsilon:0.010000000002574904\n", - "回合:94/400,奖励:-56.0,Epsilon:0.010000000002136451\n", - "回合:95/400,奖励:-31.0,Epsilon:0.010000000001926707\n", - "回合:96/400,奖励:-38.0,Epsilon:0.010000000001697481\n", - "回合:97/400,奖励:-50.0,Epsilon:0.010000000001436887\n", - "回合:98/400,奖励:-41.0,Epsilon:0.010000000001253341\n", - "回合:99/400,奖励:-41.0,Epsilon:0.01000000000109324\n", - "回合:100/400,奖励:-13.0,Epsilon:0.010000000001046878\n", - "回合:101/400,奖励:-45.0,Epsilon:0.010000000000901057\n", - "回合:102/400,奖励:-19.0,Epsilon:0.01000000000084576\n", - "回合:103/400,奖励:-44.0,Epsilon:0.010000000000730383\n", - "回合:104/400,奖励:-23.0,Epsilon:0.010000000000676478\n", - "回合:105/400,奖励:-40.0,Epsilon:0.010000000000592037\n", - "回合:106/400,奖励:-52.0,Epsilon:0.010000000000497817\n", - "回合:107/400,奖励:-38.0,Epsilon:0.010000000000438592\n", - "回合:108/400,奖励:-24.0,Epsilon:0.01000000000040487\n", - "回合:109/400,奖励:-32.0,Epsilon:0.010000000000363909\n", - "回合:110/400,奖励:-38.0,Epsilon:0.010000000000320614\n", - "回合:111/400,奖励:-52.0,Epsilon:0.01000000000026959\n", - "回合:112/400,奖励:-22.0,Epsilon:0.010000000000250527\n", - "回合:113/400,奖励:-38.0,Epsilon:0.010000000000220721\n", - "回合:114/400,奖励:-33.0,Epsilon:0.01000000000019773\n", - "回合:115/400,奖励:-29.0,Epsilon:0.010000000000179511\n", - "回合:116/400,奖励:-56.0,Epsilon:0.010000000000148944\n", - "回合:117/400,奖励:-20.0,Epsilon:0.010000000000139338\n", - "回合:118/400,奖励:-31.0,Epsilon:0.010000000000125658\n", - "回合:119/400,奖励:-33.0,Epsilon:0.01000000000011257\n", - "回合:120/400,奖励:-39.0,Epsilon:0.010000000000098846\n", - "回合:121/400,奖励:-26.0,Epsilon:0.010000000000090641\n", - "回合:122/400,奖励:-31.0,Epsilon:0.010000000000081742\n", - "回合:123/400,奖励:-40.0,Epsilon:0.010000000000071538\n", - "回合:124/400,奖励:-33.0,Epsilon:0.010000000000064086\n", - "回合:125/400,奖励:-46.0,Epsilon:0.010000000000054977\n", - "回合:126/400,奖励:-28.0,Epsilon:0.010000000000050078\n", - "回合:127/400,奖励:-23.0,Epsilon:0.010000000000046382\n", - "回合:128/400,奖励:-30.0,Epsilon:0.010000000000041968\n", - "回合:129/400,奖励:-24.0,Epsilon:0.010000000000038742\n", - "回合:130/400,奖励:-36.0,Epsilon:0.01000000000003436\n", - "回合:131/400,奖励:-28.0,Epsilon:0.010000000000031298\n", - "回合:132/400,奖励:-28.0,Epsilon:0.01000000000002851\n", - "回合:133/400,奖励:-35.0,Epsilon:0.01000000000002537\n", - "回合:134/400,奖励:-27.0,Epsilon:0.010000000000023187\n", - "回合:135/400,奖励:-30.0,Epsilon:0.01000000000002098\n", - "回合:136/400,奖励:-35.0,Epsilon:0.01000000000001867\n", - "回合:137/400,奖励:-31.0,Epsilon:0.010000000000016837\n", - "回合:138/400,奖励:-27.0,Epsilon:0.010000000000015387\n", - "回合:139/400,奖励:-48.0,Epsilon:0.010000000000013113\n", - "回合:140/400,奖励:-23.0,Epsilon:0.010000000000012145\n", - "回合:141/400,奖励:-29.0,Epsilon:0.010000000000011026\n", - "回合:142/400,奖励:-21.0,Epsilon:0.01000000000001028\n", - "回合:143/400,奖励:-22.0,Epsilon:0.010000000000009553\n", - "回合:144/400,奖励:-42.0,Epsilon:0.010000000000008306\n", - "回合:145/400,奖励:-21.0,Epsilon:0.010000000000007744\n", - "回合:146/400,奖励:-141.0,Epsilon:0.010000000000006733\n", - "回合:147/400,奖励:-43.0,Epsilon:0.010000000000005834\n", - "回合:148/400,奖励:-44.0,Epsilon:0.010000000000005038\n", - "回合:149/400,奖励:-18.0,Epsilon:0.010000000000004745\n", - "回合:150/400,奖励:-23.0,Epsilon:0.010000000000004394\n", - "回合:151/400,奖励:-24.0,Epsilon:0.010000000000004056\n", - "回合:152/400,奖励:-30.0,Epsilon:0.010000000000003671\n", - "回合:153/400,奖励:-27.0,Epsilon:0.010000000000003355\n", - "回合:154/400,奖励:-15.0,Epsilon:0.01000000000000319\n", - "回合:155/400,奖励:-19.0,Epsilon:0.010000000000002994\n", - "回合:156/400,奖励:-50.0,Epsilon:0.010000000000002535\n", - "回合:157/400,奖励:-22.0,Epsilon:0.010000000000002356\n", - "回合:158/400,奖励:-28.0,Epsilon:0.010000000000002146\n", - "回合:159/400,奖励:-27.0,Epsilon:0.010000000000001962\n", - "回合:160/400,奖励:-13.0,Epsilon:0.010000000000001879\n", - "回合:161/400,奖励:-33.0,Epsilon:0.010000000000001683\n", - "回合:162/400,奖励:-24.0,Epsilon:0.010000000000001553\n", - "回合:163/400,奖励:-30.0,Epsilon:0.010000000000001405\n", - "回合:164/400,奖励:-19.0,Epsilon:0.010000000000001319\n", - "回合:165/400,奖励:-22.0,Epsilon:0.010000000000001227\n", - "回合:166/400,奖励:-32.0,Epsilon:0.010000000000001102\n", - "回合:167/400,奖励:-35.0,Epsilon:0.01000000000000098\n", - "回合:168/400,奖励:-32.0,Epsilon:0.010000000000000881\n", - "回合:169/400,奖励:-21.0,Epsilon:0.010000000000000822\n", - "回合:170/400,奖励:-27.0,Epsilon:0.010000000000000751\n", - "回合:171/400,奖励:-22.0,Epsilon:0.010000000000000698\n", - "回合:172/400,奖励:-22.0,Epsilon:0.010000000000000649\n", - "回合:173/400,奖励:-34.0,Epsilon:0.01000000000000058\n", - "回合:174/400,奖励:-22.0,Epsilon:0.010000000000000538\n", - "回合:175/400,奖励:-27.0,Epsilon:0.010000000000000491\n", - "回合:176/400,奖励:-13.0,Epsilon:0.01000000000000047\n", - "回合:177/400,奖励:-29.0,Epsilon:0.010000000000000427\n", - "回合:178/400,奖励:-20.0,Epsilon:0.010000000000000401\n", - "回合:179/400,奖励:-22.0,Epsilon:0.010000000000000371\n", - "回合:180/400,奖励:-33.0,Epsilon:0.010000000000000333\n", - "回合:181/400,奖励:-20.0,Epsilon:0.010000000000000312\n", - "回合:182/400,奖励:-26.0,Epsilon:0.010000000000000286\n", - "回合:183/400,奖励:-22.0,Epsilon:0.010000000000000266\n", - "回合:184/400,奖励:-29.0,Epsilon:0.010000000000000241\n", - "回合:185/400,奖励:-25.0,Epsilon:0.010000000000000222\n", - "回合:186/400,奖励:-16.0,Epsilon:0.01000000000000021\n", - "回合:187/400,奖励:-28.0,Epsilon:0.010000000000000191\n", - "回合:188/400,奖励:-23.0,Epsilon:0.010000000000000177\n", - "回合:189/400,奖励:-31.0,Epsilon:0.01000000000000016\n", - "回合:190/400,奖励:-17.0,Epsilon:0.010000000000000151\n", - "回合:191/400,奖励:-22.0,Epsilon:0.01000000000000014\n", - "回合:192/400,奖励:-18.0,Epsilon:0.010000000000000132\n", - "回合:193/400,奖励:-34.0,Epsilon:0.010000000000000118\n", - "回合:194/400,奖励:-32.0,Epsilon:0.010000000000000106\n", - "回合:195/400,奖励:-14.0,Epsilon:0.0100000000000001\n", - "回合:196/400,奖励:-23.0,Epsilon:0.010000000000000094\n", - "回合:197/400,奖励:-23.0,Epsilon:0.010000000000000087\n", - "回合:198/400,奖励:-28.0,Epsilon:0.01000000000000008\n", - "回合:199/400,奖励:-24.0,Epsilon:0.010000000000000073\n", - "回合:200/400,奖励:-21.0,Epsilon:0.010000000000000068\n", - "回合:201/400,奖励:-15.0,Epsilon:0.010000000000000064\n", - "回合:202/400,奖励:-16.0,Epsilon:0.010000000000000061\n", - "回合:203/400,奖励:-22.0,Epsilon:0.010000000000000057\n", - "回合:204/400,奖励:-28.0,Epsilon:0.010000000000000052\n", - "回合:205/400,奖励:-25.0,Epsilon:0.010000000000000049\n", - "回合:206/400,奖励:-16.0,Epsilon:0.010000000000000045\n", - "回合:207/400,奖励:-13.0,Epsilon:0.010000000000000044\n", - "回合:208/400,奖励:-31.0,Epsilon:0.01000000000000004\n", - "回合:209/400,奖励:-25.0,Epsilon:0.010000000000000037\n", - "回合:210/400,奖励:-21.0,Epsilon:0.010000000000000033\n", - "回合:211/400,奖励:-26.0,Epsilon:0.010000000000000031\n", - "回合:212/400,奖励:-13.0,Epsilon:0.01000000000000003\n", - "回合:213/400,奖励:-15.0,Epsilon:0.010000000000000028\n", - "回合:214/400,奖励:-23.0,Epsilon:0.010000000000000026\n", - "回合:215/400,奖励:-23.0,Epsilon:0.010000000000000024\n", - "回合:216/400,奖励:-13.0,Epsilon:0.010000000000000023\n", - "回合:217/400,奖励:-21.0,Epsilon:0.010000000000000021\n", - "回合:218/400,奖励:-28.0,Epsilon:0.01000000000000002\n", - "回合:219/400,奖励:-24.0,Epsilon:0.010000000000000018\n", - "回合:220/400,奖励:-20.0,Epsilon:0.010000000000000018\n", - "回合:221/400,奖励:-13.0,Epsilon:0.010000000000000016\n", - "回合:222/400,奖励:-15.0,Epsilon:0.010000000000000016\n", - "回合:223/400,奖励:-27.0,Epsilon:0.010000000000000014\n", - "回合:224/400,奖励:-18.0,Epsilon:0.010000000000000014\n", - "回合:225/400,奖励:-20.0,Epsilon:0.010000000000000012\n", - "回合:226/400,奖励:-27.0,Epsilon:0.010000000000000012\n", - "回合:227/400,奖励:-18.0,Epsilon:0.01000000000000001\n", - "回合:228/400,奖励:-15.0,Epsilon:0.01000000000000001\n", - "回合:229/400,奖励:-19.0,Epsilon:0.010000000000000009\n", - "回合:230/400,奖励:-20.0,Epsilon:0.010000000000000009\n", - "回合:231/400,奖励:-13.0,Epsilon:0.010000000000000009\n", - "回合:232/400,奖励:-28.0,Epsilon:0.010000000000000007\n", - "回合:233/400,奖励:-38.0,Epsilon:0.010000000000000007\n", - "回合:234/400,奖励:-17.0,Epsilon:0.010000000000000007\n", - "回合:235/400,奖励:-22.0,Epsilon:0.010000000000000005\n", - "回合:236/400,奖励:-13.0,Epsilon:0.010000000000000005\n", - "回合:237/400,奖励:-20.0,Epsilon:0.010000000000000005\n", - "回合:238/400,奖励:-18.0,Epsilon:0.010000000000000005\n", - "回合:239/400,奖励:-14.0,Epsilon:0.010000000000000005\n", - "回合:240/400,奖励:-13.0,Epsilon:0.010000000000000005\n", - "回合:241/400,奖励:-28.0,Epsilon:0.010000000000000004\n", - "回合:242/400,奖励:-13.0,Epsilon:0.010000000000000004\n", - "回合:243/400,奖励:-23.0,Epsilon:0.010000000000000004\n", - "回合:244/400,奖励:-17.0,Epsilon:0.010000000000000004\n", - "回合:245/400,奖励:-14.0,Epsilon:0.010000000000000004\n", - "回合:246/400,奖励:-22.0,Epsilon:0.010000000000000004\n", - "回合:247/400,奖励:-15.0,Epsilon:0.010000000000000004\n", - "回合:248/400,奖励:-19.0,Epsilon:0.010000000000000004\n", - "回合:249/400,奖励:-17.0,Epsilon:0.010000000000000004\n", - "回合:250/400,奖励:-27.0,Epsilon:0.010000000000000002\n", - "回合:251/400,奖励:-21.0,Epsilon:0.010000000000000002\n", - "回合:252/400,奖励:-23.0,Epsilon:0.010000000000000002\n", - "回合:253/400,奖励:-15.0,Epsilon:0.010000000000000002\n", - "回合:254/400,奖励:-15.0,Epsilon:0.010000000000000002\n", - "回合:255/400,奖励:-13.0,Epsilon:0.010000000000000002\n", - "回合:256/400,奖励:-15.0,Epsilon:0.010000000000000002\n", - "回合:257/400,奖励:-13.0,Epsilon:0.010000000000000002\n", - "回合:258/400,奖励:-28.0,Epsilon:0.010000000000000002\n", - "回合:259/400,奖励:-13.0,Epsilon:0.010000000000000002\n", - "回合:260/400,奖励:-13.0,Epsilon:0.010000000000000002\n", - "回合:261/400,奖励:-23.0,Epsilon:0.010000000000000002\n", - "回合:262/400,奖励:-13.0,Epsilon:0.010000000000000002\n", - "回合:263/400,奖励:-24.0,Epsilon:0.010000000000000002\n", - "回合:264/400,奖励:-17.0,Epsilon:0.010000000000000002\n", - "回合:265/400,奖励:-19.0,Epsilon:0.010000000000000002\n", - "回合:266/400,奖励:-13.0,Epsilon:0.010000000000000002\n", - "回合:267/400,奖励:-25.0,Epsilon:0.010000000000000002\n", - "回合:268/400,奖励:-15.0,Epsilon:0.01\n", - "回合:269/400,奖励:-15.0,Epsilon:0.01\n", - "回合:270/400,奖励:-21.0,Epsilon:0.01\n", - "回合:271/400,奖励:-13.0,Epsilon:0.01\n", - "回合:272/400,奖励:-13.0,Epsilon:0.01\n", - "回合:273/400,奖励:-22.0,Epsilon:0.01\n", - "回合:274/400,奖励:-15.0,Epsilon:0.01\n", - "回合:275/400,奖励:-13.0,Epsilon:0.01\n", - "回合:276/400,奖励:-19.0,Epsilon:0.01\n", - "回合:277/400,奖励:-13.0,Epsilon:0.01\n", - "回合:278/400,奖励:-18.0,Epsilon:0.01\n", - "回合:279/400,奖励:-14.0,Epsilon:0.01\n", - "回合:280/400,奖励:-126.0,Epsilon:0.01\n", - "回合:281/400,奖励:-15.0,Epsilon:0.01\n", - "回合:282/400,奖励:-19.0,Epsilon:0.01\n", - "回合:283/400,奖励:-13.0,Epsilon:0.01\n", - "回合:284/400,奖励:-25.0,Epsilon:0.01\n", - "回合:285/400,奖励:-13.0,Epsilon:0.01\n", - "回合:286/400,奖励:-119.0,Epsilon:0.01\n", - "回合:287/400,奖励:-15.0,Epsilon:0.01\n", - "回合:288/400,奖励:-15.0,Epsilon:0.01\n", - "回合:289/400,奖励:-14.0,Epsilon:0.01\n", - "回合:290/400,奖励:-13.0,Epsilon:0.01\n", - "回合:291/400,奖励:-13.0,Epsilon:0.01\n", - "回合:292/400,奖励:-15.0,Epsilon:0.01\n", - "回合:293/400,奖励:-33.0,Epsilon:0.01\n", - "回合:294/400,奖励:-19.0,Epsilon:0.01\n", - "回合:295/400,奖励:-13.0,Epsilon:0.01\n", - "回合:296/400,奖励:-15.0,Epsilon:0.01\n", - "回合:297/400,奖励:-13.0,Epsilon:0.01\n", - "回合:298/400,奖励:-132.0,Epsilon:0.01\n", - "回合:299/400,奖励:-13.0,Epsilon:0.01\n", - "回合:300/400,奖励:-13.0,Epsilon:0.01\n", - "回合:301/400,奖励:-13.0,Epsilon:0.01\n", - "回合:302/400,奖励:-14.0,Epsilon:0.01\n", - "回合:303/400,奖励:-15.0,Epsilon:0.01\n", - "回合:304/400,奖励:-13.0,Epsilon:0.01\n", - "回合:305/400,奖励:-13.0,Epsilon:0.01\n", - "回合:306/400,奖励:-13.0,Epsilon:0.01\n", - "回合:307/400,奖励:-13.0,Epsilon:0.01\n", - "回合:308/400,奖励:-13.0,Epsilon:0.01\n", - "回合:309/400,奖励:-13.0,Epsilon:0.01\n", - "回合:310/400,奖励:-13.0,Epsilon:0.01\n", - "回合:311/400,奖励:-15.0,Epsilon:0.01\n", - "回合:312/400,奖励:-13.0,Epsilon:0.01\n", - "回合:313/400,奖励:-13.0,Epsilon:0.01\n", - "回合:314/400,奖励:-13.0,Epsilon:0.01\n", - "回合:315/400,奖励:-15.0,Epsilon:0.01\n", - "回合:316/400,奖励:-14.0,Epsilon:0.01\n", - "回合:317/400,奖励:-13.0,Epsilon:0.01\n", - "回合:318/400,奖励:-13.0,Epsilon:0.01\n", - "回合:319/400,奖励:-13.0,Epsilon:0.01\n", - "回合:320/400,奖励:-21.0,Epsilon:0.01\n", - "回合:321/400,奖励:-19.0,Epsilon:0.01\n", - "回合:322/400,奖励:-13.0,Epsilon:0.01\n", - "回合:323/400,奖励:-13.0,Epsilon:0.01\n", - "回合:324/400,奖励:-13.0,Epsilon:0.01\n", - "回合:325/400,奖励:-13.0,Epsilon:0.01\n", - "回合:326/400,奖励:-14.0,Epsilon:0.01\n", - "回合:327/400,奖励:-15.0,Epsilon:0.01\n", - "回合:328/400,奖励:-13.0,Epsilon:0.01\n", - "回合:329/400,奖励:-13.0,Epsilon:0.01\n", - "回合:330/400,奖励:-13.0,Epsilon:0.01\n", - "回合:331/400,奖励:-13.0,Epsilon:0.01\n", - "回合:332/400,奖励:-13.0,Epsilon:0.01\n", - "回合:333/400,奖励:-14.0,Epsilon:0.01\n", - "回合:334/400,奖励:-13.0,Epsilon:0.01\n", - "回合:335/400,奖励:-113.0,Epsilon:0.01\n", - "回合:336/400,奖励:-13.0,Epsilon:0.01\n", - "回合:337/400,奖励:-13.0,Epsilon:0.01\n", - "回合:338/400,奖励:-13.0,Epsilon:0.01\n", - "回合:339/400,奖励:-13.0,Epsilon:0.01\n", - "回合:340/400,奖励:-13.0,Epsilon:0.01\n", - "回合:341/400,奖励:-15.0,Epsilon:0.01\n", - "回合:342/400,奖励:-23.0,Epsilon:0.01\n", - "回合:343/400,奖励:-13.0,Epsilon:0.01\n", - "回合:344/400,奖励:-13.0,Epsilon:0.01\n", - "回合:345/400,奖励:-13.0,Epsilon:0.01\n", - "回合:346/400,奖励:-13.0,Epsilon:0.01\n", - "回合:347/400,奖励:-13.0,Epsilon:0.01\n", - "回合:348/400,奖励:-13.0,Epsilon:0.01\n", - "回合:349/400,奖励:-13.0,Epsilon:0.01\n", - "回合:350/400,奖励:-13.0,Epsilon:0.01\n", - "回合:351/400,奖励:-13.0,Epsilon:0.01\n", - "回合:352/400,奖励:-13.0,Epsilon:0.01\n", - "回合:353/400,奖励:-13.0,Epsilon:0.01\n", - "回合:354/400,奖励:-13.0,Epsilon:0.01\n", - "回合:355/400,奖励:-13.0,Epsilon:0.01\n", - "回合:356/400,奖励:-13.0,Epsilon:0.01\n", - "回合:357/400,奖励:-13.0,Epsilon:0.01\n", - "回合:358/400,奖励:-13.0,Epsilon:0.01\n", - "回合:359/400,奖励:-13.0,Epsilon:0.01\n", - "回合:360/400,奖励:-13.0,Epsilon:0.01\n", - "回合:361/400,奖励:-13.0,Epsilon:0.01\n", - "回合:362/400,奖励:-13.0,Epsilon:0.01\n", - "回合:363/400,奖励:-13.0,Epsilon:0.01\n", - "回合:364/400,奖励:-13.0,Epsilon:0.01\n", - "回合:365/400,奖励:-13.0,Epsilon:0.01\n", - "回合:366/400,奖励:-13.0,Epsilon:0.01\n", - "回合:367/400,奖励:-13.0,Epsilon:0.01\n", - "回合:368/400,奖励:-13.0,Epsilon:0.01\n", - "回合:369/400,奖励:-13.0,Epsilon:0.01\n", - "回合:370/400,奖励:-13.0,Epsilon:0.01\n", - "回合:371/400,奖励:-13.0,Epsilon:0.01\n", - "回合:372/400,奖励:-14.0,Epsilon:0.01\n", - "回合:373/400,奖励:-13.0,Epsilon:0.01\n", - "回合:374/400,奖励:-15.0,Epsilon:0.01\n", - "回合:375/400,奖励:-13.0,Epsilon:0.01\n", - "回合:376/400,奖励:-13.0,Epsilon:0.01\n", - "回合:377/400,奖励:-13.0,Epsilon:0.01\n", - "回合:378/400,奖励:-13.0,Epsilon:0.01\n", - "回合:379/400,奖励:-13.0,Epsilon:0.01\n", - "回合:380/400,奖励:-117.0,Epsilon:0.01\n", - "回合:381/400,奖励:-13.0,Epsilon:0.01\n", - "回合:382/400,奖励:-13.0,Epsilon:0.01\n", - "回合:383/400,奖励:-13.0,Epsilon:0.01\n", - "回合:384/400,奖励:-13.0,Epsilon:0.01\n", - "回合:385/400,奖励:-13.0,Epsilon:0.01\n", - "回合:386/400,奖励:-13.0,Epsilon:0.01\n", - "回合:387/400,奖励:-13.0,Epsilon:0.01\n", - "回合:388/400,奖励:-13.0,Epsilon:0.01\n", - "回合:389/400,奖励:-13.0,Epsilon:0.01\n", - "回合:390/400,奖励:-13.0,Epsilon:0.01\n", - "回合:391/400,奖励:-13.0,Epsilon:0.01\n", - "回合:392/400,奖励:-13.0,Epsilon:0.01\n", - "回合:393/400,奖励:-13.0,Epsilon:0.01\n", - "回合:394/400,奖励:-13.0,Epsilon:0.01\n", - "回合:395/400,奖励:-13.0,Epsilon:0.01\n", - "回合:396/400,奖励:-13.0,Epsilon:0.01\n", - "回合:397/400,奖励:-13.0,Epsilon:0.01\n", - "回合:398/400,奖励:-15.0,Epsilon:0.01\n", - "回合:399/400,奖励:-13.0,Epsilon:0.01\n", - "回合:400/400,奖励:-13.0,Epsilon:0.01\n", - "完成训练!\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "回合:20/400,奖励:-45.0,Epsilon:0.010\n", + "回合:40/400,奖励:-34.0,Epsilon:0.010\n", + "回合:60/400,奖励:-47.0,Epsilon:0.010\n", + "回合:80/400,奖励:-88.0,Epsilon:0.010\n", + "回合:100/400,奖励:-53.0,Epsilon:0.010\n", + "回合:120/400,奖励:-23.0,Epsilon:0.010\n", + "回合:140/400,奖励:-20.0,Epsilon:0.010\n", + "回合:160/400,奖励:-29.0,Epsilon:0.010\n", + "回合:180/400,奖励:-42.0,Epsilon:0.010\n", + "回合:200/400,奖励:-28.0,Epsilon:0.010\n", + "回合:220/400,奖励:-20.0,Epsilon:0.010\n", + "回合:240/400,奖励:-20.0,Epsilon:0.010\n", + "回合:260/400,奖励:-17.0,Epsilon:0.010\n", + "回合:280/400,奖励:-13.0,Epsilon:0.010\n", + "回合:300/400,奖励:-13.0,Epsilon:0.010\n", + "回合:320/400,奖励:-13.0,Epsilon:0.010\n", + "回合:340/400,奖励:-13.0,Epsilon:0.010\n", + "回合:360/400,奖励:-13.0,Epsilon:0.010\n", + "回合:380/400,奖励:-13.0,Epsilon:0.010\n", + "回合:400/400,奖励:-14.0,Epsilon:0.010\n", + "完成训练!\n", "开始测试!\n", "环境:CliffWalking-v0, 算法:Q-learning, 设备:cpu\n", "回合数:1/20, 奖励:-13.0\n", @@ -869,7 +391,17 @@ }, { "data": { - "image/png": "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AACmTp2K1atX44033qi270fl5RVDqxW1muchExND3LhRVKd5GwPrk4f1ycP65HlS61MqFVV+sa42IOLi4mQVsG/fPkRFRWHdunVo27atZJstW7bA398fzZo1AwAMGTIEO3furHVAEBFR/WnQn7keOHAACxYswOrVq9G+fftK27Vv3x5HjhyBEAJarRaHDx9Gly5dGrI0IiKqhuyASEhIgJubG/bu3YulS5fCzc0NqampAIAZM2ZAo9EgPDwc/v7+8Pf3R35+PgBg1qxZSEpKAgC88847KCwshK+vL/z8/KBWqzFx4kS5pRERkQwKIUTdDto/gXgOoumwPnlYnzysr26qOwfB/0lNRESSGBBERCSJAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESSGBBERCSJAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESSGBBERCSJAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESSGBBERCSJAUFERJJkB8SuXbvg5+cHOzs7xMbGlpu2fPly+Pn5ISAgAP7+/khMTKy0n23btuHll1/G4MGDMWfOHGi1WrmlERGRDHpyO7C1tUVUVBRiYmIqTAsJCcHEiRMBADk5OfD29oarqyuMjIzKtUtPT8fnn3+OnTt3ok2bNggNDcV3332HgIAAueUREVEdyd6DsLa2hpWVFZTKil0ZGhrqHpeUlEChUEjuGXz//fcYPHgwnn32WSiVSgwfPrzKvQ0iImp4svcgqrN582asX78e2dnZmD9/PoyNjSu0ycrKgoWFhe65hYUFsrKyGro0nUs/7obeteMQWtFoy6ytK0oF65OB9cnD+uRp6PrKOvVFVw+feu+32oAIDAxEZmam5LRjx45BpVJVOX9wcDCCg4Nx5coVTJs2DX369JEMifrw3HOt6zRfi+b60ABQKBX1W1A9Y33ysD55WJ88DVlfi+b6MDExrL5hLVUbEHFxcfWyIBsbG5iamuLkyZPw9PQsN83c3LxcCGVmZsLc3LzWy8jLK4a2Dindqe8rMPEfhhs3imo9b2MxMTFkfTKwPnlYnzyNUV9d+lcqFVV+sW7Qn7mmpqbqHqenpyMlJQVWVlYV2nl6emL//v24desWtFottm/fDm9v74YsjYiIqiH7HERCQgIWL16MwsJCJCUlISYmBmvWrIGVlRWio6ORmpoKPT09qFQqzJ49G507dwYALF26FKampggODsbf/vY3vP322xgxYgQAwNXVFUOHDpVbGhERyaAQQjy5Z3Zqqa6HmADuosrF+uRhffKwvrpp0kNMRET058WAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSJDsgdu3aBT8/P9jZ2SE2NrbctOXLl8PPzw8BAQHw9/dHYmKiZB/79+9HUFAQfH194ePjgzVr1sgti4iIZNKT24GtrS2ioqIQExNTYVpISAgmTpwIAMjJyYG3tzdcXV1hZGRUrp2JiQmWL18OMzMzFBUVISgoCN27d4eTk5Pc8oiIqI5kB4S1tTUAQKmsuDNiaGioe1xSUgKFQgGtVluhXY8ePcrN07lzZ2RkZDAgiIiaUIOfg9i8eTO8vLwQGBiIuXPnwtjYuMr2aWlpOHfuHHr37t3QpRERURUUQghRVYPAwEBkZmZKTjt27BhUKhUAICIiAt26dUNISIhk2ytXrmDatGnYsGFDpSGRm5uL0aNHY/LkyfD29q7N+yAionpW7SGmuLi4elmQjY0NTE1NcfLkSXh6elaYnpeXh3HjxuHNN9+sczjk5RVDq60y7yplYmKIGzeK6jRvY2B98rA+eVifPE9qfUqlAs8917ry6Q258NTUVN3j9PR0pKSkwMrKqkK7/Px8jBs3Dq+99hqGDx/ekCUREVENyT5JnZCQgMWLF6OwsBBJSUmIiYnBmjVrYGVlhejoaKSmpkJPTw8qlQqzZ89G586dAQBLly6FqakpgoODERMTg2vXrmHr1q3YunUrAGDMmDEYNmyY3PKIiKiOqj0H8WfCQ0xNh/XJw/rkYX1106SHmIiI6M+LAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESSGBBERCSJAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESSGBBERCSJAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESSGBBERCSJAUFERJIYEEREJIkBQUREkmQHxK5du+Dn5wc7OzvExsaWm7Z8+XL4+fkhICAA/v7+SExMrLKv0tJS+Pj4ICgoSG5ZREQkk57cDmxtbREVFYWYmJgK00JCQjBx4kQAQE5ODry9veHq6gojIyPJvqKiotCjRw9cvnxZbllERCST7D0Ia2trWFlZQams2JWhoaHucUlJCRQKBbRarWQ/ycnJuHbtGvz9/eWWRERE9UD2HkR1Nm/ejPXr1yM7Oxvz58+HsbFxhTYlJSWYP38+li9fjmvXrtV5Wc8911pGpYCJiWH1jZoQ65OH9cnD+uR50uuTUm1ABAYGIjMzU3LasWPHoFKpqpw/ODgYwcHBuHLlCqZNm4Y+ffpUCInFixdj1KhRMDMzkxUQeXnF0GpFneY1MTHEjRtFdV52Q2N98rA+eVifPE9qfUqlosov1tUGRFxcXL0UYmNjA1NTU5w8eRKenp7lpp0+fRqHDh3Cl19+idLSUty+fRt+fn6Ij4+vl2UTEVHtNeghptTUVFhZWQEA0tPTkZKSonv+qEeD4MSJE1i0aBF27NjRkKUREVE1ZAdEQkICFi9ejMLCQiQlJSEmJgZr1qyBlZUVoqOjkZqaCj09PahUKsyePRudO3cGACxduhSmpqYIDg6W/SaIiKj+KYQQdTto/wTiOYimw/rkYX3ysL66qe4cBP8nNRERSWJAEBGRJAYEERFJYkAQEZEkBgQREUliQBARkSQGBBERSWJAEBGRJAYEERFJYkAQEZEkBgQREUliQBARkSQGBBERSWJAEBGRJAYEERFJYkAQEZEkBgQREUliQBARkSQGBBERSWJAEBGRJAYEERFJkh0Qu3btgp+fH+zs7BAbG1tu2vLly+Hn54eAgAD4+/sjMTGx0n5SUlLw2muvYciQIRgyZAgOHjwotzQiIpJBT24Htra2iIqKQkxMTIVpISEhmDhxIgAgJycH3t7ecHV1hZGRUbl2JSUlmDRpEj755BPY29vj/v37KCoqklsaERHJIDsgrK2tAQBKZcWdEUNDQ93jkpISKBQKaLXaCu0SEhLQs2dP2NvbPyhKTw/GxsZySyMiIhlkB0R1Nm/ejPXr1yM7Oxvz58+X3PCnpqZCT08PoaGhyM3NRdeuXTF9+vQKexpERNR4FEIIUVWDwMBAZGZmSk47duwYVCoVACAiIgLdunVDSEiIZNsrV65g2rRp2LBhQ4WQmDdvHn788Uds2bIFbdu2xYIFC1BcXIwFCxbU5T0REVE9qHYPIi4url4WZGNjA1NTU5w8eRKenp7lppmbm8PFxQWmpqYAAD8/P8ycObPWy8jLK4ZWW2XeVcrExBA3bjy55z1YnzysTx7WJ8+TWp9SqcBzz7WufHpDLjw1NVX3OD09HSkpKbCysqrQztvbGxcuXEBxcTEA4NChQ7CxsWnI0oiIqBqyz0EkJCRg8eLFKCwsRFJSEmJiYrBmzRpYWVkhOjpad35BpVJh9uzZ6Ny5MwBg6dKlMDU1RXBwMCwsLBAaGoqRI0dCoVCgffv2mDt3ruw3R0REdVftOYg/Ex5iajqsTx7WJw/rq5smPcRERER/XgwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkNfsOgxqRUKpp0/obG+uRhffKwPnmexPqqq+kvdbE+IiKqPzzEREREkhgQREQkiQFBRESSGBBERCSJAUFERJIYEEREJIkBQUREkhgQREQkiQFBRESS/lKX2qjOb7/9hoiICBQUFKBNmzZYtGgROnbsWK5NWVkZ5s2bh8OHD0OhUOCtt97C8OHDG7y2/Px8/Otf/8Iff/wBAwMDdOjQAXPmzMGzzz5brl1ERASOHTsGY2NjAICXlxcmTpzY4PUBgIeHBwwMDNCsWTMAwLRp09C/f/9ybe7evYsZM2bg0qVLUKlUmD59Otzd3Ru8tuvXr+Odd97RPS8qKkJxcTFOnjxZrl10dDQ2bdoEU1NTAICjoyM++OCDBqlp0aJF+P7775GRkYH4+HhYW1sDqNk4BBp+LErVV9NxCDT8WKxs/dVkHAINPxal6qvpOAQadyzWmXiKjB49WuzcuVMIIcTOnTvF6NGjK7SJi4sT48ePF2VlZSIvL0/0799fpKenN3ht+fn54j//+Y/u+cKFC8WMGTMqtJs+fbr4+uuvG7weKe7u7uLKlStVtomOjhazZs0SQgjx22+/ib59+4ri4uLGKK+cefPmicjIyAqvL1u2TCxcuLBRajh16pTIzMyssN5qMg6FaPixKFVfTcehEA0/FitbfzUZh0I0/FisrL5HVTYOhWjcsVhXT80hpry8PPz888/w9fUFAPj6+uLnn3/GrVu3yrVLTEzE8OHDoVQq8eyzz2Lw4MHYu3dvg9fXpk0buLi46J7b29sjMzOzwZdb3/bs2YO///3vAICOHTuiW7duOHToUKPWoFarER8fj2HDhjXqch/n5OQEc3Pzcq/VdBwCDT8Wpep7ksahVH210dBjsbr6npRxKMdTExBZWVkwMzODSqUCAKhUKpiamiIrK6tCOwsLC91zc3NzZGdnN2qtWq0WmzdvhoeHh+T0tWvXws/PD2+//TbS0tIatbZp06bBz88PH374IQoLCytMz8zMhKWlpe55U6y/H3/8EWZmZujatavk9N27d8PPzw/jx4/H2bNnG7W2mo7Dh22bcixWNw6BphuL1Y1DoOnHYnXjEGjasVgTT01A/JnMnTsXLVu2REhISIVpU6ZMwb59+xAfH49XXnkFb775JsrKyhqlro0bN+K7777Dt99+CyEE5syZ0yjLra1vv/220m9tI0eORFJSEuLj4/HGG2/g7bffRn5+fiNX+OdQ1TgEmm4s/hXGIfDnGItPTUCYm5sjJydHN4DLysqQm5tbYRfR3Ny83C51VlYW2rVr12h1Llq0CL///js+++wzKJUV/zxmZma61wMCAlBSUtJo34oerisDAwOMGjUKZ86cqdDGwsICGRkZuueNvf5ycnJw6tQp+Pn5SU43MTGBvr4+AMDV1RXm5ua4evVqo9VX03H4sG1TjcXqxiHQdGOxJuMQaNqxWN04BJp+LNbEUxMQzz33HGxtbZGQkAAASEhIgK2tbYVfZ3h5eWH79u3QarW4desW9u/fD09Pz0ap8dNPP8V///tffPHFFzAwMJBsk5OTo3t8+PBhKJVKmJmZNXhtJSUlKCoqAgAIIZCYmAhbW9sK7by8vLB161YAwLVr13Dx4kXJX5g0lLi4OAwYMED3y5rHPbr+UlJSkJGRgRdeeKGxyqvxOASabizWZBwCTTMWazoOgaYdi9WNQ6Dpx2JNPFU3DEpLS0NERAQKCwvxzDPPYNGiRejUqRNCQ0MRHh6Ol156CWVlZZgzZw6OHj0KAAgNDdWd6GpIV69eha+vLzp27IjmzZsDANq3b48vvvgC/v7+iImJgZmZGcaOHYu8vDwoFAq0bt0a//rXv2Bvb9/g9aWnpyMsLAxlZWXQarXo3LkzZs+eDVNT03L1lZSUICIiAikpKVAqlXjvvfcwePDgBq/vIU9PT8yaNQtubm661x79+06fPh2XLl2CUqmEvr4+wsPDMWDAgAapZd68efjhhx9w8+ZNGBsbo02bNti9e3el4/DxWht6LErV99lnn1U6DgE06liUqm/FihWVjsPH62vosVjZ3xeQHodA043FunqqAoKIiGruqTnEREREtcOAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCCqZytWrMCsWbPqNG9ERASioqLquSKiunmqLvdN1BgmTJjQ1CUQ1QvuQRARkSQGBD31cnJyEBYWht69e8PDwwMbNmwA8OCGLuHh4Zg8eTIcHBwQGBiIy5cv6+aLiYlB//794eDgAE9PTxw/flw337Rp03TtkpKS4OPjAycnJ4wePbrcVU9//vlnBAYGwsHBAZMnT0ZpaWm52g4cOAB/f384OTlh5MiRNVo+Ub1pultREDW9srIyERgYKKKjo0Vpaan4448/hIeHhzh06JBYtmyZsLOzE3v27BFqtVqsWrVKuLu7C7VaLdLS0oSbm5vIzs4WQgiRnp4ufv/9dyHEgxvBTJ06VQghxK+//ip69Oghjhw5ItRqtYiJiRGDBw8WpaWlorS0VAwcOFCsXbtWqNVqsWfPHmFnZyc+/fRTIYQQly5dEr179xbnzp0T9+/fFzt27BDu7u6itLS0yuUT1RfuQdBT7eLFi7h16xYmTZoEAwMD/O1vf8OIESOQmJgIAOjatSu8vLygr6+PcePGQa1W4/z581CpVFCr1UhLS4NGo0H79u3x/PPPV+g/MTERAwYMgKurK/T19fHGG2/g3r17OHv2LM6fPw+NRoPXX38d+vr68PLywksvvaSbd+vWrfj73/+OHj16QKVSITAwEPr6+jh37lyNl08kB09S01MtIyMDubm5cHJy0r1WVlYGJycnWFhYlLs89MOrlT5sP3PmTERHRyM1NRX9+vVDREREhauZ5ubmlrvpj1Kp1F3yW6VSwczMDAqFQjf90baZmZnYuXMnYmNjda9pNBrk5uaiV69eNVo+kRzcg6Cnmrm5Odq3b4/k5GTdv7Nnz2LlypUAUO7+BlqtFjk5Oborh/r5+WHz5s04cOAAFAoFPv744wr9m5qalrungxBCd1c5ExMT5OTkQDxyvcxH25qbm2PChAnlajt//rzudqU1WT6RHAwIeqp1794drVq1QkxMDO7du4eysjL88ssvuHDhAgDg0qVL+OGHH3D//n2sX78eBgYG6NGjB3799VccP34carUaBgYGaNasmeSNdby9vXHw4EEcP34cGo0Ga9asgYGBARwcHGBvbw89PT1s2LABGo0GP/zwAy5evKibd/jw4diyZQvOnz8PIQRKSkrw008/obi4uMbLJ5KDh5joqaZSqbBixQosWrQIgwYNglqtxgsvvIDJkycDAAYNGoTExERMnz4dHTp0QHR0NPT19aFWq/HJJ58gLS0N+vr6cHBwkLz1ZadOnbBkyRLMnTsXOTk5sLW1xYoVK3Q34omOjsb777+Pzz77DAMGDMDLL7+sm/ell17C3LlzMWfOHPz+++9o3rw5HB0d4eTkVOPlE8nB+0EQVSI6Ohq///47D93QU4v7pEREJIkBQUREkniIiYiIJHEPgoiIJDEgiIhIEgOCiIgkMSCIiEgSA4KIiCQxIIiISNL/AQrd+XrWqhsMAAAAAElFTkSuQmCC", + "image/png": "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PVmOHDmyxHG6XC7mzJlDs2bNALx/kxMnTnDzzTdz00030blzZ+Li4vjuu++876vMZ8hgMHg/H8XLUK/Xl1i/PCeg85VXafF5NG/eHIfDwcGDB2nUqJF3eVFREQ899BDPP//8Bfd9tvDwcBo0aMBXX32FTqfzJqo+ffqwbds2fvrpJ5544okLfi+L69KlC506dWLSpEksXry41M9ARb6PJ0+eZNy4cd7lb731FnFxcUyfPp3k5GS2bNniba6LiooiNTXV20ybkpJC69atK1wuVUmaj8qpZ8+efPDBB9hsNlwuF1OmTOHll1/m4MGD5Obm8uijj9KvXz9++ukn7zpVLTY2ls8++wybzYbD4SizltG9e3e+/vprb/X+tddeY8GCBYSHh7N3716KiopwOBwlTjylGTFiBNOmTaNVq1bek3FZ5XC2Xr16sWjRIux2Oy6Xiw8++IAePXqU+1gtFgvt2rXzjgA5fvw4t9xyCzk5OQDe5ceOHWPDhg307t2b8PBwjh07Rnp6OpqmlTmSo2vXrmzYsMFb3ff0bfzjH/84b0yPP/4477zzDuvWrQPcV5jXX389EyZM4NFHH8VkMpGUlORtMrvllltKvL9nz54sWLAATdOw2Wzcf//9vP/+++zatYvw8HAeeOABevXq5f27XKjmURmxsbF88sknuFwuCgoKWLFixQVrR5UtL6PRyNixY5k8eTJpaWmAuynmhRdeoKCggDp16lTqGHr37s0bb7xBnz59vMv69OnD8uXLiYiIIDw8vELfy/bt23P77bcTHBxcanNuWcr6PtapU8f7GVi+fDl16tTBZDKRkJBAYmIiAwYMwGw2A+4ayOLFiwE4ceIE33//PX379q1UuVQVqSmU0wMPPMCMGTO47rrrcDqdtGnThsTERAIDA+nTpw/x8fHUqlWLhg0b0rx5cw4ePFhmVbSyrr/+evbv38/w4cMJDAykfv363g9XcbGxsezbt897UmrevDnTpk0jICCALl26EB8fj9Vq5eqrrz5v08Hw4cN5+eWXS5z0yyqHs91///3MmDGD4cOH43A46NixI1OmTKnQ8b700ks899xzLFy4EEVRSEpK8l5RHTlyhOuvv57CwkKeeuopmjZtCrivzm+44QasVmuJk0ZxzZs355lnnuGhhx7C6XQSEBDA/PnzCQ4OPm88bdq04d///jdz5szhhRde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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", "text/plain": [ "
" ] diff --git a/projects/notebooks/3.DQN.ipynb b/projects/notebooks/3.DQN.ipynb index 9fed7b6..6b73846 100644 --- a/projects/notebooks/3.DQN.ipynb +++ b/projects/notebooks/3.DQN.ipynb @@ -1,18 +1,5 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 1、分析伪代码\n", - "\n", - "目前DQN算法基本遵循[Nature DQN](https://www.nature.com/articles/nature14236)的伪代码步骤,如下:\n", - "\n", - "
\n", - "\"\" \n", - "
" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -36,15 +23,15 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", "class MLP(nn.Module):\n", " def __init__(self, n_states,n_actions,hidden_dim=128):\n", " \"\"\" 初始化q网络,为全连接网络\n", - " n_states: 输入的特征数即环境的状态维度\n", - " n_actions: 输出的动作维度\n", " \"\"\"\n", " super(MLP, self).__init__()\n", " self.fc1 = nn.Linear(n_states, hidden_dim) # 输入层\n", @@ -64,34 +51,39 @@ "source": [ "### 1.2、定义经验回放\n", "\n", - "经验回放首先是具有一定容量的,只有存储一定的transition网络才会更新,否则就退回到了之前的逐步更新了。另外写经验回放的时候一般需要包涵两个功能或方法,一个是push,即将一个transition样本按顺序放到经验回放中,如果满了就把最开始放进去的样本挤掉,因此如果大家学过数据结构的话推荐用队列来写,虽然这里不是。另外一个是sample,很简单就是随机采样出一个或者若干个(具体多少就是batch_size了)样本供DQN网络更新。功能讲清楚了,大家可以按照自己的想法用代码来实现,可以肯定地说,我这里不是最高效的,毕竟这还是青涩时期写出的代码。" + "经验回放首先是具有一定容量的,只有存储一定的transition网络才会更新,否则就退回到了之前的逐步更新了。另外写经验回放的时候一般需要包涵两个功能或方法,一个是push,即将一个transition样本按顺序放到经验回放中,如果满了就把最开始放进去的样本挤掉,因此如果大家学过数据结构的话推荐用队列来写,虽然这里不是。另外一个是sample,很简单就是随机采样出一个或者若干个(具体多少就是batch_size了)样本供DQN网络更新。功能讲清楚了,大家可以按照自己的想法用代码来实现,参考如下。" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "class ReplayBuffer:\n", - " def __init__(self, capacity):\n", - " self.capacity = capacity # 经验回放的容量\n", - " self.buffer = [] # 缓冲区\n", - " self.position = 0 \n", - " \n", - " def push(self, state, action, reward, next_state, done):\n", - " ''' 缓冲区是一个队列,容量超出时去掉开始存入的转移(transition)\n", + "from collections import deque\n", + "import random\n", + "class ReplayBuffer(object):\n", + " def __init__(self, capacity: int) -> None:\n", + " self.capacity = capacity\n", + " self.buffer = deque(maxlen=self.capacity)\n", + " def push(self,transitions):\n", + " ''' 存储transition到经验回放中\n", " '''\n", - " if len(self.buffer) < self.capacity:\n", - " self.buffer.append(None)\n", - " self.buffer[self.position] = (state, action, reward, next_state, done)\n", - " self.position = (self.position + 1) % self.capacity \n", - " \n", - " def sample(self, batch_size):\n", - " batch = random.sample(self.buffer, batch_size) # 随机采出小批量转移\n", - " state, action, reward, next_state, done = zip(*batch) # 解压成状态,动作等\n", - " return state, action, reward, next_state, done\n", - " \n", + " self.buffer.append(transitions)\n", + " def sample(self, batch_size: int, sequential: bool = False):\n", + " if batch_size > len(self.buffer): # 如果批量大小大于经验回放的容量,则取经验回放的容量\n", + " batch_size = len(self.buffer)\n", + " if sequential: # 顺序采样\n", + " rand = random.randint(0, len(self.buffer) - batch_size)\n", + " batch = [self.buffer[i] for i in range(rand, rand + batch_size)]\n", + " return zip(*batch)\n", + " else: # 随机采样\n", + " batch = random.sample(self.buffer, batch_size)\n", + " return zip(*batch)\n", + " def clear(self):\n", + " ''' 清空经验回放\n", + " '''\n", + " self.buffer.clear()\n", " def __len__(self):\n", " ''' 返回当前存储的量\n", " '''\n", @@ -102,61 +94,100 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 1.3、真--定义算法\n", + "### 1.3、真定义算法\n", "\n", - "到了高级一点的算法,定义算法就比较麻烦,要先定义一些子模块。可以看到,其实去掉子模块的话,DQN跟Q learning的算法结构没啥区别,当然因为神经网络一般需要Torch或者Tensorflow来写,因此推荐大家先去学一学这些工具,比如\"eat_pytorch_in_20_days\"。\n" + "到了高级一点的算法,定义算法就比较麻烦,要先定义一些子模块,再定义好子模块之后我们就可以实现我们的算法核心部分。如下,可以看到,其实去掉子模块的话,DQN跟Q learning的算法结构没啥区别,当然因为神经网络一般需要Torch或者Tensorflow来写,因此推荐大家先去学一学这些工具,比如\"eat_pytorch_in_20_days\"。\n", + "\n", + "这里我们主要分析一下DQN的更新过程,也就是update函数。首先我们知道目前所有基于深度神经网络的更新方式都是梯度下降,如下:\n", + "$$\n", + "\\theta_i \\leftarrow \\theta_i - \\lambda \\nabla_{\\theta_{i}} L_{i}\\left(\\theta_{i}\\right)\n", + "$$\n", + "那么这个$\\theta$又是什么呢,注意到前面我们讲的DQN跟Q learning算法的一个主要区别就是使用神经网络替代了Q表,而这个$\\theta$实际上就是神经网络的参数,通常用$Q\\left(s_{i}, a_{i} ; \\theta\\right)$表示。根据强化学习的原理我们需要优化的是对应状态下不同动作的长期价值,然后每次选择价值最大对应的动作就能完成一条最优策略,使用神经网络表示Q表时也是如此,我们将输入的状态数作为神经网络的输入层,动作数作为输出层,这样的神经网络表达的功能就跟在Q learning中的Q表是一样的,只不过具有更强的鲁棒性。\n", + "\n", + "讲完了为什么要优化的是这个参数$\\theta$,接下来我们从代码层面进一步剖析,稍微了解一点Torch知识的同学都知道,上面的公式其实只需要定义一个优化器,然后计算损失之后用优化器迭代即可,如下:\n", + "```python\n", + "optimizer = optim.Adam(Q_net.parameters(), lr=0.01) # 定义优化器,对应的网络是Q_net,学习率为0.01\n", + "loss = ... # 计算损失,这里掠过\n", + "# 然后优化器先zero_grad(),loss再反向传播,然后优化器step() ,这是一个固定的套路\n", + "optimizer.zero_grad() \n", + "loss.backward()\n", + "optimizer.step() \n", + "```\n", + "当然强烈建议同学们了解一下深度学习中的梯度下降,并且使用numpy实现,这样就会更加清楚整个梯度下降过程到底是怎么回事,上述只是在同学们了解了梯度下降的具体实现方式的前提下为了方便学习更多其他的知识形成的套路。这就好比我们玩一个竞技游戏,如果我们之前从来没有接触过该类游戏,那么肯定是从普通攻击,每个技能一步一步地学起打好基础,然后再学习技能连招等等也就是形成固定的套路,但是如果不先打基础,直接学习套路可能会是一脸懵逼的状态,尤其是很多高端玩家会对这些连招套路简化名称比如光速qa和1233321等等,一开始我们是很难听懂的。等当我们先打好基础,然后再学习了很多套路之后会发现这些基础并不能用得上,甚至有的时候可能会忽然忘记了这些基础,但其实我们并没有忘记,再回顾一遍也能很快拣起来。在这点上我想强调的是基础固然重要,但是不要死磕基础,除非是学术研究需要。再比如我们小学学完简单加减乘除之后很快就去背九九乘法表,而不会去过多纠结一加一等于几的问题,上大学后也是如此,只是很多时候我们很可能看起来这个问题值得研究,但意识不到自己就是在纠结一加一等于几的问题,这也是我在和众多读者们学习讨论的过程中在他们身上发现的问题。\n", + "\n", + "回归正题,细心的同学会发现数学公式和代码的对应是有一定的壁垒的,只要通过多加练习跨越了这个壁垒,那么对于往后我们想要复现论文也会轻松许多。我们目前讲了参数的更新过程,但是最关键的是损失是如何计算的,在DQN中损失的计算相对来说比较简单,如下:\n", + "$$\n", + "L(\\theta)=\\left(y_{i}-Q\\left(s_{i}, a_{i} ; \\theta\\right)\\right)^{2}\n", + "$$\n", + "这里的$y_{i}$通常称为期望值,$Q\\left(s_{i}, a_{i} ; \\theta\\right)$称为实际值,这个损失在深度学习中通常称作均方差损失,也就是mseloss,使用这个损失函数通常追溯到数学上的最小二乘法,感兴趣的同学可以了解一下深度学习中的各种损失函数以及各自的使用场景。\n", + "$y_{i}$在DQN中一般表示如下:\n", + "$$\n", + "y_{i}= \\begin{cases}r_{i} & \\text {对于终止状态} s_{i+1} \\\\ r_{i}+\\gamma \\max _{a^{\\prime}} Q\\left(s_{i+1}, a^{\\prime} ; \\theta\\right) & \\text {对于非终止状态} s_{i+1}\\end{cases}\n", + "$$\n", + "该公式的意思就是将下一个状态对应的最大Q值作为实际值(因为实际值通常不能直接求得,只能近似),这种做法实际上只是一种近似,可能会导致过估计等问题,也有一些改善的方法具体可以在后面各种改进的DQN算法比如Double DQN中看到,在这里我们暂时不要深究为什么要用这个来近似实际值。然后注意到这里其实有一个终止状态的判断,因为如果当前状态是终止状态,那么实际上是没有下一个状态的,所以DQN干脆直接使用对应的奖励表示Q的实际值。" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ + "import torch\n", + "import torch.optim as optim\n", + "import math\n", + "import numpy as np\n", "class DQN:\n", - " def __init__(self,n_actions,model,memory,cfg):\n", + " def __init__(self,model,memory,cfg):\n", "\n", - " self.n_actions = n_actions \n", - " self.device = torch.device(cfg.device) # cpu or cuda\n", - " self.gamma = cfg.gamma # 奖励的折扣因子\n", + " self.n_actions = cfg['n_actions'] \n", + " self.device = torch.device(cfg['device']) \n", + " self.gamma = cfg['gamma'] # 奖励的折扣因子\n", " # e-greedy策略相关参数\n", " self.sample_count = 0 # 用于epsilon的衰减计数\n", - " self.epsilon = lambda sample_count: cfg.epsilon_end + \\\n", - " (cfg.epsilon_start - cfg.epsilon_end) * \\\n", - " math.exp(-1. * sample_count / cfg.epsilon_decay)\n", - " self.batch_size = cfg.batch_size\n", + " self.epsilon = cfg['epsilon_start']\n", + " self.sample_count = 0 \n", + " self.epsilon_start = cfg['epsilon_start']\n", + " self.epsilon_end = cfg['epsilon_end']\n", + " self.epsilon_decay = cfg['epsilon_decay']\n", + " self.batch_size = cfg['batch_size']\n", " self.policy_net = model.to(self.device)\n", " self.target_net = model.to(self.device)\n", - " for target_param, param in zip(self.target_net.parameters(),self.policy_net.parameters()): # 复制参数到目标网路targe_net\n", + " # 复制参数到目标网络\n", + " for target_param, param in zip(self.target_net.parameters(),self.policy_net.parameters()): \n", " target_param.data.copy_(param.data)\n", - " self.optimizer = optim.Adam(self.policy_net.parameters(), lr=cfg.lr) # 优化器\n", + " self.optimizer = optim.Adam(self.policy_net.parameters(), lr=cfg['lr']) # 优化器\n", " self.memory = memory # 经验回放\n", - "\n", - " def sample(self, state):\n", - " ''' 选择动作\n", + " def sample_action(self, state):\n", + " ''' 采样动作\n", " '''\n", " self.sample_count += 1\n", - " if random.random() > self.epsilon(self.sample_count):\n", + " # epsilon指数衰减\n", + " self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \\\n", + " math.exp(-1. * self.sample_count / self.epsilon_decay) \n", + " if random.random() > self.epsilon:\n", " with torch.no_grad():\n", " state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0)\n", " q_values = self.policy_net(state)\n", - " action = q_values.max(1)[1].item() # 选择Q值最大的动作\n", + " action = q_values.max(1)[1].item() # choose action corresponding to the maximum q value\n", " else:\n", " action = random.randrange(self.n_actions)\n", " return action\n", - " def predict(self,state):\n", - " with torch.no_grad():\n", - " state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0)\n", - " q_values = self.policy_net(state)\n", - " action = q_values.max(1)[1].item() # 选择Q值最大的动作\n", + " @torch.no_grad() # 不计算梯度,该装饰器效果等同于with torch.no_grad():\n", + " def predict_action(self, state):\n", + " ''' 预测动作\n", + " '''\n", + " state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0)\n", + " q_values = self.policy_net(state)\n", + " action = q_values.max(1)[1].item() # choose action corresponding to the maximum q value\n", " return action\n", " def update(self):\n", - " if len(self.memory) < self.batch_size: # 当memory中不满足一个批量时,不更新策略\n", + " if len(self.memory) < self.batch_size: # 当经验回放中不满足一个批量时,不更新策略\n", " return\n", - " # 从经验回放中(replay memory)中随机采样一个批量的转移(transition)\n", - " \n", + " # 从经验回放中随机采样一个批量的转移(transition)\n", " state_batch, action_batch, reward_batch, next_state_batch, done_batch = self.memory.sample(\n", " self.batch_size)\n", + " # 将数据转换为tensor\n", " state_batch = torch.tensor(np.array(state_batch), device=self.device, dtype=torch.float)\n", " action_batch = torch.tensor(action_batch, device=self.device).unsqueeze(1) \n", " reward_batch = torch.tensor(reward_batch, device=self.device, dtype=torch.float) \n", @@ -170,17 +201,10 @@ " # 优化更新模型\n", " self.optimizer.zero_grad() \n", " loss.backward()\n", - " for param in self.policy_net.parameters(): # clip防止梯度爆炸\n", + " # clip防止梯度爆炸\n", + " for param in self.policy_net.parameters(): \n", " param.grad.data.clamp_(-1, 1)\n", - " self.optimizer.step() \n", - "\n", - " def save(self, path):\n", - " torch.save(self.target_net.state_dict(), path+'checkpoint.pth')\n", - "\n", - " def load(self, path):\n", - " self.target_net.load_state_dict(torch.load(path+'checkpoint.pth'))\n", - " for target_param, param in zip(self.target_net.parameters(), self.policy_net.parameters()):\n", - " param.data.copy_(target_param.data)" + " self.optimizer.step() " ] }, { @@ -192,7 +216,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -200,47 +224,43 @@ " ''' 训练\n", " '''\n", " print(\"开始训练!\")\n", - " print(f\"回合:{cfg.env_name}, 算法:{cfg.algo_name}, 设备:{cfg.device}\")\n", " rewards = [] # 记录所有回合的奖励\n", " steps = []\n", - " for i_ep in range(cfg.train_eps):\n", + " for i_ep in range(cfg['train_eps']):\n", " ep_reward = 0 # 记录一回合内的奖励\n", " ep_step = 0\n", " state = env.reset() # 重置环境,返回初始状态\n", - " while True:\n", + " for _ in range(cfg['ep_max_steps']):\n", " ep_step += 1\n", - " action = agent.sample(state) # 选择动作\n", + " action = agent.sample_action(state) # 选择动作\n", " next_state, reward, done, _ = env.step(action) # 更新环境,返回transition\n", - " agent.memory.push(state, action, reward,\n", - " next_state, done) # 保存transition\n", + " agent.memory.push((state, action, reward,next_state, done)) # 保存transition\n", " state = next_state # 更新下一个状态\n", " agent.update() # 更新智能体\n", " ep_reward += reward # 累加奖励\n", " if done:\n", " break\n", - " if (i_ep + 1) % cfg.target_update == 0: # 智能体目标网络更新\n", + " if (i_ep + 1) % cfg['target_update'] == 0: # 智能体目标网络更新\n", " agent.target_net.load_state_dict(agent.policy_net.state_dict())\n", " steps.append(ep_step)\n", " rewards.append(ep_reward)\n", " if (i_ep + 1) % 10 == 0:\n", - " print(f'回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.2f},Epislon:{agent.epsilon(agent.frame_idx):.3f}')\n", + " print(f\"回合:{i_ep+1}/{cfg['train_eps']},奖励:{ep_reward:.2f},Epislon:{agent.epsilon:.3f}\")\n", " print(\"完成训练!\")\n", " env.close()\n", - " res_dic = {'rewards':rewards}\n", - " return res_dic\n", + " return {'rewards':rewards}\n", "\n", "def test(cfg, env, agent):\n", " print(\"开始测试!\")\n", - " print(f\"回合:{cfg.env_name}, 算法:{cfg.algo_name}, 设备:{cfg.device}\")\n", " rewards = [] # 记录所有回合的奖励\n", " steps = []\n", - " for i_ep in range(cfg.test_eps):\n", + " for i_ep in range(cfg['test_eps']):\n", " ep_reward = 0 # 记录一回合内的奖励\n", " ep_step = 0\n", " state = env.reset() # 重置环境,返回初始状态\n", - " while True:\n", + " for _ in range(cfg['ep_max_steps']):\n", " ep_step+=1\n", - " action = agent.predict(state) # 选择动作\n", + " action = agent.predict_action(state) # 选择动作\n", " next_state, reward, done, _ = env.step(action) # 更新环境,返回transition\n", " state = next_state # 更新下一个状态\n", " ep_reward += reward # 累加奖励\n", @@ -248,27 +268,271 @@ " break\n", " steps.append(ep_step)\n", " rewards.append(ep_reward)\n", - " print(f'回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.2f}')\n", + " print(f\"回合:{i_ep+1}/{cfg['test_eps']},奖励:{ep_reward:.2f}\")\n", " print(\"完成测试\")\n", " env.close()\n", " return {'rewards':rewards}" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. 定义环境" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "import os\n", + "def all_seed(env,seed = 1):\n", + " ''' 万能的seed函数\n", + " '''\n", + " env.seed(seed) # env config\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " torch.manual_seed(seed) # config for CPU\n", + " torch.cuda.manual_seed(seed) # config for GPU\n", + " os.environ['PYTHONHASHSEED'] = str(seed) # config for python scripts\n", + " # config for cudnn\n", + " torch.backends.cudnn.deterministic = True\n", + " torch.backends.cudnn.benchmark = False\n", + " torch.backends.cudnn.enabled = False\n", + "def env_agent_config(cfg):\n", + " env = gym.make(cfg['env_name']) # 创建环境\n", + " if cfg['seed'] !=0:\n", + " all_seed(env,seed=cfg['seed'])\n", + " n_states = env.observation_space.shape[0]\n", + " n_actions = env.action_space.n\n", + " print(f\"状态空间维度:{n_states},动作空间维度:{n_actions}\")\n", + " cfg.update({\"n_states\":n_states,\"n_actions\":n_actions}) # 更新n_states和n_actions到cfg参数中\n", + " model = MLP(n_states, n_actions, hidden_dim = cfg['hidden_dim']) # 创建模型\n", + " memory = ReplayBuffer(cfg['memory_capacity'])\n", + " agent = DQN(model,memory,cfg)\n", + " return env,agent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4、设置参数" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "import argparse\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "def get_args():\n", + " \"\"\" 超参数\n", + " \"\"\"\n", + " parser = argparse.ArgumentParser(description=\"hyperparameters\") \n", + " parser.add_argument('--algo_name',default='DQN',type=str,help=\"name of algorithm\")\n", + " parser.add_argument('--env_name',default='CartPole-v0',type=str,help=\"name of environment\")\n", + " parser.add_argument('--train_eps',default=200,type=int,help=\"episodes of training\")\n", + " parser.add_argument('--test_eps',default=20,type=int,help=\"episodes of testing\")\n", + " parser.add_argument('--ep_max_steps',default = 100000,type=int,help=\"steps per episode, much larger value can simulate infinite steps\")\n", + " parser.add_argument('--gamma',default=0.95,type=float,help=\"discounted factor\")\n", + " parser.add_argument('--epsilon_start',default=0.95,type=float,help=\"initial value of epsilon\")\n", + " parser.add_argument('--epsilon_end',default=0.01,type=float,help=\"final value of epsilon\")\n", + " parser.add_argument('--epsilon_decay',default=500,type=int,help=\"decay rate of epsilon, the higher value, the slower decay\")\n", + " parser.add_argument('--lr',default=0.0001,type=float,help=\"learning rate\")\n", + " parser.add_argument('--memory_capacity',default=100000,type=int,help=\"memory capacity\")\n", + " parser.add_argument('--batch_size',default=64,type=int)\n", + " parser.add_argument('--target_update',default=4,type=int)\n", + " parser.add_argument('--hidden_dim',default=256,type=int)\n", + " parser.add_argument('--device',default='cpu',type=str,help=\"cpu or cuda\") \n", + " parser.add_argument('--seed',default=10,type=int,help=\"seed\") \n", + " args = parser.parse_args([])\n", + " args = {**vars(args)} # 转换成字典类型 \n", + " ## 打印超参数\n", + " print(\"超参数\")\n", + " print(''.join(['=']*80))\n", + " tplt = \"{:^20}\\t{:^20}\\t{:^20}\"\n", + " print(tplt.format(\"Name\", \"Value\", \"Type\"))\n", + " for k,v in args.items():\n", + " print(tplt.format(k,v,str(type(v)))) \n", + " print(''.join(['=']*80)) \n", + " return args\n", + "def smooth(data, weight=0.9): \n", + " '''用于平滑曲线,类似于Tensorboard中的smooth曲线\n", + " '''\n", + " last = data[0] \n", + " smoothed = []\n", + " for point in data:\n", + " smoothed_val = last * weight + (1 - weight) * point # 计算平滑值\n", + " smoothed.append(smoothed_val) \n", + " last = smoothed_val \n", + " return smoothed\n", + "\n", + "def plot_rewards(rewards,cfg, tag='train'):\n", + " ''' 画图\n", + " '''\n", + " sns.set()\n", + " plt.figure() # 创建一个图形实例,方便同时多画几个图\n", + " plt.title(f\"{tag}ing curve on {cfg['device']} of {cfg['algo_name']} for {cfg['env_name']}\")\n", + " plt.xlabel('epsiodes')\n", + " plt.plot(rewards, label='rewards')\n", + " plt.plot(smooth(rewards), label='smoothed')\n", + " plt.legend()\n", + " plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5、我准备好了!" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "超参数\n", + "================================================================================\n", + " Name \t Value \t Type \n", + " algo_name \t DQN \t \n", + " env_name \t CartPole-v0 \t \n", + " train_eps \t 200 \t \n", + " test_eps \t 20 \t \n", + " ep_max_steps \t 100000 \t \n", + " gamma \t 0.95 \t \n", + " epsilon_start \t 0.95 \t \n", + " epsilon_end \t 0.01 \t \n", + " epsilon_decay \t 500 \t \n", + " lr \t 0.0001 \t \n", + " memory_capacity \t 100000 \t \n", + " batch_size \t 64 \t \n", + " target_update \t 4 \t \n", + " hidden_dim \t 256 \t \n", + " device \t cpu \t \n", + " seed \t 10 \t \n", + "================================================================================\n", + "状态空间维度:4,动作空间维度:2\n", + "开始训练!\n", + "回合:10/200,奖励:14.00,Epislon:0.611\n", + "回合:20/200,奖励:10.00,Epislon:0.470\n", + "回合:30/200,奖励:11.00,Epislon:0.372\n", + "回合:40/200,奖励:18.00,Epislon:0.302\n", + "回合:50/200,奖励:15.00,Epislon:0.228\n", + "回合:60/200,奖励:62.00,Epislon:0.121\n", + "回合:70/200,奖励:128.00,Epislon:0.039\n", + "回合:80/200,奖励:200.00,Epislon:0.011\n", + "回合:90/200,奖励:200.00,Epislon:0.010\n", + "回合:100/200,奖励:200.00,Epislon:0.010\n", + "回合:110/200,奖励:200.00,Epislon:0.010\n", + "回合:120/200,奖励:200.00,Epislon:0.010\n", + "回合:130/200,奖励:200.00,Epislon:0.010\n", + "回合:140/200,奖励:200.00,Epislon:0.010\n", + "回合:150/200,奖励:200.00,Epislon:0.010\n", + "回合:160/200,奖励:200.00,Epislon:0.010\n", + "回合:170/200,奖励:200.00,Epislon:0.010\n", + "回合:180/200,奖励:200.00,Epislon:0.010\n", + "回合:190/200,奖励:200.00,Epislon:0.010\n", + "回合:200/200,奖励:200.00,Epislon:0.010\n", + "完成训练!\n" + ] + }, + { + "data": { + "image/png": "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d5OSklLhObZt28by5cuZPn06L730Ekajkdtvv73SX0hVPWbfvn1ce+21AMyfP5/bb7+dZcuWsXnz5kr7u2PHDiZPnozNZuOZZ57h0UcfZdu2bUydOhWn01mDnxwsWbKESy65hIULFzJmzBgGDRrEF1984XXMV199haZpXHzxxQA88sgjLFy4kEsvvZQlS5YwduxYnnjiCV566aUKz1NYWMhVV13FZ599xg033MDixYvp378/DzzwAEuWLPE69s0332T//v08+eSTPP7442zbtq3K+qO7776b119/nX/84x96dmHmzJleH9Dfffcdq1evZvbs2Tz66KPs3LmTKVOmUFBQUKOfWWkff/wx119/Pc2aNWP+/PnMmjWLLVu28M9//pNTp04xcuRIFi1aBMC0adN49913a3We9u3b07x5c/318csvv2Cz2Tj//PMrfMywYcOIjIzk22+/9doeFBTEk08+SUpKCs8880y12/CPf/yDhx56CICHHnpI79dDDz2kB6Evv/wykyZN4u233+bWW2/1qifZtGkTx48f56WXXuKuu+7CaDSWOcfPP/8MUGFdR1BQEA899BBDhgwBICkpiWuvvZbIyEief/55Xn75ZQYMGMCiRYu8/gABd6B144038swzzzB06FD9A37RokXceuutVfb/wIEDALRq1QqAxYsXc+edd9KnTx8WLlzIf/7zH9asWcOUKVMoLCws9zmWLl3Kgw8+yJAhQ1iyZAmTJk3ilVde4cEHH6z03Jdeeilr1671Ciz37dtHUlIS48ePp7CwkKNHj9KuXTuvx0VHRxMWFqa3XdQfGfoRuo4dOxIWFgZQJh171VVXMXbsWP375ORkpk6d6vVLqUWLFlx++eVs3rxZ/zAuLScnh9WrV9O6dWsAQkJCmDx5Mr///jtjxoyp1WOWLl1KeHg4r776KlarFXB/GP3rX/+qtL9LliwhMjKS1157jaCgIADi4+O566672LNnT6WPLW3AgAFcd911+vfjx4/n/vvv59ixY3qa+IsvvmDo0KHExcVx4MAB3nvvPe68805uuukmwP1hqCgKS5cu5aqrriIqKqrMeVavXs3u3bt555136Nu3LwDDhw/H6XSyePFi/vWvfxEZGQm4hyUWL16sf4gdPnxYLwwt77l3797NmjVruP/++7nmmmsA99DH0aNHWb9+PePGjQOgoKCA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a55++ukat2vQoEEAZYqwv/jiC1wul359qqtTp06MGDGCV155heTk5DL7ly5dSkZGBpdeeingvkaDBw/m/PPP14OUbdu2kZ6eXuV7ujq/NyrSu3dvLBZLmWu/adMmjh07Vu617927N2azmdTUVK/3j8lkYv78+Rw5coSwsDCvfb169dLf0xEREZx77rl89913rFmzhksvvdRrSOfss8/mxx9/9PrdsGbNGoxGI2eddVat+ypqRzIqwktERARbtmzht99+o3v37uUeExMTQ4sWLVi5ciUJCQlERETw888/8+abbwKV15vUhVtuuYUvv/ySG264geuvv57s7GxeeOEFDAZDpePJt956K//85z+5+eabufrqqyksLGTBggUkJiZy9tlnU1hYSHBwME899RT/93//p6/94PnrvypGo5GLL76Yt99+m6ZNmzJ48GB9X5cuXbj00kt58MEHOXr0KD179uTAgQM8//zztGzZsty/EgEuv/xyVq1axX/+8x+mT59Oy5Yt+f777/nwww+57bbb9L80a6Nr166MHTuWZ599lsLCQrp168ZPP/3EDz/8oM9KAff1veGGG5g2bRp5eXk8//zzdO7cWa8xOPfcc3nrrbd44IEHuOKKK9i9ezevv/56uTNTPAwGA3feeSezZs3irrvu4tJLLyUjI4NFixbRpEkTr0Ll6kpJSeHPP/8E3NmD1NRUPvroI9atW1emEPW2227j4MGDTJs2jSuuuIJRo0Zx0UUXcfjwYZ5//nkAnn766TLDaaWVHAKqqY4dOzJhwgQWLlxIQUEBAwcOZOfOnSxatIjBgwczfPjwGj/no48+yjXXXMOVV17J1VdfTe/evcnLy+Orr77iiy++4F//+pdeJJ+YmMj//vc//vvf/9KhQweSkpJ4+eWXURSlyve053X3zTffMGLEiBplHSIjI7npppt46aWXMJvNnHvuuRw5coQXXnhB/5mUFhUVxQ033MALL7xAbm4ugwcPJjU1lRdeeAFFUfRh6MpceumlTJ8+HZfL5fVHBMANN9ygD9ted911HDx4kPnz53PllVfKGioNQAIV4WXSpEls27aNG2+8kSeffLLCFWI9qeKZM2disVjo2LEjL7/8Mk888QSbNm3S14ioD23atGH58uU888wzTJ8+nZiYGG6++WZefvnlSsfyu3fvzltvvcVzzz3HHXfcQVhY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04dRo0bx5ptvNnCLq2/9+vXl9q1Lly6cd955ALz88svl7vcXS5cuLfOaq+qa+dv7tLw+fv/990ycOJG+ffsyatQonn76aQoLC/X9mzdvLve6lrypa2NRXv9mz55dpu2jRo3S9/v7NZwyZUqF782PP/4YAJfLRWJiYpn9L774YgP1wltVnw+//fYbl19+Ob1792bs2LF88cUXXo+32Ww8+uijDBkyhL59+3LXXXeRnp7u20ZqoowXX3xRGzx4sPbDDz9oO3fu1K6//npt9OjRms1ma+im1cp1112njRs3Ttu4caO2f/9+7dFHH9USExO1ffv2aZqmaUOGDNFWrVqlpaWl6f8yMjIattE19OOPP2q9evXSUlNTvfpRUFCgpaena4MHD9ZmzZql7d27V/vggw+0Xr16aR988EFDN7tabDabV5/S0tK0r7/+WuvSpYveh//7v//T7rnnnjLH+YO3335b69q1qzZ58mR9W3WumT+9T8vr48aNG7Vu3bppL7/8snbgwAHtxx9/1EaMGKHNnDlTP2blypXa+eefX+a6NrY+ltc/TdO0K664Qps/f75X20+dOqXv9/drmJGR4dW31NRU7aqrrtIuvvhiLTc3V9M0Tdu7d6/WuXNnbefOnV7HevY3tMo+H/bu3av16tVLmz9/vrZ3717t1Vdf1bp37679+uuv+uNnzpypnX/++drGjRu1v/76S7vsssu0SZMm+bSNEqiUYrPZtL59+2orV67Ut2VlZWmJiYnaZ5991oAtq52DBw9qnTt31jZt2qRvU1VVO//887UFCxZoJ0+e1Dp37qxt3769AVt5+pYtW6Zdcskl5e5bsmSJNmzYMM3hcOjbnnvuOW306NH11TyfysvL084991yvD7QLL7xQe/311xuuUbWQkpKi3XzzzVqfPn20sWPHen0AVHXN/OV9Wlkf77rrLu3aa6/1Ov6jjz7SevTooX9QP/zww9ott9xSr22uicr6p6qq1qdPH+3rr78u97GBcA1Le+utt7SePXvqfwRqmqZ98cUXWr9+/eqjqTVW1efDgw8+qF1xxRVej7nzzju166+/XtM098+ma9eu2o8//qjv379/v9a5c2ftjz/+8Fk7ZeinlKSkJPLy8hgyZIi+LSIigu7du7Nx48YGbFntREVFsWzZMnr16qVvUxQFRVHIzs5m165dKIpCu3btGrCVp2/Xrl106NCh3H2bNm1i0KBBmEzFNws/66yzOHjwICdPnqyvJvrMkiVLKCgo4L777gPAbrdz8OBB2rdv38Atq5nt27djNpv59NNP6d27t9e+qq6Zv7xPK+vj9ddfr19DD4PBgMPhIDc3F6j8dd0YVNa/w4cPk5+fX+HrMhCuYUnp6eksWLCAadOmefW5MV/Dqj4fNm3a5HV9wP0+3Lx5M5qmsXnzZn2bR7t27WjatKlPr6Gp6kPOLCkpKQA0a9bMa3t8fLy+z59ERERwzjnneG1bs2YNhw4d4v7772f37t2Eh4fz2GOP8csvvxASEsLYsWO59dZbsVgsDdTqmtu9ezdRUVFMmjSJAwcO0KZNG6ZNm8aIESNISUmhc+fOXsfHx8cDcPz4cWJjYxuiybWSnp7OihUruOuuu4iMjARg7969uFwu1qxZw9y5c7HZbAwcOJB77rlH72djNGrUKK96hZKqumb+8j6trI/du3f3+t7hcLBixQp69uxJdHQ0AHv27CEqKorLL7+c1NRUOnfuzIwZM0hMTKzztldHZf3bvXs3AG+99RY//fQTBoOBESNGMGPGDMLDwwPiGpb0yiuvEBwczNSpU7227969G6fTydSpU0lKSqJp06Zcc801jB8/vq6aXG1VfT589NFHJCQkeO2Pj4+noKCAjIwMUlNTiYqKIigoqMwxvryGklEppaCgAKDMh3RQUBA2m60hmuRTf/zxB7NmzWL06NGMHDmS3bt3Y7PZSExM5NVXX2XatGm8//77zJ49u6GbWm1Op5P9+/eTlZXF7bffzrJly+jTpw833XQTv/32G4WFheVeT8DvrumqVasIDw/nn//8p77N84FgtVp54YUXmDt3Lvv37+fqq6/2Ksz0J1Vds0B7nzqdTu6991727NnDww8/DLgDspycHPLz85k9ezaLFy8mNjaWyZMns3fv3gZucdV2796NwWAgPj6eJUuWMHPmTNatW8ett96KqqoBdQ1zc3N57733mDp1apkP7T179pCZmcmUKVNYvnw5Y8aMYdasWXzwwQcN1NqKlf58KO996PnebrdTUFBQ7h+0vr6GklEpJTg4GHBfBM/X4P7laLVaG6pZPvHtt99y9913069fP+bNmwfAY489xn333UeTJk0A6Ny5M2azmRkzZnDvvff6RbbBZDKxfv16jEajfs169uzJnj17WL58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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "开始测试!\n", + "回合:1/20,奖励:200.00\n", + "回合:2/20,奖励:200.00\n", + "回合:3/20,奖励:200.00\n", + "回合:4/20,奖励:200.00\n", + "回合:5/20,奖励:200.00\n", + "回合:6/20,奖励:200.00\n", + "回合:7/20,奖励:200.00\n", + "回合:8/20,奖励:200.00\n", + "回合:9/20,奖励:200.00\n", + "回合:10/20,奖励:200.00\n", + "回合:11/20,奖励:200.00\n", + "回合:12/20,奖励:200.00\n", + "回合:13/20,奖励:200.00\n", + "回合:14/20,奖励:200.00\n", + "回合:15/20,奖励:200.00\n", + "回合:16/20,奖励:200.00\n", + "回合:17/20,奖励:200.00\n", + "回合:18/20,奖励:200.00\n", + "回合:19/20,奖励:200.00\n", + "回合:20/20,奖励:200.00\n", + "完成测试\n" + ] + }, + { + "data": { + "image/png": "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iYqK4uWXX7a+8ZctW5YiRYoQExNj8/h5e3szZcqUDH+l31kr3D6Nfqc1a9aQlpZmDU+5UbZsWTw9Pfnll19slv/73/+ma9eu1jk3f39sk5KS2LRpk3WOUvrjdv78eWubY8eO3fPMTmBgIL/88ovNJOy0tDTWrFlDtWrVcnUfmcwsW7aMuLg46wRWuP0X/cmTJ23mdvz66680btyYoUOHMnLkSG7evEn37t3vuu9GjRrRvHlzIiMj73nVzt+VKVOGYsWKsXr1apvlp0+f5rfffiMgICBH+zOZTHTq1IkNGzbwn//8J8P6bdu2sXHjRutQ6a5du/Dw8ODtt9+2Bpvr16+za9euew5t3TmclFMFChSgatWq/PDDDzZ/SFy7do0NGzZk+pouWLAglStX5vjx4zY/PxUqVGD69OnW4dk716X/fKVr2bIlmzdvZs2aNQQEBFjnGcHt+T7Hjh2zuQrt6NGjHDt2jLp16+a6VvnndOZG8pSHhwd79uxh69atVK5cmdatW7N48WLeeustunfvTokSJfjvf//LZ599Rvv27XF2dqZOnTpMnjyZXr160b59exwdHfnqq69wcXGxzofx8PDg4sWLbNy4MUfj+HdKfzPp1asX/fr1w8PDg88//5xLly5ZT81npnXr1ixatIgePXrQt29fPD09WbhwISkpKbRt25ZChQrh7+/PokWLePrppylUqBALFy4kKSkp26flX375Zfr27UtaWpp1siLcfjMYMGAAI0eOxNHRkYYNG5KQkMCsWbOIjY3NcrivfPnyvPLKK0ybNo2bN28SGBjIgQMHmDFjBrVr1+a5557L2YN3h/Srqd5//32KFClCaGgoJ06cYNq0abRr187mbFJ4eDj9+/enSJEizJs3jxs3blgvca9duzb58+fnww8/pF+/fly/fp1p06ZlOZyTrnfv3mzatIk333yTrl274uzszOLFizl9+jRz587NcT2JiYn89ttvwO2zSPHx8fz6668sW7aMl19+mcaNG1vbhoSEMGTIECZOnMj+/ft55ZVX8Pb25s0337TewLJ169bZujprxIgRbNu2LdMzEXdjMpkYOHAg4eHhDBo0iJdffpn4+HhmzJhBoUKFeOutt3K0P4BOnTqxc+dO+vTpQ5s2bahfvz4mk4mdO3eyaNEinnnmGQYNGgTcPsv65Zdf8uGHH9KwYUMuXLjA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t1xvfy8eHq73bd+PGnuqFeyrXtVqXPZUr2q1T7mejrx7927Cw8Np3LgxDRo0ICkpKUNQSf8+OTnZZvmCBQvw9fXl+eefv+sxjhw5AtyeaDRhwgSSkpKYPXs2bdu25fvvv6do0aK56rvZbCEh4Uautr0bR0cTHh6uJCTcNHx6tqdawb7qVa3GZU/1qlbj8fBwzfZZx1yFm3Xr1vHOO+8QEBDA5MmTAciXL1+GEJP+ffrHqQMkJSXx448/8u67795zpnutWrXYunUrnp6e1rYzZsygQYMGLF++/J5DWndzPz9gLC3NbIgPMMsOe6oV7Kte1Wpc9lSvarVPOR54Xbx4MX369KFhw4bMmTOHfPnyAVCiRAkuXLhg0/bChQsUKFAAd3d367ItW7aQkpLCSy+9lK3jeXl52YQgV1dXSpUqRWxsbE67LiIiInYgR+Fm6dKljB07lnbt2hEREWEzDFWrVi127Nhh037btm0EBATYzH6Ojo6mUqVKeHp63vN4y5Yto3bt2ty48b8hpMTERP766y/Kly+fk66LiIiInch2uDlx4gTjx4/nhRdeoFu3bly8eJG4uDji4uK4du0aHTp04I8//mDy5MkcO3aM+fPn8+OPP/L222/b7Gf//v1UqlQp02OkpaURFxdHUlISAPXq1cNsNjN48GCOHDnC3r176dOnD15eXrRu3foflC0iIiJGle1wExUVRUpKCj///DMhISE2X+PGjaNChQrMmjWLjRs30qpVK7755hsmTZpEcHCwzX7i4uIoXLhwpsc4d+4cISEhrF27Frg91LVgwQJu3LjBG2+8QadOnXB3d2fhwoXW4TARERGROzlY7PBTyNLSzFy+fD3P9+vkZMLT0434+OuGn9RlT7WCfdWrWo3LnupVrcbj5eWW7aulHvc7OYmIiIjYULgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUNRuBERERFDUbgRERERQ1G4EREREUPJcbi5cuUKI0eOpF69egQEBPDGG28QHR1tXb9161Zat25N9erVefHFF1mzZo3N9rt27cLX1zfD1/bt27M8ZkxMDN26dSMgIICQkBCmTp1KWlpaTrsuIiIidsAppxsMHDiQuLg4IiIiKFKkCIsWLSIsLIwVK1ZgsVjo1q0bb731FpMmTWLDhg0MHjwYLy8vgoODATh06BBPPfUUS5cutdlvoUKFMj1eSkoKYWFhlC5dmq+++opTp07x3nvvYTKZ6Nu3by5KFhERESPLUbg5efIkW7ZsYenSpdSsWROAESNGsHnzZr7//nsuXbqEr68vAwYMAKBcuXLs37+fuXPnWsPN4cOHKV++PMWKFcvWMaOiojh79ixff/01hQoVomLFily6dImJEyfSvXt3XFxcclKCiIiIGFyOwo2npyeRkZFUq1bNuszBwQEHBwcSEhKIjo6mUaNGNtvUqVOHcePGYbFYcHBw4NChQ9ZglB3R0dFUqVLF5sxOnTp1SExM5MCBA1SvXj0nJVg5OeX9dCNHR5PNv0ZmT7WCfdWrWo3LnupVrfYtR+HGw8OD+vXr2yyLiori5MmTDBs2jBUrVuDj42Ozvnjx4ty8eZP4+Hi8vLw4cuQInp6etG7dmtjYWCpWrMiAAQPw8/PL9Jjnz5/PdJ8A586dy1W4MZkc8PR0y/F22eXh4Xrf9v2osadawb7qVa3GZU/1qlb7lOM5N3favXs34eHhNG7cmAYNGpCUlJRhmCj9++TkZM6dO8e1a9e4ceMGw4cPx9HRkcWLF9O+fXuWL19O+fLlMxwjKSkJDw8Pm2X58uUD4NatW7nqt9lsISHhRq62vRtHRxMeHq4kJNwkLc2c5/t/lNhTrWBf9apW47KnelWr8Xh4uGb77FSuw826det45513CAgIYPLkycDt0JGcnGzTLv17V1dXChUqxM6dO3F1dcXZ2RmAatWqsX//fhYtWsSYMWMyHCd//vwZ9pkeagoUKJDb7pOaev9eAGlp5vu6/0eJPdUK9lWvajUue6pXtdqnXA3QLV68mD59+tCwYUPmzJljPZNSokQJLly4YNP2woULFChQAHd3d+D20FZ6sAEwmUyUK1eO2NjYTI/l4+OT6T4BvL29c9N9ERERMbAch5ulS5cyduxY2rVrR0REhM0wVK1atdixY4dN+23bthEQEIDJZGLTpk34+/tz+vRp6/rU1FQOHjyY6ZAUQGBgIPv37ycxMdFmn25ublSqVCmn3RcRERGDy1G4OXHiBOPHj+eFF16gW7duXLx4kbi4OOLi4rh27RodOnTgjz/+YPLkyRw7doz58+fz448/8vbbbwMQEBCAp6cnQ4YMYd++fRw6dIghQ4Zw5coVOnXqBNwexoqLi7MORTVq1IhixYrRv39/Dh48yLp164iIiKBz5866DFxEREQyyFG4iYqKIiUlhZ9//pmQkBCbr3HjxlGhQgVmzZrFxo0badWqFd988w2TJk2y3uOmYMGCLFiwgKJFixIWFsbrr7/OlStXWLx4MUWLFgVgz549hISEsGfPHuD2PJ65c+diNptp06YNY8aMoW3btvTs2TOPHwoRERExAgeLxWJ52J140NLSzFy+fD3P9+vkZMLT0434+OuGn9RlT7WCfdWrWo3LnupVrcbj5eWW7auldMcfERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExlByHmytXrjBy5Ejq1atHQEAAb7zxBtHR0db1W7dupXXr1lSvXp0XX3yRNWvW2Gx/7tw5Bg4cSN26dQkMDCQsLIwjR47c9ZjDhw/H19fX5is0NDSnXRcRERE74JTTDQYOHEhcXBwREREUKVKERYsWERYWxooVK7BYLHTr1o233nqLSZMmsWHDBgYPHoyXlxfBwcEkJyfTtWtXChcuzJw5c8ifPz/Tp0+nY8eOrF69Gi8vr0yPeejQIbp370779u2tyxwdHXNftYiIiBhWjsLNyZMn2bJlC0uXLqVmzZoAjBgxgs2bN/P9999z6dIlfH19GTBgAADlypVj//79zJ07l+DgYKKjozl8+DCbNm3C29sbgEmTJlG7dm3+85//8Nprr2U4psVi4ejRo3Tt2pVixYr903pFRETE4HIUbjw9PYmMjKRatWrWZQ4ODjg4OJCQkEB0dDSNGjWy2aZOnTqMGzcOi8VChQoViIyMtAYbAJPp9shYQkJCpsc8deoUN27coGzZsjnp6j05OeX9dCNHR5PNv0ZmT7WCfdWrWo3LnupVrfYtR+HGw8OD+vXr2yyLiori5MmTDBs2jBUrVuDj42Ozvnjx4ty8eZP4+HiKFSuWYftFixaRlJRE3bp1Mz3m4cOHre02bdqEyWSiXr16DBgwAHd395x038pkcsDT0y1X22aHh4frfdv3o8aeagX7qle1Gpc91ata7VOO59zcaffu3YSHh9O4cWMaNGhAUlISLi4uNm3Sv09OTs6w/c8//8yUKVPo1KkTvr6+mR7j8OHDmEwmihcvzpw5czh16hQTJ07kyJEjfPHFF9YzPzlhNltISLiR4+3uxdHRhIeHKwkJN0lLM+f5/h8l9lQr2Fe9qtW47Kle1Wo8Hh6u2T47letws27dOt555x0CAgKYPHkyAPny5csQYtK/d3W1TZRffvklY8eO5eWXX2bw4MFZHqdHjx60bdsWT09PACpWrEixYsVo06YNe/fupXr16rnqf2rq/XsBpKWZ7+v+HyX2VCvYV72q1bjsqV7Vap9yNUC3ePFi+vTpQ8OGDZkzZw758uUDoESJEly4cMGm7YULFyhQoIDNENKkSZMYPXo0b775JhMmTLjr2ReTyWQNNukqVKgAwPnz53PTfRERETGwHIebpUuXMnbsWNq1a0dERITNMFStWrXYsWOHTftt27YREBBgDTCTJk1i7ty5DBkyhKFDh+Lg4HDX4w0ePJhOnTrZLNu7dy8A5cuXz2n3RURExOByFG5OnDjB+PHjeeGFF+jWrRsXL14kLi6OuLg4rl27RocOHfjjjz+YPHkyx44dY/78+fz444+8/fbbAGzfvp25c+fSoUMHWrRoYd02Li6O69evA5CUlERcXBxpaWkANGnShK1btzJjxgxOnTrFxo0bGTZsGM2bN6dcuXJ5/HCIiIjI4y5Hc26ioqJISUnh559/5ueff7ZZ98orr/Dhhx8ya9YsJk2axBdffEGpUqWYNGkSwcHBAKxevRq4feXTokWLbLbv3bs3ffr0Ye3atYSHh7N+/XpKlSrF888/z9SpU4mMjOSzzz7D3d2dFi1a0L9//39QtoiIiBiVg8VisTzsTjxoaWlmLl++nuf7dXIy4enpRnz8dcNP6rKnWsG+6lWtxmVP9apW4/Hycsv21VK644+IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBiKwo2IiIgYisKNiIiIGIrCjYiIiBhKjsPNlStXGDlyJPXq1SMgIIA33niD6Oho6/qtW7fSunVrqlevzosvvsiaNWtstr916xZjxowhODgYf39/Bg0axOXLl+96zJiYGLp160ZAQAAhISFMnTqVtLS0nHZdRERE7ECOw83AgQPZs2cPERERfPfddzzzzDOEhYVx/Phxjh07Rrdu3XjuuedYvnw5//rXvxg8eDBbt261bj969Gh+/fVXpk+fzhdffMHx48fp27dvlsdLSUkhLCwMgK+++orRo0fz5ZdfMnPmzFyUKyIiIkbnYLFYLNltfPLkSRo3bszSpUupWbMmABaLhcaNG9O8eXMuXbrEgQMH+Oabb6zbDBo0iCtXrjBv3jxiY2Np0KABc+bMoX79+gCcOHGCF198ka+++gp/f/8Mx1y9ejXh4eH8+uuvFCpUCIBly5YxceJEtm7diouLS46LTkszc/ny9Rxvdy8mE7i6OHD16k1SU815vv9HiZOTiUKFXO2iVrCvelWrcdlTvar14XJxzY/JlLczX7y83HB0zN4+nXKyY09PTyIjI6lWrZp1mYODAw4ODiQkJBAdHU2jRo1stqlTpw7jxo3DYrGwa9cu67J0ZcqUwdvbm507d2YabqKjo6lSpYo12KRvn5iYyIEDB6hevXpOSrBycsrbB91sNnMwMpwS5nN5ut9HVQpw82F34gGyp3pVq3HZU72q9eE6aSrBM10n5HnAya4chRsPDw/rGZd0UVFRnDx5kmHDhrFixQp8fHxs1hcvXpybN28SHx9PbGwsnp6e5MuXL0Ob8+fPZ3rM8+fPZ7pPgHPnzuUq3JhMDnh6uuV4u7sxm83g4JCn+xQREXkcOTjcfp99LMLN3+3evZvw8HAaN25MgwYNSEpKyjBMlP59cnIyN2/ezHQYKV++fNy6dSvTYyQlJeHh4ZGhPZDlNvdiNltISLiRq23vpkr3D3FxtHAtMQlzWrZH+x5LJkcH3Avmt4tawb7qVa3GZU/1qtaHq5Jrfq5ezdvzSR4ervdnWOpO69at45133iEgIIDJkycDt0NHcnKyTbv0711dXcmfP3+G9XA7pLi6umZ6nMy2SQ81BQoUyG3378u4pJOTiQLuBbmV6vDIjHveL7drdbOLWsG+6lWtxmVP9arWh8ts/v8jGg9Jrs4XLV68mD59+tCwYUPmzJljPZNSokQJLly4YNP2woULFChQAHd3d3x8fLhy5UqGsHLhwgW8vb0zPZaPj0+m+wSy3EZERETsV47DzdKlSxk7dizt2rUjIiLCZpipVq1a7Nixw6b9tm3bCAgIwGQyUbNmTcxms3ViMdy+Wio2NpbAwMBMjxcYGMj+/ftJTEy02aebmxuVKlXKafdFRETE4HIUbk6cOMH48eN54YUX6NatGxcvXiQuLo64uDiuXbtGhw4d+OOPP5g8eTLHjh1j/vz5/Pjjj7z99tvA7TMtzZo1Y/jw4Wzfvp0//viDgQMHEhQURI0aNYDbw1hxcXHWszuNGjWiWLFi9O/fn4MHD7Ju3ToiIiLo3Llzri4DFxEREWPLUbiJiooiJSWFn3/+mZCQEJuvcePGUaFCBWbNmsXGjRtp1aoV33zzDZMmTSI4ONi6j7FjxxIcHEzv3r0JCwujbNmyTJs2zbp+z549hISEsGfPHuD2PJ65c+diNptp06YNY8aMoW3btvTs2TOPHgIRERExkhzdxM8o7tdN/JycTHh6uhEff/2RmdR1v9hTrWBf9apW47KnelWr8eTkJn764EwRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETEUhRsRERExFIUbERERMRSFGxERETGUfxRuPv30Uzp06GCzbPPmzbz66qv4+/vTokULVq9ebV23fPlyfH19M/168803szzOqlWrMt0mJibmn3RfREREDMgptxsuWbKE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n+Hu7k6LFi3o379/XnZdREREDMLBYrFYHnYnHrS0NDOXL1/P8/06OZnw9HQjPv664Sd12VOtYF/1qlbjsqd6VavxeHm5ZftqKd3xR0RERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDEXhRkRERAxF4UZEREQMReFGREREDOUfhZtPP/2UDh062CzbvHkzr776Kv7+/rRo0YLVq1fbrL916xZjxowhODgYf39/Bg0axOXLl+96nJiYGLp160ZAQAAhISFMnTqVtLS0f9J1ERERMahch5slS5YwdepUm2W7du2iS5cu1KhRg2+//Zbu3bszcuRIVq5caW0zevRofv31V6ZPn84XX3zB8ePH6du3b5bHSUlJISwsDICvvvqK0aNH8+WXXzJz5szcdl1EREQMzCmnG8TGxjJq1Ci2b99O6dKlbdbNmzcPPz8/RowYAUC5cuU4deoU06ZNo1WrVsTGxrJy5UrmzJlDrVq1AIiIiODFF19kz549+Pv7ZzheVFQUZ8+e5euvv6ZQoUJUrFiRS5cuMXHiRLp3746Li0suyhYRERGjynG4+fPPP3F2dmbVqlXMnDmTM2fOWNedPHmSevXq2bSvXLkyZ86c4ezZs/z2228A1KlTx7q+TJkyeHt7s3PnzkzDTXR0NFWqVKFQoULWZXXq1CExMZEDBw5QvXr1nJYAgJNT3k83cnQ02fxrZPZUK9hXvarVuOypXtVq33IcbkJDQwkNDc10XfHixTl37pzNspiYGAAuXbpEbGwsnp6e5MuXL8N258+fz3Sf58+fx8fHJ0N7gHPnzuUq3JhMDnh6uuV4u+zy8HC9b/t+1NhTrWBf9apW47KnelWrfcpxuLmbli1bMmzYMFatWkXTpk05cuQI8+fPB27Pnbl582amw0j58uXj1q1bme4zKSkJDw+PDO2BLLe5F7PZQkLCjVxtezeOjiY8PFxJSLhJWpo5z/f/KLGnWsG+6lWtxmVP9apW4/HwcM322ak8DTetWrXizJkzjBgxgiFDhlCiRAm6dOnC6NGjcXd3J3/+/CQnJ2fY7tatW7i6Zp44M9smPdQUKFAg131NTb1/L4C0NPN93f+jxJ5qBfuqV7Ualz3Vq1rtU54P0PXq1Yvdu3ezYcMG1q1bR8mSJXF0dKRkyZL4+Phw5cqVDGHlwoULeHt7Z7o/Hx8fLly4kKE9kOU2IiIiYr/yNNwsXryYsWPH4ujoiLe3NyaTiaioKPz9/XFzc6NmzZqYzWZ27dpl3ebEiRPExsYSGBiY6T4DAwPZv38/iYmJ1mXbtm3Dzc2NSpUq5WX3RURExADyNNyUK1eOr776ipUrVxITE0NkZCSrVq2iX79+wO0zLc2aNWP48OFs376dP/74g4EDBxIUFESNGjUASE5OJi4uznp2p1GjRhQrVoz+/ftz8OBB1q1bR0REBJ07d9Zl4CIiIpJBnoab4OBgxowZw6xZs2jWrBlRUVHMnj2boKAga5uxY8cSHBxM7969CQsLo2zZskybNs26fs+ePYSEhLBnzx7g9uThuXPnYjabadOmDWPGjKFt27b07NkzL7suIiIiBuFgsVgsD7sTD1pampnLl6/n+X6dnEx4eroRH3/d8JO67KlWsK96Vatx2VO9qtV4vLzcsn21lO74IyIiIoaicCMiIiKGonAjIiIihqJwIyIiIoaicCMiIiKGonAjIiIihqJwIyIiIoaicCMiIiKGYpc38bNYLJjN96dsR0eToT9y/k72VCvYV72q1bjsqV7VaiwmkwMODg7ZamuX4UZERESMS8NSIiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNzlgNpuZNm0azz33HDVq1KBLly6cPn06y/bx8fEMGjSIwMBAgoKCGDNmDDdv3nyAPc69K1euMHLkSOrVq0dAQABvvPEG0dHRWbafPXs2vr6+Gb4eF7GxsZn2f/ny5Zm2f1yf2+3bt2dap6+vL88//3ym2+zatSvT9tu3b3/Avc+ZTz/9lA4dOtgsO3DgAO3bt6dGjRqEhoaycOHCe+7nhx9+oGnTpvj5+dGqVSu2bt16v7r8j2RW73/+8x9effVV/P39CQ0N5aOPPiIpKSnLfaSlpeHn55fhuZ4+ffr97n6OZFbr8OHDM/Q7NDT0rvt5HJ7bv9faoUOHLH+GV65cmeV+3nrrrQzt//4YGopFsm369OmW2rVrW3755RfLgQMHLJ07d7Y0btzYcuvWrUzbt2/f3vLqq69a9u3bZ/nvf/9radiwoWXw4MEPuNe589Zbb1maN29u2blzp+X48eOWMWPGWPz8/CzHjh3LtH2/fv0s7777ruXChQs2X4+LDRs2WKpVq2aJjY216f/Nmzczbf+4Pre3bt3K8Bz99NNPFl9fX8u3336b6TZLliyxNGrUKMN2Wb3uHwWLFy+2VKpUydK+fXvrssuXL1tq165tCQ8Ptxw9etTy7bffWqpVq5Zl3RaLxbJ161ZLlSpVLF988YXl6NGjlg8//NBStWpVy9GjRx9EGdmWWb07d+60PPPMM5bZs2dbTpw4YdmwYYOlXr16lqFDh2a5n6NHj1oqVqxoOXDggM1znZiY+CDKyJbMarVYLJbXXnvNEhERYdPvS5cuZbmfx+G5zazW+Ph4mxpjY2Mtbdu2tTRr1uyuz1NwcLBl6dKlNtvGx8c/gCoeDoWbbLp165bF39/fsmTJEuuyq1evWvz8/Czff/99hva7d++2VKxY0eYHZfPmzRZfX1/L+fPnH0ifc+uvv/6yVKxY0RIdHW1dZjabLY0aNbJMnTo1021eeukly+eff/6Aepj3IiMjLS1atMhW28f5uf2769evWxo2bHjXN7xRo0ZZunfv/gB7lXvnz5+3dOvWzVKjRg3Liy++aPOmMGfOHEtISIglJSXFumzKlCmWxo0bZ7m/zp07W/r162ez7PXXX7eMGDEiz/ueG3erd9CgQZZOnTrZtF+xYoWlSpUqWQbTNWvWWAICAu5rn3PrbrWazWZLjRo1LD/99FO29/coP7d3q/XvFi1aZKlatWqWf3haLBbLxYsXLRUrVrT8+eef96O7jyQNS2XTwYMHuX79OsHBwdZlHh4eVK5cmZ07d2ZoHx0dTbFixShXrpx1WVBQEA4ODuzateuB9Dm3PD09iYyMpFq1atZlDg4OODg4kJCQkKF9cnIyf/31F2XLln2Q3cxThw4dsnmu7uZxfm7/bs6cOdy8eZMhQ4Zk2SYnj83D9ueff+Ls7MyqVauoXr26zbro6GiCgoJwcnKyLqtTpw5//fUXFy9ezLAvs9nM7t27bX7mAWrXrp3pz/zDcLd6O3funOF5NZlMpKSkkJiYmOn+HuXn+m61njp1ihs3bmT7d9Cj/tzerdY7Xb58malTp9KjR4+71n7o0CEcHBwoU6bM/ejuI8np3k0E4Pz58wCUKFHCZnnx4sWt6+4UGxuboa2LiwuFCxfm3Llz96+jecDDw4P69evbLIuKiuLkyZMMGzYsQ/ujR4+SlpZGVFQU48aN49atWwQGBvLuu+9SvHjxB9Xtf+Tw4cN4enrSrl07Tpw4wdNPP02PHj2oV69ehraP83N7p8uXL7NgwQIGDRpE4cKFs2x35MgRPD09ad26NbGxsVSsWJEBAwbg5+f34DqbTaGhoVnOszh//jwVK1a0WZb++jx37hxFixa1WZeQkMCNGzfw8fHJsE1mP/MPw93qrVy5ss33KSkpLFiwgKpVq+Ll5ZXpNocPHyY1NZWwsDAOHjyIt7c3HTt2pGXLlnne95y6W62HDx8GYNGiRWzatAmTyUS9evUYMGAA7u7uGdo/6s/t3Wq902effUb+/PkJCwu7a7vDhw/j7u7O+++/z5YtWyhQoAAvvvgiPXv2xMXFJa+6/UjRmZtsSp8s+vcXQr58+bh161am7TN70WTV/lG2e/duwsPDady4MQ0aNMiwPv0Xi6urK5988gnjxo3j+PHjvPnmm3edvPioSE1N5fjx41y9epU+ffoQGRlJjRo16Nq1a6YTDI3y3C5duhR3d3def/31LNucO3eOa9eucePGDYYPH86sWbMoWrQo7du35+jRow+wt/9cUlJSpj+/QKbPW/prN7s/84+y1NRUBg8ezJEjRxg1alSW7Y4cOcKVK1fo0KED8+bNo0mTJoSHh/Ptt98+wN7m3OHDhzGZTBQvXpw5c+YwdOhQfv31V3r27InZbM7Q3gjPbWJiIl9//TVhYWHW13FWDh8+zK1bt/Dz82Pu3Ln06NGDb775huHDhz+g3j54OnOTTfnz5wduD8Gk/x9u/1J0dXXNtH1ycnKG5bdu3aJAgQL3r6N5bN26dbzzzjsEBAQwefLkTNu0atWKevXq2fw1WKFCBerVq8d//vMfmjZt+qC6mytOTk5s374dR0dH63NbtWpVjhw5wrx58zKcujbKc7ty5UpatWpl83r+uxIlSrBz505cXV1xdnYGoFq1auzfv59FixYxZsyYB9Xdfyyz5y39jSyz5y39DSOzbTL7mX9UJSYm0r9/f3bs2MGMGTPuesZt9erVpKWl4ebmBkClSpU4e/Ys8+bN47XXXntQXc6xHj160LZtWzw9PQGoWLEixYoVo02bNuzduzfD0I4Rntt169aRnJzMq6++es+277//PkOGDKFQoULA7cfH2dmZAQMGMHjw4AxnLY1AZ26yKX0Y4sKFCzbLL1y4gLe3d4b2Pj4+GdomJydz5cqVx2aoZvHixfTp04eGDRsyZ86cu/518PfT3MWLF6dw4cKPxCne7HBzc8vwJl+hQgViY2MztDXCc3vw4EFOnz5NixYt7tnWw8PDGmzg9ryNcuXKZfrYPMoye97Sv8/sZ7hw4cIUKFAg2z/zj6ILFy7Qrl07fvvtN+bNm5dhuPnv8ufPbw026SpWrPjI/xybTCZrsElXoUIFgEz7boTndt26ddSvXx8PD497tnVycrIGm3R3e3yMQOEmmypVqkTBggVt7u2RkJDA/v37CQwMzNA+MDCQ8+fPc/LkSeuyHTt2AFCzZs373+F/aOnSpYwdO5Z27doRERFx13HZjz/+mCZNmmCxWKzLYmJiiI+Pp3z58g+iu//IkSNHCAgIyHDfln379mXa/8f9uYXbk2uLFClCpUqV7tpu06ZN+Pv729zPKTU1lYMHDz4Wz+2dAgMD2bVrF2lpadZl27Zto0yZMhQpUiRDewcHBwICAqzPbbrt27dTq1at+97ff+rq1at07NiRy5cvs2TJkkx/T90pISGBoKCgDPd22rt3r/WN8FE1ePBgOnXqZLNs7969AJm+Th/35xZu/wz//axyVjp06EB4eLjNsr179+Ls7Ezp0qXvQ+8ePoWbbHJxcaF9+/ZMnjyZ9evXc/DgQQYMGICPjw+NGzcmLS2NuLg461hu9erVCQgIYMCAAfzxxx9s27aNkSNH0qpVq0f+L4MTJ04wfvx4XnjhBbp168bFixeJi4sjLi6Oa9eukZycTFxcnPWU7gsvvMCZM2cYPXo0J06cYOfOnfTp04eAgACee+65h1zNvZUrV46yZcvy/vvvEx0dzbFjx5gwYQK//fYbPXr0MNRzm27//v1Z3mQxLi6O69evAxAQEICnpydDhgxh3759HDp0iCFDhnDlypUMbyaPuldffZXExETee+89jh49yvLly1mwYAHdunWztrl27RqXL1+2fv/WW2+xZs0aPv/8c44dO8bEiRM5cOAAHTt2fBgl5MiECRM4ffo0kyZNwsvLy/ozHBcXZw14V65c4cqVK8DtM3R16tTh448/ZuPGjfz1119ERkayatUq+vTp8xArubcmTZqwdetWZsyYwalTp9i4cSPDhg2jefPm1qu/jPTcnjt3jvj4+Cz/OLl+/TpxcXHW75s0acK///1vvvzyS06fPs3atWuZOHEiYWFhFCxY8EF1+8F62NeiP05SU1MtEydOtNSpU8dSo0YNS5cuXSynT5+2WCwWy+nTpy0VK1a0fPfdd9b2Fy9etPTp08dSo0YNS+3atS2jRo2yJCUlPazuZ9vs2bMtFStWzPRryJAhlm3btlkqVqxo2bZtm3Wb//73v5bXX3/dUqNGDUtQUJAlPDzccuXKlYdYRc7ExcVZhg4daqlbt66lWrVqltdff92yc+dOi8VirOc23dtvv23p379/pusqVqxomTZtmvX7kydPWvr06WMJCgqyVK9e3dK5c2fLoUOHHlRXc23IkCEZ7g/y+++/W9q0aWOpWrWqpWHDhpZFixZl2KZhw4Y2y1asWGF54YUXLNWqVbO88sorlv/+97/3ve+5cWe9qamplmrVqmX5c5z+e6t9+/Y2j9G1a9cs48ePt9SvX99StWpVS8uWLS0///zzQ6nnbjJ7bteuXWtp1aqVxc/Pz1K3bl3Lhx9+aPMz+bg+t1m9jv9+r607TZs2zVKxYkWbZYsXL7a89NJL1tf+7NmzLWlpafet3w+bg8Vyx1iCiIiIyGNOw1IiIiJiKAo3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyLyWIqJicHX1zfDZyHlxtChQwkNDc2DXonIo8DpYXdARCQ3ihcvzrJly3jqqacedldE5BGjcCMijyUXFxdq1KjxsLshIo8gDUuJyH3xzTff0KxZM6pWrUqDBg2YPn269dOohw4dSocOHfj2229p2LAh/v7+dOzYkYMHD1q3N5vNfPzxx4SGhlK1alVCQ0OZMmUKKSkpQObDUn/99Rd9+/albt261KhRgw4dOrBr1y6bfl29epXw8HCCgoIIDAxk0qRJmM3mDP1ft24drVu3plq1atStW5cPPviAGzduWNcnJSUxevRo6tWrR9WqVXnxxReZN29enj6GIpI7OnMjInnu008/5eOPP6Z9+/aEh4dz4MABpk+fzrlz5xg/fjwABw4c4Pjx4wwcOJBChQoxbdo02rdvz9q1aylevDifffYZX375JUOGDOHJJ5/k999/5+OPP8bZ2Zm+fftmOObRo0dp06YNpUuXZvjw4Tg7O7Nw4UI6duzI/PnzCQoKwmw28/bbb3PmzBmGDBlC4cKFmTt3Lnv37qV48eLWfX3//fe88847tGjRgv79+3PmzBk+/vhjjh49yueff46DgwPjx4/n119/ZciQIRQtWpRNmzYxceJEChcuzKuvvvrAHmsRyUjhRkTy1LVr15g1axavv/46w4cPByAkJITChQszfPhw3nrrLWu7OXPmUKtWLQD8/Pxo1KgRCxcu5J133mHHjh1UrVrVGhSCgoJwdXXF3d090+POmDEDFxcXFi5cSMGCBQFo0KABzZs3Z+LEiXz77bds2rSJP/74g88++4x69eoBEBwcbDOZ2GKxMHnyZJ577jkmT55sXV66dGk6derExo0badCgATt27KBu3bo0a9YMgNq1a1OgQAGKFCmSlw+niOSChqVEJE/t2bOHpKQkQkNDSU1NtX6lB4gtW7YAUKpUKWuwgdsThP39/dm5cydwOyxs2bKFtm3bMnfuXI4ePUr79u1p2bJlpsfdsWMHDRs2tAYbACcnJ5o1a8a+ffu4fv060dHRODs789xzz1nbFChQgPr161u/P378OOfPn8/Q/8DAQAoWLGjtf+3atfn666/p0qULixcv5vTp0/Tq1YsGDRrkzQMpIrmmMzcikqeuXLkCQNeuXTNdf+HCBQC8vb0zrCtSpAh//vknAG+//TZubm589913TJ48mUmTJlGhQgWGDx9OnTp1Mmx79epVihYtmmF50aJFsVgsJCYmcvXqVQoXLoyDg4NNm2LFimXo/5gxYxgzZkyW/X/vvffw8fFh1apVjB07lrFjx+Lv78/o0aOpVKlSprWLyIOhcCMiecrDwwOAyZMnU7p06QzrixYtyieffEJ8fHyGdRcvXrQO65hMJtq1a0e7du24dOkSGzduZM6cOfTp08d69uROhQoV4uLFixmWx8XFAeDp6Ymnpyfx8fGkpaXh6OhobZMeaO7s/+DBgwkKCsr0OHD7aq0ePXrQo0cPzp49yy+//MKsWbMYNGgQa9asyerhEZEHQMNSIpKnqlevjrOzM7GxsVSrVs365eTkREREBDExMcDtK5uOHTtm3S42NpY9e/YQHBwMwP/93//xwQcfALfP6LRu3Zp27dqRkJBAYmJihuMGBgbyyy+/2KxLS0tjzZo1VKtWDRcXF4KDg0lNTWXdunXWNsnJyTZhqWzZshQpUoSYmBib/nt7ezNlyhT2799PUlISTZo0Yf78+QCULFmSdu3a0axZM86ePZuHj6aI5IbO3IhInvL09OTtt9/mk08+ITExkdq1axMbG8snn3yCg4ODdcjGYrHQvXt3BgwYgKOjIzNmzKBQoUJ06NABuB1W5s+fT9GiRfH39yc2NpbPP/+coKAgvLy8bC7LBujduzebNm3izTffpGvXrjg7O1vnwsydOxe4PXk4JCSE4cOHc+nSJZ544gkWLlzI5cuXrWeMHB0dGTBgACNHjsTR0ZGGDRuSkJDArFmziI2NpUqVKuTPn58qVaowY8YMnJ2d8fX15cSJE6xYsYImTZo8wEdbRDLjYLFYLA+7EyJiPEuWLGHp0qWcPHmSQoUKERwczMCBAylZsiRDhw5lx44ddOnShZkzZ3Lz5k2effZZhgwZQqlSpQBITU1l9uzZrFq1ivPnz+Pu7k5oaCiDBg3C09OTmJgYnn/+eSZMmEDr1q2B25eXR0REEB0djYODA35+fvTu3dtm4vLNmzeZPHkya9as4datWzRt2pQCBQqwfv16/vOf/1jbrV27lrlz53LkyBEKFChAQEAA/fv3x9fXF4DExESmTp3K+vXriYuLo0iRIjRt2pR+/fqRP3/+B/hIi8jfKdyIyAOXHm7uDBMiInlFc25ERETEUBRuRERExFA0LCUiIiKGojM3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyIiImIoCjciIiJiKAo3IiIiYigKNyIiImIo/w+ztV4eBAvaNAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 获取参数\n", + "cfg = get_args() \n", + "# 训练\n", + "env, agent = env_agent_config(cfg)\n", + "res_dic = train(cfg, env, agent)\n", + " \n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"train\") \n", + "# 测试\n", + "res_dic = test(cfg, env, agent)\n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"test\") # 画出结果" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.7.13 ('easyrl')", + "display_name": "Python 3.7.12 ('easyrl')", "language": "python", "name": "python3" }, "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", "name": "python", - "version": "3.7.13" + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.12" }, "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "8994a120d39b6e6a2ecc94b4007f5314b68aa69fc88a7f00edf21be39b41f49c" + "hash": "f5a9629e9f3b9957bf68a43815f911e93447d47b3d065b6a8a04975e44c504d9" } } }, diff --git a/projects/notebooks/DDPG.ipynb b/projects/notebooks/DDPG.ipynb new file mode 100644 index 0000000..5194644 --- /dev/null +++ b/projects/notebooks/DDPG.ipynb @@ -0,0 +1,559 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. 定义算法" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1. 定义模型\n", + "\n", + "注意DDGP中critic网络的输入是state加上action。" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "class Actor(nn.Module):\n", + " def __init__(self, n_states, n_actions, hidden_dim = 256, init_w=3e-3):\n", + " super(Actor, self).__init__() \n", + " self.linear1 = nn.Linear(n_states, hidden_dim)\n", + " self.linear2 = nn.Linear(hidden_dim, hidden_dim)\n", + " self.linear3 = nn.Linear(hidden_dim, n_actions)\n", + " \n", + " self.linear3.weight.data.uniform_(-init_w, init_w)\n", + " self.linear3.bias.data.uniform_(-init_w, init_w)\n", + " \n", + " def forward(self, x):\n", + " x = F.relu(self.linear1(x))\n", + " x = F.relu(self.linear2(x))\n", + " x = torch.tanh(self.linear3(x))\n", + " return x\n", + " \n", + "class Critic(nn.Module):\n", + " def __init__(self, n_states, n_actions, hidden_dim=256, init_w=3e-3):\n", + " super(Critic, self).__init__()\n", + " \n", + " self.linear1 = nn.Linear(n_states + n_actions, hidden_dim)\n", + " self.linear2 = nn.Linear(hidden_dim, hidden_dim)\n", + " self.linear3 = nn.Linear(hidden_dim, 1)\n", + " # 随机初始化为较小的值\n", + " self.linear3.weight.data.uniform_(-init_w, init_w)\n", + " self.linear3.bias.data.uniform_(-init_w, init_w)\n", + " \n", + " def forward(self, state, action):\n", + " # 按维数1拼接\n", + " x = torch.cat([state, action], 1)\n", + " x = F.relu(self.linear1(x))\n", + " x = F.relu(self.linear2(x))\n", + " x = self.linear3(x)\n", + " return x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.2 定义经验回放" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import deque\n", + "import random\n", + "class ReplayBuffer:\n", + " def __init__(self, capacity: int) -> None:\n", + " self.capacity = capacity\n", + " self.buffer = deque(maxlen=self.capacity)\n", + " def push(self,transitions):\n", + " '''_summary_\n", + " Args:\n", + " trainsitions (tuple): _description_\n", + " '''\n", + " self.buffer.append(transitions)\n", + " def sample(self, batch_size: int, sequential: bool = False):\n", + " if batch_size > len(self.buffer):\n", + " batch_size = len(self.buffer)\n", + " if sequential: # sequential sampling\n", + " rand = random.randint(0, len(self.buffer) - batch_size)\n", + " batch = [self.buffer[i] for i in range(rand, rand + batch_size)]\n", + " return zip(*batch)\n", + " else:\n", + " batch = random.sample(self.buffer, batch_size)\n", + " return zip(*batch)\n", + " def clear(self):\n", + " self.buffer.clear()\n", + " def __len__(self):\n", + " return len(self.buffer)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import torch.optim as optim\n", + "import numpy as np\n", + "class DDPG:\n", + " def __init__(self, models,memories,cfg):\n", + " self.device = torch.device(cfg['device'])\n", + " self.critic = models['critic'].to(self.device)\n", + " self.target_critic = models['critic'].to(self.device)\n", + " self.actor = models['actor'].to(self.device)\n", + " self.target_actor = models['actor'].to(self.device)\n", + " \n", + " # 复制参数到目标网络\n", + " for target_param, param in zip(self.target_critic.parameters(), self.critic.parameters()):\n", + " target_param.data.copy_(param.data)\n", + " for target_param, param in zip(self.target_actor.parameters(), self.actor.parameters()):\n", + " target_param.data.copy_(param.data)\n", + " self.critic_optimizer = optim.Adam(\n", + " self.critic.parameters(), lr=cfg['critic_lr'])\n", + " self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=cfg['actor_lr'])\n", + " self.memory = memories['memory']\n", + " self.batch_size = cfg['batch_size']\n", + " self.gamma = cfg['gamma']\n", + " self.tau = cfg['tau'] # 软更新参数\n", + " def sample_action(self, state):\n", + " state = torch.FloatTensor(state).unsqueeze(0).to(self.device)\n", + " action = self.actor(state)\n", + " return action.detach().cpu().numpy()[0, 0]\n", + " @torch.no_grad()\n", + " def predict_action(self, state):\n", + " ''' 用于预测,不需要计算梯度\n", + " '''\n", + " state = torch.FloatTensor(state).unsqueeze(0).to(self.device)\n", + " action = self.actor(state)\n", + " return action.cpu().numpy()[0, 0]\n", + " def update(self):\n", + " if len(self.memory) < self.batch_size: # 当memory中不满足一个批量时,不更新策略\n", + " return\n", + " # 从经验回放中中随机采样一个批量的transition\n", + " state, action, reward, next_state, done = self.memory.sample(self.batch_size)\n", + " # 转变为张量\n", + " state = torch.FloatTensor(np.array(state)).to(self.device)\n", + " next_state = torch.FloatTensor(np.array(next_state)).to(self.device)\n", + " action = torch.FloatTensor(np.array(action)).to(self.device)\n", + " reward = torch.FloatTensor(reward).unsqueeze(1).to(self.device)\n", + " done = torch.FloatTensor(np.float32(done)).unsqueeze(1).to(self.device)\n", + " # 注意看伪代码,这里的actor损失就是对应策略即actor输出的action下对应critic值的负均值\n", + " actor_loss = self.critic(state, self.actor(state))\n", + " actor_loss = - actor_loss.mean()\n", + "\n", + " next_action = self.target_actor(next_state)\n", + " target_value = self.target_critic(next_state, next_action.detach())\n", + " # 这里的expected_value就是伪代码中间的y_i \n", + " expected_value = reward + (1.0 - done) * self.gamma * target_value\n", + " expected_value = torch.clamp(expected_value, -np.inf, np.inf)\n", + "\n", + " actual_value = self.critic(state, action)\n", + " critic_loss = nn.MSELoss()(actual_value, expected_value.detach())\n", + " \n", + " self.actor_optimizer.zero_grad()\n", + " actor_loss.backward()\n", + " self.actor_optimizer.step()\n", + " self.critic_optimizer.zero_grad()\n", + " critic_loss.backward()\n", + " self.critic_optimizer.step()\n", + " # 各自目标网络的参数软更新\n", + " for target_param, param in zip(self.target_critic.parameters(), self.critic.parameters()):\n", + " target_param.data.copy_(\n", + " target_param.data * (1.0 - self.tau) +\n", + " param.data * self.tau\n", + " )\n", + " for target_param, param in zip(self.target_actor.parameters(), self.actor.parameters()):\n", + " target_param.data.copy_(\n", + " target_param.data * (1.0 - self.tau) +\n", + " param.data * self.tau\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. 定义训练\n", + "\n", + "注意测试函数中不需要动作噪声" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "class OUNoise(object):\n", + " '''Ornstein–Uhlenbeck噪声\n", + " '''\n", + " def __init__(self, action_space, mu=0.0, theta=0.15, max_sigma=0.3, min_sigma=0.3, decay_period=100000):\n", + " self.mu = mu # OU噪声的参数\n", + " self.theta = theta # OU噪声的参数\n", + " self.sigma = max_sigma # OU噪声的参数\n", + " self.max_sigma = max_sigma\n", + " self.min_sigma = min_sigma\n", + " self.decay_period = decay_period\n", + " self.n_actions = action_space.shape[0]\n", + " self.low = action_space.low\n", + " self.high = action_space.high\n", + " self.reset()\n", + " def reset(self):\n", + " self.obs = np.ones(self.n_actions) * self.mu\n", + " def evolve_obs(self):\n", + " x = self.obs\n", + " dx = self.theta * (self.mu - x) + self.sigma * np.random.randn(self.n_actions)\n", + " self.obs = x + dx\n", + " return self.obs\n", + " def get_action(self, action, t=0):\n", + " ou_obs = self.evolve_obs()\n", + " self.sigma = self.max_sigma - (self.max_sigma - self.min_sigma) * min(1.0, t / self.decay_period) # sigma会逐渐衰减\n", + " return np.clip(action + ou_obs, self.low, self.high) # 动作加上噪声后进行剪切\n", + "\n", + "def train(cfg, env, agent):\n", + " print(\"开始训练!\")\n", + " ou_noise = OUNoise(env.action_space) # 动作噪声\n", + " rewards = [] # 记录所有回合的奖励\n", + " for i_ep in range(cfg['train_eps']):\n", + " state = env.reset()\n", + " ou_noise.reset()\n", + " ep_reward = 0\n", + " for i_step in range(cfg['max_steps']):\n", + " action = agent.sample_action(state)\n", + " action = ou_noise.get_action(action, i_step+1) \n", + " next_state, reward, done, _ = env.step(action)\n", + " ep_reward += reward\n", + " agent.memory.push((state, action, reward, next_state, done))\n", + " agent.update()\n", + " state = next_state\n", + " if done:\n", + " break\n", + " if (i_ep+1)%10 == 0:\n", + " print(f\"回合:{i_ep+1}/{cfg['train_eps']},奖励:{ep_reward:.2f}\")\n", + " rewards.append(ep_reward)\n", + " print(\"完成训练!\")\n", + " return {'rewards':rewards}\n", + "def test(cfg, env, agent):\n", + " print(\"开始测试!\")\n", + " rewards = [] # 记录所有回合的奖励\n", + " for i_ep in range(cfg['test_eps']):\n", + " state = env.reset() \n", + " ep_reward = 0\n", + " for i_step in range(cfg['max_steps']):\n", + " action = agent.predict_action(state)\n", + " next_state, reward, done, _ = env.step(action)\n", + " ep_reward += reward\n", + " state = next_state\n", + " if done:\n", + " break\n", + " rewards.append(ep_reward)\n", + " print(f\"回合:{i_ep+1}/{cfg['test_eps']},奖励:{ep_reward:.2f}\")\n", + " print(\"完成测试!\")\n", + " return {'rewards':rewards}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. 定义环境" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "import os\n", + "import torch\n", + "import numpy as np\n", + "import random\n", + "class NormalizedActions(gym.ActionWrapper):\n", + " ''' 将action范围重定在[0.1]之间\n", + " '''\n", + " def action(self, action):\n", + " low_bound = self.action_space.low\n", + " upper_bound = self.action_space.high\n", + " action = low_bound + (action + 1.0) * 0.5 * (upper_bound - low_bound)\n", + " action = np.clip(action, low_bound, upper_bound)\n", + " return action\n", + "\n", + " def reverse_action(self, action):\n", + " low_bound = self.action_space.low\n", + " upper_bound = self.action_space.high\n", + " action = 2 * (action - low_bound) / (upper_bound - low_bound) - 1\n", + " action = np.clip(action, low_bound, upper_bound)\n", + " return action\n", + "def all_seed(env,seed = 1):\n", + " ''' 万能的seed函数\n", + " '''\n", + " env.seed(seed) # env config\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " torch.manual_seed(seed) # config for CPU\n", + " torch.cuda.manual_seed(seed) # config for GPU\n", + " os.environ['PYTHONHASHSEED'] = str(seed) # config for python scripts\n", + " # config for cudnn\n", + " torch.backends.cudnn.deterministic = True\n", + " torch.backends.cudnn.benchmark = False\n", + " torch.backends.cudnn.enabled = False\n", + "def env_agent_config(cfg):\n", + " env = NormalizedActions(gym.make(cfg['env_name'])) # 装饰action噪声\n", + " if cfg['seed'] !=0:\n", + " all_seed(env,seed=cfg['seed'])\n", + " n_states = env.observation_space.shape[0]\n", + " n_actions = env.action_space.shape[0]\n", + " cfg.update({\"n_states\":n_states,\"n_actions\":n_actions}) # 更新n_states和n_actions到cfg参数中\n", + " models = {\"actor\":Actor(n_states,n_actions,hidden_dim=cfg['actor_hidden_dim']),\"critic\":Critic(n_states,n_actions,hidden_dim=cfg['critic_hidden_dim'])}\n", + " memories = {\"memory\":ReplayBuffer(cfg['memory_capacity'])}\n", + " agent = DDPG(models,memories,cfg)\n", + " return env,agent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. 设置参数" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "import argparse\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "def get_args():\n", + " \"\"\" 超参数\n", + " \"\"\"\n", + " parser = argparse.ArgumentParser(description=\"hyperparameters\") \n", + " parser.add_argument('--algo_name',default='DDPG',type=str,help=\"name of algorithm\")\n", + " parser.add_argument('--env_name',default='Pendulum-v1',type=str,help=\"name of environment\")\n", + " parser.add_argument('--train_eps',default=300,type=int,help=\"episodes of training\")\n", + " parser.add_argument('--test_eps',default=20,type=int,help=\"episodes of testing\")\n", + " parser.add_argument('--max_steps',default=100000,type=int,help=\"steps per episode, much larger value can simulate infinite steps\")\n", + " parser.add_argument('--gamma',default=0.99,type=float,help=\"discounted factor\")\n", + " parser.add_argument('--critic_lr',default=1e-3,type=float,help=\"learning rate of critic\")\n", + " parser.add_argument('--actor_lr',default=1e-4,type=float,help=\"learning rate of actor\")\n", + " parser.add_argument('--memory_capacity',default=8000,type=int,help=\"memory capacity\")\n", + " parser.add_argument('--batch_size',default=128,type=int)\n", + " parser.add_argument('--target_update',default=2,type=int)\n", + " parser.add_argument('--tau',default=1e-2,type=float)\n", + " parser.add_argument('--critic_hidden_dim',default=256,type=int)\n", + " parser.add_argument('--actor_hidden_dim',default=256,type=int)\n", + " parser.add_argument('--device',default='cpu',type=str,help=\"cpu or cuda\") \n", + " parser.add_argument('--seed',default=1,type=int,help=\"random seed\")\n", + " args = parser.parse_args([]) \n", + " args = {**vars(args)} # 将args转换为字典 \n", + " # 打印参数\n", + " print(\"训练参数如下:\")\n", + " print(''.join(['=']*80))\n", + " tplt = \"{:^20}\\t{:^20}\\t{:^20}\"\n", + " print(tplt.format(\"参数名\",\"参数值\",\"参数类型\"))\n", + " for k,v in args.items():\n", + " print(tplt.format(k,v,str(type(v)))) \n", + " print(''.join(['=']*80)) \n", + " return args\n", + "def smooth(data, weight=0.9): \n", + " '''用于平滑曲线,类似于Tensorboard中的smooth\n", + "\n", + " Args:\n", + " data (List):输入数据\n", + " weight (Float): 平滑权重,处于0-1之间,数值越高说明越平滑,一般取0.9\n", + "\n", + " Returns:\n", + " smoothed (List): 平滑后的数据\n", + " '''\n", + " last = data[0] # First value in the plot (first timestep)\n", + " smoothed = list()\n", + " for point in data:\n", + " smoothed_val = last * weight + (1 - weight) * point # 计算平滑值\n", + " smoothed.append(smoothed_val) \n", + " last = smoothed_val \n", + " return smoothed\n", + "\n", + "def plot_rewards(rewards,cfg,path=None,tag='train'):\n", + " sns.set()\n", + " plt.figure() # 创建一个图形实例,方便同时多画几个图\n", + " plt.title(f\"{tag}ing curve on {cfg['device']} of {cfg['algo_name']} for {cfg['env_name']}\")\n", + " plt.xlabel('epsiodes')\n", + " plt.plot(rewards, label='rewards')\n", + " plt.plot(smooth(rewards), label='smoothed')\n", + " plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. 我准备好了!" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "训练参数如下:\n", + "================================================================================\n", + " 参数名 \t 参数值 \t 参数类型 \n", + " algo_name \t DDPG \t \n", + " env_name \t Pendulum-v1 \t \n", + " train_eps \t 300 \t \n", + " test_eps \t 20 \t \n", + " max_steps \t 100000 \t \n", + " gamma \t 0.99 \t \n", + " critic_lr \t 0.001 \t \n", + " actor_lr \t 0.0001 \t \n", + " memory_capacity \t 8000 \t \n", + " batch_size \t 128 \t \n", + " target_update \t 2 \t \n", + " tau \t 0.01 \t \n", + " critic_hidden_dim \t 256 \t \n", + " actor_hidden_dim \t 256 \t \n", + " device \t cpu \t \n", + " seed \t 1 \t \n", + "================================================================================\n", + "开始训练!\n", + "回合:10/300,奖励:-1549.57\n", + "回合:20/300,奖励:-1515.84\n", + "回合:30/300,奖励:-1413.30\n", + "回合:40/300,奖励:-972.99\n", + "回合:50/300,奖励:-829.94\n", + "回合:60/300,奖励:-727.91\n", + "回合:70/300,奖励:-954.71\n", + "回合:80/300,奖励:-1318.39\n", + "回合:90/300,奖励:-981.19\n", + "回合:100/300,奖励:-1262.05\n", + "回合:110/300,奖励:-640.49\n", + "回合:120/300,奖励:-1100.00\n", + "回合:130/300,奖励:-764.66\n", + "回合:140/300,奖励:-352.27\n", + "回合:150/300,奖励:-891.03\n", + "回合:160/300,奖励:-1318.07\n", + "回合:170/300,奖励:-124.30\n", + "回合:180/300,奖励:-240.08\n", + "回合:190/300,奖励:-491.77\n", + "回合:200/300,奖励:-1000.77\n", + "回合:210/300,奖励:-128.87\n", + "回合:220/300,奖励:-950.32\n", + "回合:230/300,奖励:-122.48\n", + "回合:240/300,奖励:-246.52\n", + "回合:250/300,奖励:-374.37\n", + "回合:260/300,奖励:-368.25\n", + "回合:270/300,奖励:-364.17\n", + "回合:280/300,奖励:-725.39\n", + "回合:290/300,奖励:-131.21\n", + "回合:300/300,奖励:-610.10\n", + "完成训练!\n", + "开始测试!\n", + "回合:1/20,奖励:-116.05\n", + "回合:2/20,奖励:-126.18\n", + "回合:3/20,奖励:-231.46\n", + "回合:4/20,奖励:-246.40\n", + "回合:5/20,奖励:-304.69\n", + "回合:6/20,奖励:-124.40\n", + "回合:7/20,奖励:-1.06\n", + "回合:8/20,奖励:-114.20\n", + "回合:9/20,奖励:-348.97\n", + "回合:10/20,奖励:-116.11\n", + "回合:11/20,奖励:-117.20\n", + "回合:12/20,奖励:-118.66\n", + "回合:13/20,奖励:-235.18\n", + "回合:14/20,奖励:-356.14\n", + "回合:15/20,奖励:-118.39\n", + "回合:16/20,奖励:-351.94\n", + "回合:17/20,奖励:-114.51\n", + "回合:18/20,奖励:-124.78\n", + "回合:19/20,奖励:-226.47\n", + "回合:20/20,奖励:-121.49\n", + "完成测试!\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjwAAAHJCAYAAACBuOOtAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOxdd5gdVfl+p9y2vSTZTe89hCQkgdCbgHRQQelN9KeIQhARkCIgUlQMGEF6k141gEiVkk5CCKGlZ5Ns77u3Tfn9MffMnHNm5ra9d3ezzPs8ebJ3ypkzZ8p55/ve7/sEXdd1ePDgwYMHDx48DGCIfd0BDx48ePDgwYOHfMMjPB48ePDgwYOHAQ+P8Hjw4MGDBw8eBjw8wuPBgwcPHjx4GPDwCI8HDx48ePDgYcDDIzwePHjw4MGDhwEPj/B48ODBgwcPHgY8PMLjwYMHDx48eBjw8AiPh4zg5an04MGDBw97IjzC4yFtvP322/jNb36Tk7ZefPFFTJ48GTU1NXndx8O3C4888ggOOOAAzJw5E4sXL3bcZvLkycy/adOmYd9998UFF1yAd999N+fbT548GTNnzsRxxx2H+++/H5qm2fZZt24dfvvb3+KII47AzJkzMX/+fJx77rn497//ndZ533HHHZg/fz5mzZqFl19+Oa190sXy5ctt5zNlyhTMmTMHP/zhD/HOO+/k9Hjp9GX58uV53aev8cc//hFnn312X3djwEHu6w542HPwyCOP5KytQw89FM888wyGDBmS1308fHvQ2dmJ2267DYceeiguuOACjBgxwnXb73//+/jBD34AAIjH42hoaMALL7yAn/70p7jmmmtwzjnn5Gx7AAiHw3jzzTdx5513or29HQsXLjTXPfLII7j99tsxd+5cXHLJJRgxYgTa2trw5ptv4oorrsDatWtx7bXXup7L119/jQceeACnnXYaTjrpJIwbNy79QcsA1113HaZPnw7AsPS2tbXhoYcews9+9jPcd999OOSQQ/Jy3G8bHnroITz88MOYP39+X3dlwMEjPB76BBUVFaioqMj7Ph6+PWhra4OmaTjyyCMxb968pNtWV1dj1qxZzLJjjz0Wv/jFL3D77bfj8MMPZwhTLrZfsGABNm/ejCeffBKXXnopfD4fli9fjj/+8Y8466yzbKTmyCOPxJQpU3Dbbbfh+OOPt7VH0NraCgA47rjjMHfu3KTn3RNMmDDB1oe5c+fi0EMPxWOPPeYRnh5ix44duO222/DOO++guLi4r7szIOG5tDykhbPPPhsrVqzAihUrTPMwMRU//fTTOOywwzBnzhx89NFHAIDnnnsOp556KmbNmoWZM2fipJNOwuuvv262x7unrrrqKpx33nl44YUXcPTRR2PGjBk46aST8L///a9H+wDAmjVrcOaZZ2LWrFk49NBD8eijj+K8887DVVddlfSc165diwsuuABz5szBfvvth8svvxx1dXWOfSE4/PDDmXYnT56Me+65B6eeeipmzpyJe+65B1OnTsUTTzzB7Nfc3Izp06ebVjRN0/CPf/wD3/nOdzBjxgwcffTRePzxx1Nep46ODtx666048sgjsddee+H444/H888/b+vjokWLcNttt2H//ffHzJkzceGFF2Lr1q1J247FYrjrrrtMt8vxxx+Pl156yVx/9tln46qrrsK9996L/fffH/vssw9+9rOfYefOneY2V111FQ4//HCm3ZqaGkyePBkvvvhi0uN/9NFHOOOMM7DPPvtg3333xcKFC7F7924AxvUg7V599dWYPHlyyrFywmWXXYZ4PG4bs1xtP2PGDHR1daGtrQ0A8Le//Q1Dhw7Fr3/9a8ftzznnHBxxxBEIh8OO6++++27T9XHuueeaY6CqKp588kmccMIJmDlzJg499FDceeediEaj5r5XXXUVzj33XFx//fWYM2cOjj32WKiqmtZ5EBQVFWHs2LHYtWuXuay1tRXXXXcd9t9/f+y111447bTTsHTpUma/yZMn48knn8Q111yD+fPnY/bs2fjlL3+JxsZGZrunn34aRx99NGbOnImzzjqLOQ45f6drPXnyZNx9992OfU7nHiTvtqVLl+Lss882x/C5555DfX09LrnkEsyePRuHHHJISsv3vffeixkzZpjXnOCRRx7B9OnT0dTUBAC49dZbsW3bNjz66KOYOnVq0jY9ZAeP8HhIC9dffz2mTZuGadOm4ZlnnjFN2wBwzz334De/+Q2uu+46zJ49G08++SSuu+46HHnkkbjvvvtw5513wu/344orrkBtba3rMdavX48HH3wQl156Kf72t79BkiT84he/sL0oMtln06ZNOO+88wAAf/7zn/GLX/wC//jHP7B69eqk57thwwacddZZiEajuP3223HjjTdi/fr1uPDCC6EoSgYjZ7zwTjjhBCxatAhHH3005s+fjyVLljDbvPHGG9B1HccddxwA4IYbbsCiRYtw4okn4t5778UxxxyDP/zhD/jb3/7mepxIJIIzzjgD//rXv3DRRRdh8eLF2GeffXDNNdfg3nvvZbZ97LHHsHnzZtx66624+eabsX79+pT6rCuuuAIPP/wwfvCDH+C+++7DgQceiKuuuorRmbz99tt48cUXce211+LGG2/EF198gbPPPtt1wk4XL7/8Mi644AIMHToUf/7zn/Hb3/4Wa9aswemnn46mpiYceuihuOeeewAA//d//4dnnnkmq+OMGzcOw4YNS3l/ZLv9li1bUFhYiMrKSrS1tWHlypU44ogjEAgEHLeXZRmLFy/GggULHNf/4Ac/wHXXXQfAcDmRMbjuuutM4vv3v/8dZ555Jp544gn87Gc/YwIPVq1ahd27d+Nvf/sbFi5cCEmS0joPglgshpqaGowaNQoAEI1Gce655+Ltt9/GZZddhnvuuQfV1dW46KKLbKTnL3/5CzRNw5///GdceeWVePfdd/GHP/zBXP/EE0/g+uuvxyGHHILFixdj7733xu9+97uM+tdTXH755Tj88MNx3333YezYsbj++utxzjnnYOLEiVi8eDFmzpyJW2+9FevWrXNt44QTToCiKHjzzTeZ5UuWLMGBBx6IyspKAMCvfvUrvPrqqymtkx6yh+fS8pAWJkyYgKKiIgCwmbXPOOMMHHPMMebvHTt24MILL8TPfvYzc9nw4cNx6qmnYvXq1eakzqOjowMvvvii+fIsKCjAWWedhWXLluHoo4/Oap/77rsPxcXFeOCBBxAKhQAYk9QPf/jDpOd77733oqysDA899JA5GQ0ZMgQLFy7EN998k3RfHnPnzsX5559v/j7ppJNw9dVXY9euXRg2bBgA4+W3//77Y/DgwdiyZQueffZZXH755bj44osBAAceeCAEQcB9992HM844A+Xl5bbjvPjii/j666/x9NNPY/bs2QCAgw46CIqiYPHixfjhD3+IsrIyAEBJSQkWL15sTnDbt2/H3XffjZaWFse2v/76a/znP//B1VdfjXPPPReA4aLZuXMnli9fjuOPPx6AoVV58cUXMXLkSADGWJ9yyil4+eWX8aMf/SijcSPQNA133nknDjzwQPzpT38ylxOrxIMPPogrr7zS/CoeNWqUq/sn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Cy5Ae3s7/vrXv0IUxaQ6jZ/97Gc4/fTT8ZOf/ATnnHMOIpEI7rrrLsycORMHHHAAIpEIgsEg/vjHP+KXv/wlurq6sGjRItMakQqSJOG4447DE088gaqqKuy7777musmTJ+PEE0/E7373O+zcuRMzZszAli1b8Je//AUjRozAmDFjHNs89dRT8c9//hM///nPcemll2LEiBF455138MILL+CSSy4xrTTZYMqUKTjmmGNwxx13IBKJYOrUqfjf//6Hd99914wMAozre9FFF+H//u//0NXVhb/85S+YNGmSqb857LDD8Pjjj+Oaa67B97//fXz99dd4+OGHk06Eoiji8ssvx29/+1ssXLgQJ554IlpaWnDPPfegtLSUEYSni9raWqxduxaAIcCtq6vDSy+9hA8//NBRxJvp9unioIMOwu9+9zvceuutWLt2LU455RSMHTsW3d3dWLFiBV544QVEo1FbYsNkmDBhAk455RQsWrQI4XAY8+bNwxdffIF77rkH++67Lw466KCs+poOTj31VDzxxBM4//zz8dOf/hRDhw7Fxx9/jPvvvx9nnXUW49JLBkEQcMUVV2DhwoW49tprccwxx5hkgcYhhxyCW2+9Fddddx0uvPBCM+IsmVUsm3swFzjooINQVlaGZ555xhSue+hdeITHQ9o488wzsX79evz4xz/Grbfe6prxePHixbjllltw1VVXwe/3Y8KECfj73/+OP/zhD1i1alWvpkwfPXo0HnzwQdx+++249NJLUVlZiZ/85Cf4+9//nvSlOG3aNDz++OP405/+hF/96lcoKirCIYccgiuuuAJ+vx9+vx933303/vSnP+HnP/85hg8fjksuuSSjtP4nnXQSHn30URx//PE269mtt96K++67D08//TRqa2tRWVmJY489Fr/61a9cX8yhUMjs81//+ld0dnZi3LhxuOWWW/D9738/7X654Y477sA999yDRx99FC0tLRg/fjwWLVpkao8Awzq133774ZprrgFg5Py58sor4ff7ARjRQr/5zW/w+OOP4z//+Q+mT5+Oe+65J2XU3KmnnorCwkLcd999+PnPf46ioiIcdNBBuPzyy7PSdTz//POmTkYURZSVlWHvvffGww8/7BgCnun2meDMM8/E/Pnz8dRTT+Hhhx9GbW0tJEnC2LFjcdZZZ+H000931EYlwy233ILRo0fj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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAHJCAYAAABws7ggAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC7AklEQVR4nOydd3wb5f3H36ctD3lvO8tJHLI3hIQQdliBphQokAYKpS0jbeBXAoWywk6AAmGPAmE07BbChrKzEwgh286wHe8lD1nzfn9IJ9uxHS9tPe/Xyy/b0o3n0Z3uPvedkizLMgKBQCAQCARhiirYAxAIBAKBQCAYCELMCAQCgUAgCGuEmBEIBAKBQBDWCDEjEAgEAoEgrBFiRiAQCAQCQVgjxIxAIBAIBIKwRogZgUAgEAgEYY0QMwKBQCAQCMIaIWYEXeKvWoqiRqNAIBAIfI0QM4JOfPHFFyxZssTn2920aRNXXnml9/+SkhIKCgp45513fL4vQWSwdu1aTjvtNMaOHcsVV1zR5TILFiygoKDA+zNq1CgmTZrE/Pnzefnll3E4HD5dvqCggLFjxzJnzhzuuOMOGhoaOo2pvLyc5cuXc9ZZZzFp0iQmTZrEr371K5555hksFkuP8169ejUnnHACY8eO5dZbb+3DJ9Y7Dp9PQUEB48eP58wzz+TZZ5/F5XL5fJ9HGstjjz3m93WCyZdffklBQUGwhxHRaII9AEHo8eKLL/plu2+++SaFhYXe/9PT01m1ahWDBg3yy/4E4c8DDzyAy+XimWeeISUlpdvlRo8ezW233QaA0+mkoaGBb775hnvvvZeNGzfyz3/+E5VK5ZPlAex2O7/88gsPPfQQO3bs4PXXX0eSJADWrVvHokWLSEhI4KKLLqKgoACXy8W6det48skn+fTTT3n11VfR6/XdzufOO+9kyJAh3HfffWRkZPTvw+uB8847j9/85jfe/y0WC59++inLly/HbDZz/fXX+2W/0ca6devEZxkAhJgRBA2dTsfEiRODPQxBCFNfX8+0adM49thjj7hcXFxcp3PpxBNPZNiwYdx999188MEHzJs3z6fLT5s2jebmZh599FF++uknJk6cSG1tLYsXL2bIkCH861//IiYmxrv8zJkzOemkk/jtb3/LSy+91MFK2dW8Z86cydFHH33EeQ+EzMzMTnOaMWMGRUVFvPrqqyxatAitVuu3/Uc6TU1NPPvsszz77LPEx8fT0tIS7CFFNMLNJOjAggULWL9+PevXr6egoIB169YB7ovrrbfeyrHHHsu4ceM4//zzWbNmTYd1v//+e84//3wmTZrEtGnT+POf/+y1xNx44428++67lJaWel1Lh7uZ3nnnHUaPHs1PP/3EBRdcwLhx4zjhhBN4/vnnO+ynsrKSxYsXM336dKZNm8att97Kww8/zIknnnjEuVVWVrJkyRJmzJjBpEmTuOSSS9iyZQvQvcvrxhtv7LDdBQsW8H//938sWrSIiRMnctlll3HaaaexaNGiTvs755xz+POf/+z9//PPP2f+/PmMGzeOmTNnctddd/V4gXM6nbz66qucffbZjB8/njlz5rB8+XKsVmuHMV566aW8/fbbXpfMOeecwzfffHPEbQO89957/OpXv2LChAnMmTOHBx98EJvNBsBjjz3GiSeeyP/+9z/mzp3LhAkTOP/8873nBLiPWUFBASUlJR22e+KJJ3LjjTcecd/79+9n0aJFzJw5k4kTJ7JgwQI2bdoEtB2P0tJS3nvvvQ7nYl+45JJLyMjI4N///rdflh87diwAhw4dAuC1116jpqaGu+66q4OQUZgwYQILFy7s8j1wP8Ur7ojHH3+8w2f7/fffc9FFFzFlyhSOPvporr/+esrKyrzrKt+fN998k5kzZzJ9+nT27t3bq3kcPqfm5mav+0yxjJ1yyimMHTuW0047jZUrV3ZYZ8GCBdx8880888wzzJkzh3HjxnHhhReydevWDsutX7+eCy64gAkTJnDaaafxww8/dDn/w4/1ggULWLBgQZfj7e05WFBQwOuvv86NN97IlClTmD59OnfddRetra3cf//9HHPMMRx99NHcfPPNHb5fh7N582YKCgr43//+1+H1HTt2UFBQwGeffQbAW2+9xRtvvMGtt97KJZdc0u32BL5BiBlBB2677TZGjx7N6NGjWbVqFWPGjMFqtbJw4UK++OILFi9ezIoVK8jMzOSKK67wCpri4mKuuuoqxo4dy5NPPsndd9/Nvn37uPLKK3G5XFx11VUcf/zxpKWlsWrVKubMmdPl/l0uF3/9618544wzeOaZZ5g8eTIPPPAA3377LQA2m42FCxeyefNm/v73v3Pvvfeyc+dOXnjhhSPOq7m5md/+9resW7eOv/3tb6xYsQK9Xs/vf/979u/f36fP6KOPPiI2NpYnn3ySK664gnnz5vH111/T1NTkXaawsJCdO3dyzjnnAPD+++9z9dVXM2zYMB5//HGuueYa/vvf/3LVVVcdMSj61ltv5d577+Xkk0/mySef5OKLL+aVV17ptN62bdt4/vnnWbRoEY8//jhqtZprr722y3gOhVdffZUlS5YwZswYVqxYwZVXXsnKlSu56667vMvU1tayZMkSLrroIh555BEMBgOXX345O3bs6NNndjh79+5l/vz5lJSUcMstt7B8+XIkSWLhwoWsX7/e64JMS0vj+OOP956LfUWlUjFjxgy2bt3aKRbGF8vv27cPgLy8PMAdb1ZQUMCIESO6XWfJkiXd3tzGjBnDqlWrALcbaNWqVaSnp/Pee+/x+9//nqysLB566CFuuukmtmzZwgUXXEBNTY13fafTyQsvvMDdd9/NTTfdRH5+fo9z6GpOsbGxXrfe7bffzqOPPsq8efN46qmnmDt3Lvfccw+PP/54h/U++eQTvvjiC2655RYeeughqqurufbaa3E6nQD88ssv/P73vyc+Pp5HH32U3/3ud1x33XV9Ht9AWLZsGTqdjhUrVnDuueeycuVKzj33XMrKyli+fDkLFizgrbfe6iTW2jN58mQGDRrE6tWrO7z+wQcfkJiYyPHHHw+4xdSXX37JhRde6Nc5CdwIN5OgA8OHDycuLg7Aa4J+44032LlzJ2+88QYTJkwAYPbs2SxYsIDly5fz9ttvs3XrVlpbW/njH//o9fFnZmbyxRdf0NLSwqBBg0hOTu7gWurKKiHLMldddZXXlz9lyhQ+++wzvvrqK4477jj++9//UlRUxNtvv+19Kj7mmGM4+eSTjzgvxSr07rvvctRRRwHui9K5557Lhg0bmDFjRq8/I61Wyx133IFOpwNg0KBBPPbYY3z++eece+65gPvCZjKZOPHEE5FlmeXLl3PcccexfPly73aGDBnCpZdeytdff92luNu7dy9vvfUW119/vdclMXPmTNLT07nhhhv45ptvvBfOxsZG3nnnHW/8UUxMDJdccok3gPZwXC4Xjz/+OCeffHIH8WKxWFi9ejV2u937/+233+6dl/JZP/PMMzz88MO9/swOZ8WKFeh0Ol5++WXv+TZnzhzOOussHnjgAd566y0mTpyITqcjOTl5QO7I1NRU7HY79fX1pKam9mt5WZY7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kMovCDzCMiPohMlkYsuWLaxZs4bRo0czf/58XnnlFS677DL+9Kc/kZWVxQ8//MCzzz7LJZdcglar5ZhjjmH58uVcffXVXHLJJajVav7973+j0+m88Swmk4nq6mq+/vrrXvv1D+ess87imWee4eqrr+Yvf/kLJpOJf/3rX9TU1BzxKXH+/PmsXLmSP//5zyxatIikpCRefvll7HY7F110EQkJCUyaNImVK1cyePBgEhISePnll2ltbe212X7evHksWrQIp9PZwXeuVqtZvHgxt956K2q1mhNOOAGz2cwTTzxBRUVFt+674cOH86tf/YpHH30Ui8XCtGnT2LFjBytWrODoo4/muOOO69uH1w4l2+nOO+8kJSWFE088kX379vHoo49y8cUXd7AW3XTTTfz1r38lJSWF559/npaWFm/K+dFHH43BYOC+++7jL3/5i7fuSk8unWuuuYZvvvmG3/3ud1x55ZVotVpeeeUViouLee655/o8n6amJn788UfA/YReV1fHd999x6pVq5g3bx6nnnrqgJbvLRkZGaxYsYK//OUvzJs3jwsuuIAxY8agUqnYtm0bb7/9Nvv37+/TjU+lUnHddddx0003cf311zNv3jzq6upYsWIFCQkJXHbZZf0aa28oKChg3rx5/OMf/6C0tJSxY8eyb98+Hn74YXJzcxkyZEivt3X11Vfz+eefc/nll3PFFVdQW1vLP//5zw5urYKCArKysnj88ceJi4vzBhof7sJqT3/PwYGiZC699tprTJo0icGDB/t1f4IjI8SMoBMXX3wx27Zt4w9/+AP33nsvZ599Nq+++ioPPvggy5Yto7GxkZycHK6//np+//vfAzBq1CieeuopHn/8ca677jqcTidjx47lhRdeYNiwYYBbUHz99ddcffXVLFq0iDPOOKPPY9NoNDz//PPcfffd3H777Wg0GubNm0diYqI3TbYr4uLieOWVV3jggQdYunQpLpeLiRMn8vLLL3vdAffddx9Lly7llltuIS4ujvPOO48pU6bw5ptv9mpsxx9/PPHx8eTl5TF06NAO7/3mN78hNjaW5557jlWrVhETE8PkyZNZvnx5B3fE4dx9990MHjyYt99+m2effZb09HR+97vfcdVVVw3Y0nXxxRcTExPD888/z6pVq8jMzOQPf/gDf/jDHzosd/vtt3PPPfdQW1vL5MmTef31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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 获取参数\n", + "cfg = get_args() \n", + "# 训练\n", + "env, agent = env_agent_config(cfg)\n", + "res_dic = train(cfg, env, agent)\n", + " \n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"train\") \n", + "# 测试\n", + "res_dic = test(cfg, env, agent)\n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"test\") # 画出结果" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('easyrl')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "8994a120d39b6e6a2ecc94b4007f5314b68aa69fc88a7f00edf21be39b41f49c" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/projects/notebooks/PolicyGradient.ipynb b/projects/notebooks/PolicyGradient.ipynb new file mode 100644 index 0000000..b6326da --- /dev/null +++ b/projects/notebooks/PolicyGradient.ipynb @@ -0,0 +1,202 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. 定义算法\n", + "\n", + "最基础的策略梯度算法就是REINFORCE算法,又称作Monte-Carlo Policy Gradient算法。我们策略优化的目标如下:\n", + "\n", + "$$\n", + "J_{\\theta}= \\Psi_{\\pi} \\nabla_\\theta \\log \\pi_\\theta\\left(a_t \\mid s_t\\right)\n", + "$$\n", + "\n", + "其中$\\Psi_{\\pi}$在REINFORCE算法中表示衰减的回报(具体公式见伪代码),也可以用优势来估计,也就是我们熟知的A3C算法,这个在后面包括GAE算法中都会讲到。\n", + "\n", + "### 1.1. 策略函数设计\n", + "\n", + "既然策略梯度是直接对策略函数进行梯度计算,那么策略函数如何设计呢?一般来讲有两种设计方式,一个是softmax函数,另外一个是高斯分布$\\mathbb{N}\\left(\\phi(\\mathbb{s})^{\\mathbb{\\pi}} \\theta, \\sigma^2\\right)$,前者用于离散动作空间,后者多用于连续动作空间。\n", + "\n", + "softmax函数可以表示为:\n", + "$$\n", + "\\pi_\\theta(s, a)=\\frac{e^{\\phi(s, a)^{T_\\theta}}}{\\sum_b e^{\\phi(s, b)^{T^T}}}\n", + "$$\n", + "对应的梯度为:\n", + "$$\n", + "\\nabla_\\theta \\log \\pi_\\theta(s, a)=\\phi(s, a)-\\mathbb{E}_{\\pi_\\theta}[\\phi(s,)\n", + "$$\n", + "高斯分布对应的梯度为:\n", + "$$\n", + "\\nabla_\\theta \\log \\pi_\\theta(s, a)=\\frac{\\left(a-\\phi(s)^T \\theta\\right) \\phi(s)}{\\sigma^2}\n", + "$$\n", + "但是对于一些特殊的情况,例如在本次演示中动作维度=2且为离散空间,这个时候可以用伯努利分布来实现,这种方式其实是不推荐的,这里给大家做演示也是为了展现一些特殊情况,启发大家一些思考,例如Bernoulli,Binomial,Gaussian分布之间的关系。简单说来,Binomial分布,$n = 1$时就是Bernoulli分布,$n \\rightarrow \\infty$时就是Gaussian分布。\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.2. 模型设计\n", + "\n", + "前面讲到,尽管本次演示是离散空间,但是由于动作维度等于2,此时就可以用特殊的高斯分布来表示策略函数,即伯努利分布。伯努利的分布实际上是用一个概率作为输入,然后从中采样动作,伯努利采样出来的动作只可能是0或1,就像投掷出硬币的正反面。在这种情况下,我们的策略模型就需要在MLP的基础上,将状态作为输入,将动作作为倒数第二层输出,并在最后一层增加激活函数来输出对应动作的概率。不清楚激活函数作用的同学可以再看一遍深度学习相关的知识,简单来说其作用就是增加神经网络的非线性。既然需要输出对应动作的概率,那么输出的值需要处于0-1之间,此时sigmoid函数刚好满足我们的需求,实现代码参考如下。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "class PGNet(nn.Module):\n", + " def __init__(self, input_dim,output_dim,hidden_dim=128):\n", + " \"\"\" 初始化q网络,为全连接网络\n", + " input_dim: 输入的特征数即环境的状态维度\n", + " output_dim: 输出的动作维度\n", + " \"\"\"\n", + " super(PGNet, self).__init__()\n", + " self.fc1 = nn.Linear(input_dim, hidden_dim) # 输入层\n", + " self.fc2 = nn.Linear(hidden_dim,hidden_dim) # 隐藏层\n", + " self.fc3 = nn.Linear(hidden_dim, output_dim) # 输出层\n", + " def forward(self, x):\n", + " x = F.relu(self.fc1(x))\n", + " x = F.relu(self.fc2(x))\n", + " x = torch.sigmoid(self.fc3(x))\n", + " return x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.3. 更新函数设计\n", + "\n", + "前面提到我们的优化目标也就是策略梯度算法的损失函数如下:\n", + "$$\n", + "J_{\\theta}= \\Psi_{\\pi} \\nabla_\\theta \\log \\pi_\\theta\\left(a_t \\mid s_t\\right)\n", + "$$\n", + "\n", + "我们需要拆开成两个部分$\\Psi_{\\pi}$和$\\nabla_\\theta \\log \\pi_\\theta\\left(a_t \\mid s_t\\right)$分开计算,首先看值函数部分$\\Psi_{\\pi}$,在REINFORCE算法中值函数是从当前时刻开始的衰减回报,如下:\n", + "$$\n", + "G \\leftarrow \\sum_{k=t+1}^{T} \\gamma^{k-1} r_{k}\n", + "$$\n", + "\n", + "这个实际用代码来实现的时候可能有点绕,我们可以倒过来看,在同一回合下,我们的终止时刻是$T$,那么对应的回报$G_T=\\gamma^{T-1}r_T$,而对应的$G_{T-1}=\\gamma^{T-2}r_{T-1}+\\gamma^{T-1}r_T$,在这里代码中我们使用了一个动态规划的技巧,如下:\n", + "```python\n", + "running_add = running_add * self.gamma + reward_pool[i] # running_add初始值为0\n", + "```\n", + "这个公式也是倒过来循环的,第一次的值等于:\n", + "$$\n", + "running\\_add = r_T\n", + "$$\n", + "第二次的值则等于:\n", + "$$\n", + "running\\_add = r_T*\\gamma+r_{T-1}\n", + "$$\n", + "第三次的值等于:\n", + "$$\n", + "running\\_add = (r_T*\\gamma+r_{T-1})*\\gamma+r_{T-2} = r_T*\\gamma^2+r_{T-1}*\\gamma+r_{T-2}\n", + "$$\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "from torch.distributions import Bernoulli\n", + "from torch.autograd import Variable\n", + "import numpy as np\n", + "\n", + "class PolicyGradient:\n", + " \n", + " def __init__(self, model,memory,cfg):\n", + " self.gamma = cfg['gamma']\n", + " self.device = torch.device(cfg['device']) \n", + " self.memory = memory\n", + " self.policy_net = model.to(self.device)\n", + " self.optimizer = torch.optim.RMSprop(self.policy_net.parameters(), lr=cfg['lr'])\n", + "\n", + " def sample_action(self,state):\n", + "\n", + " state = torch.from_numpy(state).float()\n", + " state = Variable(state)\n", + " probs = self.policy_net(state)\n", + " m = Bernoulli(probs) # 伯努利分布\n", + " action = m.sample()\n", + " \n", + " action = action.data.numpy().astype(int)[0] # 转为标量\n", + " return action\n", + " def predict_action(self,state):\n", + "\n", + " state = torch.from_numpy(state).float()\n", + " state = Variable(state)\n", + " probs = self.policy_net(state)\n", + " m = Bernoulli(probs) # 伯努利分布\n", + " action = m.sample()\n", + " action = action.data.numpy().astype(int)[0] # 转为标量\n", + " return action\n", + " \n", + " def update(self):\n", + " state_pool,action_pool,reward_pool= self.memory.sample()\n", + " state_pool,action_pool,reward_pool = list(state_pool),list(action_pool),list(reward_pool)\n", + " # Discount reward\n", + " running_add = 0\n", + " for i in reversed(range(len(reward_pool))):\n", + " if reward_pool[i] == 0:\n", + " running_add = 0\n", + " else:\n", + " running_add = running_add * self.gamma + reward_pool[i]\n", + " reward_pool[i] = running_add\n", + "\n", + " # Normalize reward\n", + " reward_mean = np.mean(reward_pool)\n", + " reward_std = np.std(reward_pool)\n", + " for i in range(len(reward_pool)):\n", + " reward_pool[i] = (reward_pool[i] - reward_mean) / reward_std\n", + "\n", + " # Gradient Desent\n", + " self.optimizer.zero_grad()\n", + "\n", + " for i in range(len(reward_pool)):\n", + " state = state_pool[i]\n", + " action = Variable(torch.FloatTensor([action_pool[i]]))\n", + " reward = reward_pool[i]\n", + " state = Variable(torch.from_numpy(state).float())\n", + " probs = self.policy_net(state)\n", + " m = Bernoulli(probs)\n", + " loss = -m.log_prob(action) * reward # Negtive score function x reward\n", + " # print(loss)\n", + " loss.backward()\n", + " self.optimizer.step()\n", + " self.memory.clear()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('easyrl')", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "8994a120d39b6e6a2ecc94b4007f5314b68aa69fc88a7f00edf21be39b41f49c" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/projects/notebooks/figs/dqn_pseu.png b/projects/notebooks/figs/dqn_pseu.png deleted file mode 100644 index 591405b..0000000 Binary files a/projects/notebooks/figs/dqn_pseu.png and /dev/null differ diff --git a/projects/parl_tutorials/DDPG.ipynb b/projects/parl_tutorials/DDPG.ipynb new file mode 100644 index 0000000..a0db09f --- /dev/null +++ b/projects/parl_tutorials/DDPG.ipynb @@ -0,0 +1,465 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. 定义算法" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m[09-28 00:38:01 MainThread @utils.py:73]\u001b[0m paddlepaddle version: 2.3.2.\n" + ] + } + ], + "source": [ + "import parl\n", + "import paddle\n", + "import paddle.nn as nn\n", + "import paddle.nn.functional as F\n", + "class Actor(parl.Model):\n", + " def __init__(self, n_states, n_actions):\n", + " super(Actor, self).__init__()\n", + "\n", + " self.l1 = nn.Linear(n_states, 400)\n", + " self.l2 = nn.Linear(400, 300)\n", + " self.l3 = nn.Linear(300, n_actions)\n", + "\n", + " def forward(self, state):\n", + " x = F.relu(self.l1(state))\n", + " x = F.relu(self.l2(x))\n", + " return paddle.tanh(self.l3(x))\n", + "\n", + "class Critic(parl.Model):\n", + " def __init__(self, n_states, n_actions):\n", + " super(Critic, self).__init__()\n", + "\n", + " self.l1 = nn.Linear(n_states, 400)\n", + " self.l2 = nn.Linear(400 + n_actions, 300)\n", + " self.l3 = nn.Linear(300, 1)\n", + "\n", + " def forward(self, state, action):\n", + " x = F.relu(self.l1(state))\n", + " x = F.relu(self.l2(paddle.concat([x, action], 1)))\n", + " return self.l3(x)\n", + "class ActorCritic(parl.Model):\n", + " def __init__(self, n_states, n_actions):\n", + " super(ActorCritic, self).__init__()\n", + " self.actor_model = Actor(n_states, n_actions)\n", + " self.critic_model = Critic(n_states, n_actions)\n", + "\n", + " def policy(self, state):\n", + " return self.actor_model(state)\n", + "\n", + " def value(self, state, action):\n", + " return self.critic_model(state, action)\n", + "\n", + " def get_actor_params(self):\n", + " return self.actor_model.parameters()\n", + "\n", + " def get_critic_params(self):\n", + " return self.critic_model.parameters()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import deque\n", + "import random\n", + "class ReplayBuffer:\n", + " def __init__(self, capacity: int) -> None:\n", + " self.capacity = capacity\n", + " self.buffer = deque(maxlen=self.capacity)\n", + " def push(self,transitions):\n", + " '''_summary_\n", + " Args:\n", + " trainsitions (tuple): _description_\n", + " '''\n", + " self.buffer.append(transitions)\n", + " def sample(self, batch_size: int, sequential: bool = False):\n", + " if batch_size > len(self.buffer):\n", + " batch_size = len(self.buffer)\n", + " if sequential: # sequential sampling\n", + " rand = random.randint(0, len(self.buffer) - batch_size)\n", + " batch = [self.buffer[i] for i in range(rand, rand + batch_size)]\n", + " return zip(*batch)\n", + " else:\n", + " batch = random.sample(self.buffer, batch_size)\n", + " return zip(*batch)\n", + " def clear(self):\n", + " self.buffer.clear()\n", + " def __len__(self):\n", + " return len(self.buffer)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import parl\n", + "import paddle\n", + "import numpy as np\n", + "\n", + "\n", + "class DDPGAgent(parl.Agent):\n", + " def __init__(self, algorithm,memory,cfg):\n", + " super(DDPGAgent, self).__init__(algorithm)\n", + " self.n_actions = cfg['n_actions']\n", + " self.expl_noise = cfg['expl_noise']\n", + " self.batch_size = cfg['batch_size'] \n", + " self.memory = memory\n", + " self.alg.sync_target(decay=0)\n", + "\n", + " def sample_action(self, state):\n", + " action_numpy = self.predict_action(state)\n", + " action_noise = np.random.normal(0, self.expl_noise, size=self.n_actions)\n", + " action = (action_numpy + action_noise).clip(-1, 1)\n", + " return action\n", + "\n", + " def predict_action(self, state):\n", + " state = paddle.to_tensor(state.reshape(1, -1), dtype='float32')\n", + " action = self.alg.predict(state)\n", + " action_numpy = action.cpu().numpy()[0]\n", + " return action_numpy\n", + "\n", + " def update(self):\n", + " if len(self.memory) < self.batch_size: \n", + " return\n", + " state_batch, action_batch, reward_batch, next_state_batch, done_batch = self.memory.sample(\n", + " self.batch_size)\n", + " done_batch = np.expand_dims(done_batch , -1)\n", + " reward_batch = np.expand_dims(reward_batch, -1)\n", + " state_batch = paddle.to_tensor(state_batch, dtype='float32')\n", + " action_batch = paddle.to_tensor(action_batch, dtype='float32')\n", + " reward_batch = paddle.to_tensor(reward_batch, dtype='float32')\n", + " next_state_batch = paddle.to_tensor(next_state_batch, dtype='float32')\n", + " done_batch = paddle.to_tensor(done_batch, dtype='float32')\n", + " critic_loss, actor_loss = self.alg.learn(state_batch, action_batch, reward_batch, next_state_batch,\n", + " done_batch)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def train(cfg, env, agent):\n", + " ''' 训练\n", + " '''\n", + " print(f\"开始训练!\")\n", + " rewards = [] # 记录所有回合的奖励\n", + " for i_ep in range(cfg[\"train_eps\"]):\n", + " ep_reward = 0 \n", + " state = env.reset() \n", + " for i_step in range(cfg['max_steps']):\n", + " action = agent.sample_action(state) # 采样动作\n", + " next_state, reward, done, _ = env.step(action) \n", + " agent.memory.push((state, action, reward,next_state, done)) \n", + " state = next_state \n", + " agent.update() \n", + " ep_reward += reward \n", + " if done:\n", + " break\n", + " rewards.append(ep_reward)\n", + " if (i_ep + 1) % 10 == 0:\n", + " print(f\"回合:{i_ep+1}/{cfg['train_eps']},奖励:{ep_reward:.2f}\")\n", + " print(\"完成训练!\")\n", + " env.close()\n", + " res_dic = {'episodes':range(len(rewards)),'rewards':rewards}\n", + " return res_dic\n", + "\n", + "def test(cfg, env, agent):\n", + " print(\"开始测试!\")\n", + " rewards = [] # 记录所有回合的奖励\n", + " for i_ep in range(cfg['test_eps']):\n", + " ep_reward = 0 \n", + " state = env.reset() \n", + " for i_step in range(cfg['max_steps']):\n", + " action = agent.predict_action(state) \n", + " next_state, reward, done, _ = env.step(action) \n", + " state = next_state \n", + " ep_reward += reward \n", + " if done:\n", + " break\n", + " rewards.append(ep_reward)\n", + " print(f\"回合:{i_ep+1}/{cfg['test_eps']},奖励:{ep_reward:.2f}\")\n", + " print(\"完成测试!\")\n", + " env.close()\n", + " return {'episodes':range(len(rewards)),'rewards':rewards}\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "import os\n", + "import paddle\n", + "import numpy as np\n", + "import random\n", + "from parl.algorithms import DDPG\n", + "class NormalizedActions(gym.ActionWrapper):\n", + " ''' 将action范围重定在[0.1]之间\n", + " '''\n", + " def action(self, action):\n", + " low_bound = self.action_space.low\n", + " upper_bound = self.action_space.high\n", + " action = low_bound + (action + 1.0) * 0.5 * (upper_bound - low_bound)\n", + " action = np.clip(action, low_bound, upper_bound)\n", + " return action\n", + "\n", + " def reverse_action(self, action):\n", + " low_bound = self.action_space.low\n", + " upper_bound = self.action_space.high\n", + " action = 2 * (action - low_bound) / (upper_bound - low_bound) - 1\n", + " action = np.clip(action, low_bound, upper_bound)\n", + " return action\n", + "def all_seed(env,seed = 1):\n", + " ''' 万能的seed函数\n", + " '''\n", + " env.seed(seed) # env config\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " paddle.seed(seed)\n", + "def env_agent_config(cfg):\n", + " env = NormalizedActions(gym.make(cfg['env_name'])) # 装饰action噪声\n", + " if cfg['seed'] !=0:\n", + " all_seed(env,seed=cfg['seed'])\n", + " n_states = env.observation_space.shape[0]\n", + " n_actions = env.action_space.shape[0]\n", + " print(f\"状态维度:{n_states},动作维度:{n_actions}\")\n", + " cfg.update({\"n_states\":n_states,\"n_actions\":n_actions}) # 更新n_states和n_actions到cfg参数中\n", + " memory = ReplayBuffer(cfg['memory_capacity'])\n", + " model = ActorCritic(n_states, n_actions)\n", + " algorithm = DDPG(model, gamma=cfg['gamma'], tau=cfg['tau'], actor_lr=cfg['actor_lr'], critic_lr=cfg['critic_lr'])\n", + " agent = DDPGAgent(algorithm,memory,cfg)\n", + " return env,agent" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import argparse\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "def get_args():\n", + " \"\"\" 超参数\n", + " \"\"\"\n", + " parser = argparse.ArgumentParser(description=\"hyperparameters\") \n", + " parser.add_argument('--algo_name',default='DDPG',type=str,help=\"name of algorithm\")\n", + " parser.add_argument('--env_name',default='Pendulum-v0',type=str,help=\"name of environment\")\n", + " parser.add_argument('--train_eps',default=200,type=int,help=\"episodes of training\")\n", + " parser.add_argument('--test_eps',default=20,type=int,help=\"episodes of testing\")\n", + " parser.add_argument('--max_steps',default=100000,type=int,help=\"steps per episode, much larger value can simulate infinite steps\")\n", + " parser.add_argument('--gamma',default=0.99,type=float,help=\"discounted factor\")\n", + " parser.add_argument('--critic_lr',default=1e-3,type=float,help=\"learning rate of critic\")\n", + " parser.add_argument('--actor_lr',default=1e-4,type=float,help=\"learning rate of actor\")\n", + " parser.add_argument('--memory_capacity',default=80000,type=int,help=\"memory capacity\")\n", + " parser.add_argument('--expl_noise',default=0.1,type=float)\n", + " parser.add_argument('--batch_size',default=128,type=int)\n", + " parser.add_argument('--target_update',default=2,type=int)\n", + " parser.add_argument('--tau',default=1e-2,type=float)\n", + " parser.add_argument('--critic_hidden_dim',default=256,type=int)\n", + " parser.add_argument('--actor_hidden_dim',default=256,type=int)\n", + " parser.add_argument('--device',default='cpu',type=str,help=\"cpu or cuda\") \n", + " parser.add_argument('--seed',default=1,type=int,help=\"random seed\")\n", + " args = parser.parse_args([]) \n", + " args = {**vars(args)} # 将args转换为字典 \n", + " # 打印参数\n", + " print(\"训练参数如下:\")\n", + " print(''.join(['=']*80))\n", + " tplt = \"{:^20}\\t{:^20}\\t{:^20}\"\n", + " print(tplt.format(\"参数名\",\"参数值\",\"参数类型\"))\n", + " for k,v in args.items():\n", + " print(tplt.format(k,v,str(type(v)))) \n", + " print(''.join(['=']*80)) \n", + " return args\n", + "def smooth(data, weight=0.9): \n", + " '''用于平滑曲线,类似于Tensorboard中的smooth\n", + "\n", + " Args:\n", + " data (List):输入数据\n", + " weight (Float): 平滑权重,处于0-1之间,数值越高说明越平滑,一般取0.9\n", + "\n", + " Returns:\n", + " smoothed (List): 平滑后的数据\n", + " '''\n", + " last = data[0] # First value in the plot (first timestep)\n", + " smoothed = list()\n", + " for point in data:\n", + " smoothed_val = last * weight + (1 - weight) * point # 计算平滑值\n", + " smoothed.append(smoothed_val) \n", + " last = smoothed_val \n", + " return smoothed\n", + "\n", + "def plot_rewards(rewards,cfg,path=None,tag='train'):\n", + " sns.set()\n", + " plt.figure() # 创建一个图形实例,方便同时多画几个图\n", + " plt.title(f\"{tag}ing curve on {cfg['device']} of {cfg['algo_name']} for {cfg['env_name']}\")\n", + " plt.xlabel('epsiodes')\n", + " plt.plot(rewards, label='rewards')\n", + " plt.plot(smooth(rewards), label='smoothed')\n", + " plt.legend()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "训练参数如下:\n", + "================================================================================\n", + " 参数名 \t 参数值 \t 参数类型 \n", + " algo_name \t DDPG \t \n", + " env_name \t Pendulum-v0 \t \n", + " train_eps \t 200 \t \n", + " test_eps \t 20 \t \n", + " max_steps \t 100000 \t \n", + " gamma \t 0.99 \t \n", + " critic_lr \t 0.001 \t \n", + " actor_lr \t 0.0001 \t \n", + " memory_capacity \t 80000 \t \n", + " expl_noise \t 0.1 \t \n", + " batch_size \t 128 \t \n", + " target_update \t 2 \t \n", + " tau \t 0.01 \t \n", + " critic_hidden_dim \t 256 \t \n", + " actor_hidden_dim \t 256 \t \n", + " device \t cpu \t \n", + " seed \t 1 \t \n", + "================================================================================\n", + "状态维度:3,动作维度:1\n", + "开始训练!\n", + "回合:10/200,奖励:-945.22\n", + "回合:20/200,奖励:-700.56\n", + "回合:30/200,奖励:-128.48\n", + "回合:40/200,奖励:-266.74\n", + "回合:50/200,奖励:-387.26\n", + "回合:60/200,奖励:-133.07\n", + "回合:70/200,奖励:-243.47\n", + "回合:80/200,奖励:-383.76\n", + "回合:90/200,奖励:-130.47\n", + "回合:100/200,奖励:-385.78\n", + "回合:110/200,奖励:-128.11\n", + "回合:120/200,奖励:-245.72\n", + "回合:130/200,奖励:-3.26\n", + "回合:140/200,奖励:-231.93\n", + "回合:150/200,奖励:-122.84\n", + "回合:160/200,奖励:-370.19\n", + "回合:170/200,奖励:-126.60\n", + "回合:180/200,奖励:-118.99\n", + "回合:190/200,奖励:-115.58\n", + "回合:200/200,奖励:-246.70\n", + "完成训练!\n", + "开始测试!\n", + "回合:1/20,奖励:-122.76\n", + "回合:2/20,奖励:-1.78\n", + "回合:3/20,奖励:-128.77\n", + "回合:4/20,奖励:-124.03\n", + "回合:5/20,奖励:-125.87\n", + "回合:6/20,奖励:-130.87\n", + "回合:7/20,奖励:-127.97\n", + "回合:8/20,奖励:-134.63\n", + "回合:9/20,奖励:-126.38\n", + "回合:10/20,奖励:-1.42\n", + "回合:11/20,奖励:-126.13\n", + "回合:12/20,奖励:-1.88\n", + "回合:13/20,奖励:-133.22\n", + "回合:14/20,奖励:-132.14\n", + "回合:15/20,奖励:-245.42\n", + "回合:16/20,奖励:-123.41\n", + "回合:17/20,奖励:-127.20\n", + "回合:18/20,奖励:-130.53\n", + "回合:19/20,奖励:-129.29\n", + "回合:20/20,奖励:-288.72\n", + "完成测试!\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjwAAAHJCAYAAACBuOOtAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAADg6klEQVR4nOydd3gcxfnHv1uun069We5N7rhjbGNsDJhqOuRHDxBCaAmYlkBICElIgEACxvSEDgklEHrvGDds3HCvsq1itZOu7W35/bE3e7t7e6eTdGrn+TwPj9HelpnZ3Zl338ooiqKAQqFQKBQKJYthe7oBFAqFQqFQKF0NFXgoFAqFQqFkPVTgoVAoFAqFkvVQgYdCoVAoFErWQwUeCoVCoVAoWQ8VeCgUCoVCoWQ9VOChUCgUCoWS9VCBh0KhUCgUStZDBR5Ku6B5KikUCoXSF6ECDyVtPvnkE9xyyy0ZOdfrr7+OyspKVFVVdekxlEOLp59+GrNmzcKECROwZMkSy30qKysN/40ZMwaHH344Lr30Unz22WcZ37+yshITJkzASSedhCeeeAKyLCccs3btWvz617/G/PnzMWHCBEyfPh0XX3wx3n777bT6fe+992L69OmYOHEi3njjjbSOSZdly5Yl9GfUqFGYPHkyfvKTn+DTTz/N6PXSacuyZcu69JieIBAI4M4778SsWbMwadIk/OxnP8OOHTt6ullZBd/TDaD0HZ5++umMnWvu3Ln497//jZKSki49hnLo0Nrair/+9a+YO3cuLr30UvTv3z/pvmeddRbOPvtsAEA0GkVdXR1ee+01XHnllbjttttw0UUXZWx/AAiFQvjwww9x3333we/3Y9GiRdpvTz/9NO655x5MnToV11xzDfr374/m5mZ8+OGHuPHGG7FmzRrcfvvtSfuyZcsWPPnkkzjnnHNw6qmnYujQoekPWju44447MHbsWACqpre5uRn//Oc/cdVVV+Gxxx7DUUcd1SXXPVRYtGgRfvjhB9x0003wer1YvHgxLrroIrzzzjvIzc3t6eZlBVTgofQIBQUFKCgo6PJjKIcOzc3NkGUZxxxzDKZNm5Zy37KyMkycONGw7cQTT8S1116Le+65B0cffbRBYMrE/kcccQR27NiBF154Addddx1sNhuWLVuGv/zlL7jgggsShJpjjjkGo0aNwl//+lecfPLJCecjNDU1AQBOOukkTJ06NWW/O8Pw4cMT2jB16lTMnTsXzz77LBV4OsHq1avx2Wef4fHHH9fGcerUqZg/fz5efPFF/OIXv+jhFmYH1KRFSYsLL7wQy5cvx/LlyzX1MFEVv/zyy5g3bx4mT56Mb775BgDwyiuv4IwzzsDEiRMxYcIEnHrqqXjvvfe085nNU7feeisuueQSvPbaa1iwYAHGjRuHU089FV9++WWnjgHUyeT888/HxIkTMXfuXDzzzDO45JJLcOutt6bs85o1a3DppZdi8uTJmDFjBm644QbU1NRYtoVw9NFHG85bWVmJxYsX44wzzsCECROwePFijB49Gs8//7zhuIaGBowdO1bTosmyjMcffxzHHnssxo0bhwULFuC5555r8z61tLTg7rvvxjHHHIPx48fj5JNPxquvvprQxgcffBB//etfMXPmTEyYMAGXXXYZdu3alfLcgiDg73//u2Z2Ofnkk/Hf//5X+/3CCy/ErbfeikcffRQzZ87ElClTcNVVV2Hfvn3aPrfeeiuOPvpow3mrqqpQWVmJ119/PeX1v/nmG5x33nmYMmUKDj/8cCxatAgHDhwAoN4Pct7f/OY3qKysbHOsrLj++usRjUYTxixT+48bNw6BQADNzc0AgIcffhjl5eW46aabLPe/6KKLMH/+fIRCIcvfH3roIVx44YUAgIsvvlgbA0mS8MILL+CUU07BhAkTMHfuXNx3332IRCLasbfeeisuvvhi/O53v8PkyZNx4oknQpKktPpB8Hq9GDJkCPbv369ta2pqwh133IGZM2di/PjxOOecc7B06VLDcZWVlXjhhRdw2223Yfr06Zg0aRJ++ctf4uDBg4b9Xn75ZSxYsAATJkzABRdcYLgO6b/Vva6srMRDDz1k2eZ0nkEyty1duhQXXnihNoavvPIKamtrcc0112DSpEk46qij2tR8P/rooxg3bpx2zwlPP/00xo4di/r6enz99ddwu92YPXu29ntBQQGmTZuGL774IuX5KelDBR5KWvzud7/DmDFjMGbMGPz73//WVNsAsHjxYtxyyy244447MGnSJLzwwgu44447cMwxx+Cxxx7DfffdB7vdjhtvvBHV1dVJr7F+/Xo89dRTuO666/Dwww+D4zhce+21CRNFe47Zvn07LrnkEgDA/fffj2uvvRaPP/44Vq1albK/GzduxAUXXIBIJIJ77rkHd955J9avX4/LLrsMoii2Y+TUCe+UU07Bgw8+iAULFmD69Ol45513DPu8//77UBQFJ510EgDg97//PR588EEsXLgQjz76KI4//nj8+c9/xsMPP5z0OuFwGOeddx7eeustXH755ViyZAmmTJmC2267DY8++qhh32effRY7duzA3XffjT/+8Y9Yv359m/5ZN954I/71r3/h7LPPxmOPPYbZs2fj1ltvNfiZfPLJJ3j99ddx++23484778SPP/6ICy+8MOmCnS5vvPEGLr30UpSXl+P+++/Hr3/9a6xevRrnnnsu6uvrMXfuXCxevBgA8Itf/AL//ve/O3SdoUOHol+/fm0+Hx3df+fOnfB4PCgsLERzczNWrFiB+fPnw+FwWO7P8zyWLFmCI444wvL3s88+G3fccQcA1eRExuCOO+7QBN9HHnkE559/Pp5//nlcddVVhsCDlStX4sCBA3j44YexaNEicByXVj8IgiCgqqoKAwcOBABEIhFcfPHF+OSTT3D99ddj8eLFKCsrw+WXX54g9DzwwAOQZRn3338/br75Znz22Wf485//rP3+/PPP43e/+x2OOuooLFmyBIcddhh++9vftqt9neWGG27A0UcfjcceewxDhgzB7373O1x00UUYMWIElixZggkTJuDuu+/G2rVrk57jlFNOgSiK+PDDDw3b33nnHcyePRuFhYXYvn07+vfvnzD+AwcOxM6dO7ukb4ci1KRFSYvhw4fD6/UCQIJa+7zzzsPxxx+v/b13715cdtlluOqqq7RtFRUVOOOMM7Bq1SptUTfT0tKC119/XZs83W43LrjgAnz33XdYsGBBh4557LHHkJOTgyeffBIulwuAukj95Cc/SdnfRx99FHl5efjnP/+pLUYlJSVYtGgRtm7dmvJYM1OnTsVPf/pT7e9TTz0Vv/nNb7B//37069cPgDr5zZw5E8XFxdi5cyf+85//4IYbbsAVV1wBAJg9ezYYhsFjjz2G8847D/n5+QnXef3117Flyxa8/PLLmDRpEgDgyCOPhCiKWLJkCX7yk58gLy8PAODz+bBkyRJtgt2zZw8eeughNDY2Wp57y5Yt+OCDD/Cb3/wGF198MQDVRLNv3z4sW7YMJ598MgDVV+X111/HgAEDAKhjffrpp+ONN97A//3f/7Vr3AiyLOO+++7D7Nmz8be//U3bTrQS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SsyaNSsjbaNQDQ+lHfh8PqxevRpLly7FmDFjLPcpLCxERUUFXnjhBZSVlcHn8+Grr77Cs88+CyC1P05XcOWVV+Ldd9/F5ZdfjksvvRR+vx//+Mc/wLJsStv4VVddhXPPPRc///nPcdFFFyEcDuPvf/87JkyYgFmzZiEcDsPpdOIvf/kLfvnLXyIQCODBBx/UtBFtwXEcTjrpJDz//PMoLS3F4Ycfrv1WWVmJhQsX4re//S327duHcePGYefOnXjggQfQv39/DB482PKcZ5xxBl588UVcffXVuO6669C/f398+umneO2113DNNddoWpqOMGrUKBx//PG49957EQ6HMXr0aHz55Zf47LPPtMggQL2/l19+OX7xi18gEAjggQcewMiRIzX/m3nz5uG5557DbbfdhrPOOgtbtmzBv/71r5QLIcuyuOGGG/DrX/8aixYtwsKFC9HY2IjFixcjNzfX4BCeLtXV1VizZg0A1QG3pqYG//3vf/H1119bOvG2d/90OfLII/Hb3/4Wd999N9asWYPTTz8dQ4YMQTAYxPLly/Haa68hEokkJDZMxfDhw3H66afjwQcfRCgUwrRp0/Djjz9i8eLFOPzww3HkkUd2qK3pcMYZZ+D555/HT3/6U1x55ZUoLy/Ht99+iyeeeAIXXHCBwaSXCoZhcOONN2LRokW4/fbbcfzxx2vCgp6jjjoKd999N+644w5cdtllWsRZKq1YR57BTHDkkUciLy8P//73vzXHdcK0adMwffp03HTTTbjpppuQl5eHhx56CDk5OR129qckQgUeStqcf/75WL9+PX72s5/h7rvvTprxeMmSJfjTn/6EW2+9FXa7HcOHD8cjjzyCP//5z1i5cqWWN6Q7GDRoEJ566incc889uO6661BYWIif//zneOSRR1JOimPGjMFzzz2Hv/3tb/jVr34Fr9eLo446CjfeeCPsdjvsdjseeugh/O1vf8PVV1+NiooKXHPNNe1K63/qqafimWeewcknn5ygPbv77rvx2GOP4eWXX0Z1dTUKCwtx4okn4le/+lXSidnlcmlt/sc//oHW1lYMHToUf/rTn3DWWWel3a5k3HvvvVi8eDGeeeYZNDY2YtiwYXjwwQc13yNA1U7NmDEDt912GwA158/NN98Mu90OQI0WuuWWW/Dcc8/hgw8+wNixY7F48eI2o+bOOOMMeDwe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q7Fk5bNv3z6jRYsWxsaNG/3bPB6Pce211xrPPvuscfToUaNFixbG999/X42lrLi5c+caN9xwQ4n75syZY3Tr1s0oKCjwb3vmmWeMPn36VFXxKt3p06eNa665JuDm+Otf/9p45ZVXqq9QZXTo0CHj7rvvNtq3b2/069cv4EZyoWtWU76n56vjgw8+aNx+++0Bx7/77rtG69at/Tf8CRMmGH/+85+rtMxlcb76eTweo3379sZHH31U4mvD4RqebcmSJUabNm38/5g0DMNYsWKF0bFjx6ooarlc6B7x17/+1bjlllsCXvPAAw8Yf/rTnwzD8H4+LVu2NL744gv//j179hgtWrQwvv7660orp7q0gmD79u2cPn2a9PR0/7a4uDhatWrFhg0bqrFk5ZOQkMDcuXNp27atf5vJZMJkMnHy5El27NiByWSicePG1VjKituxYwdNmzYtcd/GjRvp0qULVqvVv+2KK65g3759HD16tKqKWKnmzJlDXl4eY8aMAcDpdLJv3z6aNGlSzSUrve+//x6bzcby5ctp165dwL4LXbOa8j09Xx3/9Kc/+a+fj9lspqCggJycHOD8f69Dwfnq98MPP5Cbm3vOv5PhcA2LOn78OM8++ywjRowIqHOoX8ML3SM2btwYcI3A+13ctGkThmGwadMm/zafxo0bk5SUVKnX0XrhQ6SsDh06BECDBg0CttevX9+/ryaJi4vj6quvDtj24Ycfsn//fh555BF27txJbGwsEydO5KuvviI6Opp+/fpxzz33YLfbq6nUZbdz504SEhIYNGgQe/fu5dJLL2XEiBH06NGDQ4cO0aJFi4Dj69evD8DPP/9M3bp1q6PI5Xb8+HEWLVrEgw8+SO3atQHYvXs3brebDz/8kCeffBKHw0Hnzp15+OGH/XUNNb169QoYz1HUha5ZTfmenq+OrVq1Cvi9oKCARYsW0aZNGxITEwHYtWsXCQkJDBw4kMzMTFq0aMGoUaNIS0sLetlL43z127lzJwBLlizhyy+/xGw206NHD0aNGkVsbGxYXMOi5s2bR2RkJMOGDQvYvnPnTlwuF8OGDWP79u0kJSUxdOhQbrzxxmAVuUwudI949913SU5ODthfv3598vLyyMrKIjMzk4SEBCIiIoodU5nXUS08QZCXlwdQ7GYfERGBw+GojiJVqq+//ppx48bRp08fevbsyc6d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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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gSPW+/v7U1xcTGdn54h1HR0dzmma2267jeTkZJKTkzl37hz19fVs3ryZzMxM5+jIlby9veno6BixvL29HQBfX198fX3p7OxkYGAAd3d3Z5vLAebK+l977TXsdvuo+4Ghu6kWL17M4sWLOX36NHv27KGsrIwVK1ZQW1t7te4RkZtA00wicl2mTZuGxWKhra0Nm83mfIwbN46NGzfS2toKDN15dOzYMed2bW1tHDp0iKioKACeeeYZ1q1bBwyN2CQmJpKcnMyFCxfo7e0dsd/w8HD27NkzbN3AwAC1tbXYbDY8PDyIioqiv7+fXbt2Odv89ddfw8LR/fffj5+fH62trcPqnzRpEhs2bOCnn36ir6+P+Ph4KisrAZg8eTLJyckkJCRw+vTpG9ibInItNDIjItfF19eX9PR0iouL6e3tJSIigra2NoqLi3Fzc3NOwRhjePnll1m2bBnu7u6Ulpbi7e1NamoqMBROKisr8ff3JywsjLa2NqqqqrDb7UycOHHYbdIAS5YsoaGhgeeee45FixZhsVic17JUVFQAQxf7zpgxg9zcXM6dO8c999xDdXU158+fd44Iubu7s2zZMt544w3c3d2JjY3lwoULlJWV0dbWxtSpUxk/fjxTp06ltLQUi8VCcHAwv/76Kzt37iQ+Pv4m9raIjMbNGGPGuggRcX0fffQRH3/8MSdPnsTb25uoqCiWL1/O5MmTyc7OprGxkYyMDN555x0uXbrEww8/jMPhYMqUKQD09/dTXl5OTU0NZ8+eZcKECcTFxbFixQp8fX1pbW3lkUceYf369SQmJgJDt3tv3LiRgwcP4ubmRkhICEuWLBl2ofGlS5coLCyktraWP//8kzlz5uDp6cnu3bv5+uuvne3q6uqoqKjgl19+wdPTk+nTp5OVlUVwcDAAvb29vP322+zevZv29nb8/PyYM2cOr776KuPHj7+JPS0i/05hRkT+cZfDzJXhQUTkRtE1MyIiIuLSFGZERETEpWmaSURERFyaRmZERETEpSnMiIiIiEtTmBERERGXpjAjIiIiLk1hRkRERFyawoyIiIi4NIUZERERcWkKMyIiIuLS/gVm3uHj07uzGwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 获取参数\n", + "cfg = get_args() \n", + "# 训练\n", + "env, agent = env_agent_config(cfg)\n", + "res_dic = train(cfg, env, agent)\n", + " \n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"train\") \n", + "# 测试\n", + "res_dic = test(cfg, env, agent)\n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"test\") # 画出结果" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('parl')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "29c8e495d55843cb894bac6655c13e4a65f834e86169d4dce1750654c48fe628" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/projects/parl_tutorials/DQN.ipynb b/projects/parl_tutorials/DQN.ipynb new file mode 100644 index 0000000..4b02022 --- /dev/null +++ b/projects/parl_tutorials/DQN.ipynb @@ -0,0 +1,538 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1、定义算法\n", + "相比于Q learning,DQN本质上是为了适应更为复杂的环境,并且经过不断的改良迭代,到了Nature DQN(即Volodymyr Mnih发表的Nature论文)这里才算是基本完善。DQN主要改动的点有三个:\n", + "* 使用深度神经网络替代原来的Q表:这个很容易理解原因\n", + "* 使用了经验回放(Replay Buffer):这个好处有很多,一个是使用一堆历史数据去训练,比之前用一次就扔掉好多了,大大提高样本效率,另外一个是面试常提到的,减少样本之间的相关性,原则上获取经验跟学习阶段是分开的,原来时序的训练数据有可能是不稳定的,打乱之后再学习有助于提高训练的稳定性,跟深度学习中划分训练测试集时打乱样本是一个道理。\n", + "* 使用了两个网络:即策略网络和目标网络,每隔若干步才把每步更新的策略网络参数复制给目标网络,这样做也是为了训练的稳定,避免Q值的估计发散。想象一下,如果当前有个transition(这个Q learning中提过的,一定要记住!!!)样本导致对Q值进行了较差的过估计,如果接下来从经验回放中提取到的样本正好连续几个都这样的,很有可能导致Q值的发散(它的青春小鸟一去不回来了)。再打个比方,我们玩RPG或者闯关类游戏,有些人为了破纪录经常Save和Load,只要我出了错,我不满意我就加载之前的存档,假设不允许加载呢,就像DQN算法一样训练过程中会退不了,这时候是不是搞两个档,一个档每帧都存一下,另外一个档打了不错的结果再存,也就是若干个间隔再存一下,到最后用间隔若干步数再存的档一般都比每帧都存的档好些呢。当然你也可以再搞更多个档,也就是DQN增加多个目标网络,但是对于DQN则没有多大必要,多几个网络效果不见得会好很多。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 定义模型" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m[09-26 17:18:11 MainThread @utils.py:73]\u001b[0m paddlepaddle version: 2.3.2.\n" + ] + } + ], + "source": [ + "\n", + "import paddle\n", + "import paddle.nn as nn\n", + "import paddle.nn.functional as F\n", + "import parl\n", + "\n", + "class MLP(parl.Model):\n", + " \"\"\" Linear network to solve Cartpole problem.\n", + " Args:\n", + " input_dim (int): Dimension of observation space.\n", + " output_dim (int): Dimension of action space.\n", + " \"\"\"\n", + "\n", + " def __init__(self, input_dim, output_dim):\n", + " super(MLP, self).__init__()\n", + " hidden_dim1 = 256\n", + " hidden_dim2 = 256\n", + " self.fc1 = nn.Linear(input_dim, hidden_dim1)\n", + " self.fc2 = nn.Linear(hidden_dim1, hidden_dim2)\n", + " self.fc3 = nn.Linear(hidden_dim2, output_dim)\n", + "\n", + " def forward(self, state):\n", + " x = F.relu(self.fc1(state))\n", + " x = F.relu(self.fc2(x))\n", + " x = self.fc3(x)\n", + " return x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.2 定义经验回放" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import deque\n", + "class ReplayBuffer:\n", + " def __init__(self, capacity: int) -> None:\n", + " self.capacity = capacity\n", + " self.buffer = deque(maxlen=self.capacity)\n", + " def push(self,transitions):\n", + " '''_summary_\n", + " Args:\n", + " trainsitions (tuple): _description_\n", + " '''\n", + " self.buffer.append(transitions)\n", + " def sample(self, batch_size: int, sequential: bool = False):\n", + " if batch_size > len(self.buffer):\n", + " batch_size = len(self.buffer)\n", + " if sequential: # sequential sampling\n", + " rand = random.randint(0, len(self.buffer) - batch_size)\n", + " batch = [self.buffer[i] for i in range(rand, rand + batch_size)]\n", + " return zip(*batch)\n", + " else:\n", + " batch = random.sample(self.buffer, batch_size)\n", + " return zip(*batch)\n", + " def clear(self):\n", + " self.buffer.clear()\n", + " def __len__(self):\n", + " return len(self.buffer)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.3 定义智能体" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from random import random\n", + "import parl\n", + "import paddle\n", + "import math\n", + "import numpy as np\n", + "\n", + "\n", + "class DQNAgent(parl.Agent):\n", + " \"\"\"Agent of DQN.\n", + " \"\"\"\n", + "\n", + " def __init__(self, algorithm, memory,cfg):\n", + " super(DQNAgent, self).__init__(algorithm)\n", + " self.n_actions = cfg['n_actions']\n", + " self.epsilon = cfg['epsilon_start']\n", + " self.sample_count = 0 \n", + " self.epsilon_start = cfg['epsilon_start']\n", + " self.epsilon_end = cfg['epsilon_end']\n", + " self.epsilon_decay = cfg['epsilon_decay']\n", + " self.batch_size = cfg['batch_size']\n", + " self.global_step = 0\n", + " self.update_target_steps = 600\n", + " self.memory = memory # replay buffer\n", + "\n", + " def sample_action(self, state):\n", + " self.sample_count += 1\n", + " # epsilon must decay(linear,exponential and etc.) for balancing exploration and exploitation\n", + " self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \\\n", + " math.exp(-1. * self.sample_count / self.epsilon_decay) \n", + " if random.random() < self.epsilon:\n", + " action = np.random.randint(self.n_actions)\n", + " else:\n", + " action = self.predict_action(state)\n", + " return action\n", + "\n", + " def predict_action(self, state):\n", + " state = paddle.to_tensor(state , dtype='float32')\n", + " q_values = self.alg.predict(state) # self.alg 是自带的算法\n", + " action = q_values.argmax().numpy()[0]\n", + " return action\n", + "\n", + " def update(self):\n", + " \"\"\"Update model with an episode data\n", + " Args:\n", + " obs(np.float32): shape of (batch_size, obs_dim)\n", + " act(np.int32): shape of (batch_size)\n", + " reward(np.float32): shape of (batch_size)\n", + " next_obs(np.float32): shape of (batch_size, obs_dim)\n", + " terminal(np.float32): shape of (batch_size)\n", + " Returns:\n", + " loss(float)\n", + " \"\"\"\n", + " if len(self.memory) < self.batch_size: # when transitions in memory donot meet a batch, not update\n", + " return\n", + " \n", + " if self.global_step % self.update_target_steps == 0:\n", + " self.alg.sync_target()\n", + " self.global_step += 1\n", + " state_batch, action_batch, reward_batch, next_state_batch, done_batch = self.memory.sample(\n", + " self.batch_size)\n", + " action_batch = np.expand_dims(action_batch, axis=-1)\n", + " reward_batch = np.expand_dims(reward_batch, axis=-1)\n", + " done_batch = np.expand_dims(done_batch, axis=-1)\n", + "\n", + " state_batch = paddle.to_tensor(state_batch, dtype='float32')\n", + " action_batch = paddle.to_tensor(action_batch, dtype='int32')\n", + " reward_batch = paddle.to_tensor(reward_batch, dtype='float32')\n", + " next_state_batch = paddle.to_tensor(next_state_batch, dtype='float32')\n", + " done_batch = paddle.to_tensor(done_batch, dtype='float32')\n", + " loss = self.alg.learn(state_batch, action_batch, reward_batch, next_state_batch, done_batch) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. 定义训练" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def train(cfg, env, agent):\n", + " ''' 训练\n", + " '''\n", + " print(f\"开始训练!\")\n", + " print(f\"环境:{cfg['env_name']},算法:{cfg['algo_name']},设备:{cfg['device']}\")\n", + " rewards = [] # record rewards for all episodes\n", + " steps = []\n", + " for i_ep in range(cfg[\"train_eps\"]):\n", + " ep_reward = 0 # reward per episode\n", + " ep_step = 0\n", + " state = env.reset() # reset and obtain initial state\n", + " for _ in range(cfg['ep_max_steps']):\n", + " ep_step += 1\n", + " action = agent.sample_action(state) # sample action\n", + " next_state, reward, done, _ = env.step(action) # update env and return transitions\n", + " agent.memory.push((state, action, reward,next_state, done)) # save transitions\n", + " state = next_state # update next state for env\n", + " agent.update() # update agent\n", + " ep_reward += reward #\n", + " if done:\n", + " break\n", + " steps.append(ep_step)\n", + " rewards.append(ep_reward)\n", + " if (i_ep + 1) % 10 == 0:\n", + " print(f\"回合:{i_ep+1}/{cfg['train_eps']},奖励:{ep_reward:.2f},Epislon: {agent.epsilon:.3f}\")\n", + " print(\"完成训练!\")\n", + " env.close()\n", + " res_dic = {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps}\n", + " return res_dic\n", + "\n", + "def test(cfg, env, agent):\n", + " print(\"开始测试!\")\n", + " print(f\"环境:{cfg['env_name']},算法:{cfg['algo_name']},设备:{cfg['device']}\")\n", + " rewards = [] # record rewards for all episodes\n", + " steps = []\n", + " for i_ep in range(cfg['test_eps']):\n", + " ep_reward = 0 # reward per episode\n", + " ep_step = 0\n", + " state = env.reset() # reset and obtain initial state\n", + " for _ in range(cfg['ep_max_steps']):\n", + " ep_step+=1\n", + " action = agent.predict_action(state) # predict action\n", + " next_state, reward, done, _ = env.step(action) \n", + " state = next_state \n", + " ep_reward += reward \n", + " if done:\n", + " break\n", + " steps.append(ep_step)\n", + " rewards.append(ep_reward)\n", + " print(f\"回合:{i_ep+1}/{cfg['test_eps']},奖励:{ep_reward:.2f}\")\n", + " print(\"完成测试!\")\n", + " env.close()\n", + " return {'episodes':range(len(rewards)),'rewards':rewards,'steps':steps}\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. 定义环境" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jj/opt/anaconda3/envs/easyrl/lib/python3.7/site-packages/gym/envs/registration.py:250: DeprecationWarning: SelectableGroups dict interface is deprecated. Use select.\n", + " for plugin in metadata.entry_points().get(entry_point, []):\n" + ] + } + ], + "source": [ + "import gym\n", + "import paddle\n", + "import numpy as np\n", + "import random\n", + "import os\n", + "from parl.algorithms import DQN\n", + "def all_seed(env,seed = 1):\n", + " ''' omnipotent seed for RL, attention the position of seed function, you'd better put it just following the env create function\n", + " Args:\n", + " env (_type_): \n", + " seed (int, optional): _description_. Defaults to 1.\n", + " '''\n", + " print(f\"seed = {seed}\")\n", + " env.seed(seed) # env config\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " paddle.seed(seed)\n", + " \n", + "def env_agent_config(cfg):\n", + " ''' create env and agent\n", + " '''\n", + " env = gym.make(cfg['env_name']) \n", + " if cfg['seed'] !=0: # set random seed\n", + " all_seed(env,seed=cfg[\"seed\"]) \n", + " n_states = env.observation_space.shape[0] # print(hasattr(env.observation_space, 'n'))\n", + " n_actions = env.action_space.n # action dimension\n", + " print(f\"n_states: {n_states}, n_actions: {n_actions}\")\n", + " cfg.update({\"n_states\":n_states,\"n_actions\":n_actions}) # update to cfg paramters\n", + " model = MLP(n_states,n_actions)\n", + " algo = DQN(model, gamma=cfg['gamma'], lr=cfg['lr'])\n", + " memory = ReplayBuffer(cfg[\"memory_capacity\"]) # replay buffer\n", + " agent = DQNAgent(algo,memory,cfg) # create agent\n", + " return env, agent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. 设置参数" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jj/opt/anaconda3/envs/easyrl/lib/python3.7/site-packages/seaborn/rcmod.py:82: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.\n", + " if LooseVersion(mpl.__version__) >= \"3.0\":\n", + "/Users/jj/opt/anaconda3/envs/easyrl/lib/python3.7/site-packages/setuptools/_distutils/version.py:351: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.\n", + " other = LooseVersion(other)\n" + ] + } + ], + "source": [ + "import argparse\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "def get_args():\n", + " \"\"\" \n", + " \"\"\"\n", + " parser = argparse.ArgumentParser(description=\"hyperparameters\") \n", + " parser.add_argument('--algo_name',default='DQN',type=str,help=\"name of algorithm\")\n", + " parser.add_argument('--env_name',default='CartPole-v0',type=str,help=\"name of environment\")\n", + " parser.add_argument('--train_eps',default=200,type=int,help=\"episodes of training\") # 训练的回合数\n", + " parser.add_argument('--test_eps',default=20,type=int,help=\"episodes of testing\") # 测试的回合数\n", + " parser.add_argument('--ep_max_steps',default = 100000,type=int,help=\"steps per episode, much larger value can simulate infinite steps\")\n", + " parser.add_argument('--gamma',default=0.99,type=float,help=\"discounted factor\") # 折扣因子\n", + " parser.add_argument('--epsilon_start',default=0.95,type=float,help=\"initial value of epsilon\") # e-greedy策略中初始epsilon\n", + " parser.add_argument('--epsilon_end',default=0.01,type=float,help=\"final value of epsilon\") # e-greedy策略中的终止epsilon\n", + " parser.add_argument('--epsilon_decay',default=200,type=int,help=\"decay rate of epsilon\") # e-greedy策略中epsilon的衰减率\n", + " parser.add_argument('--memory_capacity',default=200000,type=int) # replay memory的容量\n", + " parser.add_argument('--memory_warmup_size',default=200,type=int) # replay memory的预热容量\n", + " parser.add_argument('--batch_size',default=64,type=int,help=\"batch size of training\") # 训练时每次使用的样本数\n", + " parser.add_argument('--targe_update_fre',default=200,type=int,help=\"frequency of target network update\") # target network更新频率\n", + " parser.add_argument('--seed',default=10,type=int,help=\"seed\") \n", + " parser.add_argument('--lr',default=0.0001,type=float,help=\"learning rate\")\n", + " parser.add_argument('--device',default='cpu',type=str,help=\"cpu or gpu\") \n", + " args = parser.parse_args([]) \n", + " args = {**vars(args)} # type(dict) \n", + " return args\n", + "def smooth(data, weight=0.9): \n", + " '''用于平滑曲线,类似于Tensorboard中的smooth\n", + "\n", + " Args:\n", + " data (List):输入数据\n", + " weight (Float): 平滑权重,处于0-1之间,数值越高说明越平滑,一般取0.9\n", + "\n", + " Returns:\n", + " smoothed (List): 平滑后的数据\n", + " '''\n", + " last = data[0] # First value in the plot (first timestep)\n", + " smoothed = list()\n", + " for point in data:\n", + " smoothed_val = last * weight + (1 - weight) * point # 计算平滑值\n", + " smoothed.append(smoothed_val) \n", + " last = smoothed_val \n", + " return smoothed\n", + "\n", + "def plot_rewards(rewards,cfg,path=None,tag='train'):\n", + " sns.set()\n", + " plt.figure() # 创建一个图形实例,方便同时多画几个图\n", + " plt.title(f\"{tag}ing curve on {cfg['device']} of {cfg['algo_name']} for {cfg['env_name']}\")\n", + " plt.xlabel('epsiodes')\n", + " plt.plot(rewards, label='rewards')\n", + " plt.plot(smooth(rewards), label='smoothed')\n", + " plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. 收获成果!" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seed = 10\n", + "n_states: 4, n_actions: 2\n", + "开始训练!\n", + "环境:CartPole-v0,算法:DQN,设备:cpu\n", + "回合:10/200,奖励:10.00,Epislon: 0.062\n", + "回合:20/200,奖励:85.00,Epislon: 0.014\n", + "回合:30/200,奖励:41.00,Epislon: 0.011\n", + "回合:40/200,奖励:31.00,Epislon: 0.010\n", + "回合:50/200,奖励:22.00,Epislon: 0.010\n", + "回合:60/200,奖励:10.00,Epislon: 0.010\n", + "回合:70/200,奖励:10.00,Epislon: 0.010\n", + "回合:80/200,奖励:22.00,Epislon: 0.010\n", + "回合:90/200,奖励:30.00,Epislon: 0.010\n", + "回合:100/200,奖励:20.00,Epislon: 0.010\n", + "回合:110/200,奖励:15.00,Epislon: 0.010\n", + "回合:120/200,奖励:45.00,Epislon: 0.010\n", + "回合:130/200,奖励:73.00,Epislon: 0.010\n", + "回合:140/200,奖励:180.00,Epislon: 0.010\n", + "回合:150/200,奖励:163.00,Epislon: 0.010\n", + "回合:160/200,奖励:191.00,Epislon: 0.010\n", + "回合:170/200,奖励:200.00,Epislon: 0.010\n", + "回合:180/200,奖励:200.00,Epislon: 0.010\n", + "回合:190/200,奖励:200.00,Epislon: 0.010\n", + "回合:200/200,奖励:200.00,Epislon: 0.010\n", + "完成训练!\n", + "开始测试!\n", + "环境:CartPole-v0,算法:DQN,设备:cpu\n", + "回合:1/20,奖励:200.00\n", + "回合:2/20,奖励:200.00\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jj/opt/anaconda3/envs/easyrl/lib/python3.7/site-packages/seaborn/rcmod.py:400: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.\n", + " if LooseVersion(mpl.__version__) >= \"3.0\":\n", + "/Users/jj/opt/anaconda3/envs/easyrl/lib/python3.7/site-packages/setuptools/_distutils/version.py:351: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.\n", + " other = LooseVersion(other)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "回合:3/20,奖励:200.00\n", + "回合:4/20,奖励:200.00\n", + "回合:5/20,奖励:200.00\n", + "回合:6/20,奖励:200.00\n", + "回合:7/20,奖励:200.00\n", + "回合:8/20,奖励:193.00\n", + "回合:9/20,奖励:200.00\n", + "回合:10/20,奖励:200.00\n", + "回合:11/20,奖励:200.00\n", + "回合:12/20,奖励:200.00\n", + "回合:13/20,奖励:200.00\n", + "回合:14/20,奖励:194.00\n", + "回合:15/20,奖励:200.00\n", + "回合:16/20,奖励:200.00\n", + "回合:17/20,奖励:200.00\n", + "回合:18/20,奖励:200.00\n", + "回合:19/20,奖励:199.00\n", + "回合:20/20,奖励:200.00\n", + "完成测试!\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 获取参数\n", + "cfg = get_args() \n", + "# 训练\n", + "env, agent = env_agent_config(cfg)\n", + "res_dic = train(cfg, env, agent)\n", + " \n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"train\") \n", + "# 测试\n", + "res_dic = test(cfg, env, agent)\n", + "plot_rewards(res_dic['rewards'], cfg, tag=\"test\") # 画出结果" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('easyrl')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "8994a120d39b6e6a2ecc94b4007f5314b68aa69fc88a7f00edf21be39b41f49c" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/projects/parl_tutorials/README.md b/projects/parl_tutorials/README.md new file mode 100644 index 0000000..fd03c9a --- /dev/null +++ b/projects/parl_tutorials/README.md @@ -0,0 +1,19 @@ +## 运行环境 + +由于```parl```和```paddle```容易与notebook相关模块发生版本冲突,因此推荐新建一个Conda环境: +```bash +conda create -n parl python=3.7 +``` + +然后安装```parl```和```paddle```: +```bash +pip install parl==2.0.5 + +pip install paddlepaddle-gpu==2.3.2 -i https://pypi.tuna.tsinghua.edu.cn/simple + +pip install paddlepaddle==2.3.2 -i https://pypi.tuna.tsinghua.edu.cn/simple +``` +安装其他依赖: +```bash +pip install -r parl_requirements.txt +``` \ No newline at end of file diff --git a/projects/parl_tutorials/parl_requirements.txt b/projects/parl_tutorials/parl_requirements.txt new file mode 100644 index 0000000..cc8624d --- /dev/null +++ b/projects/parl_tutorials/parl_requirements.txt @@ -0,0 +1,7 @@ +gym==0.19.0 +ipykernel==6.0.0 +jupyter==1.0.0 +pyzmq==18.1.1 +jupyter-client==7.0.0 +matplotlib==3.5.3 +seaborn==0.12.0 \ No newline at end of file diff --git a/projects/requirements.txt b/projects/requirements.txt index 13ee9d0..7dbd44a 100644 --- a/projects/requirements.txt +++ b/projects/requirements.txt @@ -1,4 +1,4 @@ -gym==0.21.0 +pyyaml==6.0 ipykernel==6.15.1 jupyter==1.0.0 matplotlib==3.5.2 @@ -6,3 +6,5 @@ seaborn==0.11.2 dill==0.3.5.1 argparse==1.4.0 pandas==1.3.5 +pyglet==1.5.26 +importlib-metadata<5.0 \ No newline at end of file