From 80f20c73beafd08218a313fa7dd1fe40736832bf Mon Sep 17 00:00:00 2001 From: johnjim0816 Date: Thu, 25 Aug 2022 21:00:53 +0800 Subject: [PATCH] hot update PG --- projects/PARL/DQN.ipynb | 318 ------- projects/PARL/README.md | 11 - projects/README.md | 1 - projects/codes/PolicyGradient/main.py | 129 +++ .../20220822-174059/results/params.json | 16 - .../models/checkpoint.pt | Bin .../20220825-205930/results/params.json | 1 + .../results/testing_curve.png | Bin .../results/testing_results.csv | 0 .../results/training_curve.png | Bin .../results/training_results.csv | 0 projects/codes/PolicyGradient/pg.py | 10 +- projects/codes/PolicyGradient/task0.py | 139 --- projects/codes/QLearning/main.py | 220 ++--- .../20220824-112735/models/Qleaning_model.pkl | Bin 2543 -> 0 bytes .../20220824-112735/results/testing_curve.png | Bin 22658 -> 0 bytes .../results/training_curve.png | Bin 53864 -> 0 bytes .../results/training_results.csv | 801 ------------------ .../20220825-114335/models/Qleaning_model.pkl | Bin 0 -> 2543 bytes .../20220825-114335}/results/params.json | 6 +- .../20220825-114335/results/testing_curve.png | Bin 0 -> 24049 bytes .../results/testing_results.csv | 0 .../results/training_curve.png | Bin 0 -> 56073 bytes .../results/training_results.csv | 801 ++++++++++++++++++ projects/codes/Sarsa/main.py | 136 +++ projects/codes/Sarsa/sarsa.py | 66 +- projects/codes/Sarsa/task0.py | 118 --- projects/codes/common/launcher.py | 32 + projects/codes/envs/gridworld_env.py | 78 -- .../envs/{racetrack_env.py => racetrack.py} | 75 +- projects/codes/envs/register.py | 34 + projects/codes/envs/wrappers.py | 78 ++ projects/codes/scripts/Qlearning_task1.sh | 3 +- projects/codes/scripts/Sarsa_task0.sh | 13 + 34 files changed, 1391 insertions(+), 1695 deletions(-) delete mode 100644 projects/PARL/DQN.ipynb delete mode 100644 projects/PARL/README.md create mode 100644 projects/codes/PolicyGradient/main.py delete mode 100644 projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/params.json rename projects/codes/PolicyGradient/outputs/CartPole-v0/{20220822-174059 => 20220825-205930}/models/checkpoint.pt (100%) create mode 100644 projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/params.json rename projects/codes/PolicyGradient/outputs/CartPole-v0/{20220822-174059 => 20220825-205930}/results/testing_curve.png (100%) rename projects/codes/PolicyGradient/outputs/CartPole-v0/{20220822-174059 => 20220825-205930}/results/testing_results.csv (100%) rename projects/codes/PolicyGradient/outputs/CartPole-v0/{20220822-174059 => 20220825-205930}/results/training_curve.png (100%) rename projects/codes/PolicyGradient/outputs/CartPole-v0/{20220822-174059 => 20220825-205930}/results/training_results.csv (100%) delete mode 100644 projects/codes/PolicyGradient/task0.py delete mode 100644 projects/codes/QLearning/outputs/FrozenLake-v1/20220824-112735/models/Qleaning_model.pkl delete mode 100644 projects/codes/QLearning/outputs/FrozenLake-v1/20220824-112735/results/testing_curve.png delete mode 100644 projects/codes/QLearning/outputs/FrozenLake-v1/20220824-112735/results/training_curve.png delete mode 100644 projects/codes/QLearning/outputs/FrozenLake-v1/20220824-112735/results/training_results.csv create mode 100644 projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/models/Qleaning_model.pkl rename projects/codes/QLearning/outputs/{FrozenLake-v1/20220824-112735 => FrozenLakeNoSlippery-v1/20220825-114335}/results/params.json (72%) create mode 100644 projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/testing_curve.png rename projects/codes/QLearning/outputs/{FrozenLake-v1/20220824-112735 => FrozenLakeNoSlippery-v1/20220825-114335}/results/testing_results.csv (100%) create mode 100644 projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_curve.png create mode 100644 projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_results.csv create mode 100644 projects/codes/Sarsa/main.py delete mode 100644 projects/codes/Sarsa/task0.py create mode 100644 projects/codes/common/launcher.py rename projects/codes/envs/{racetrack_env.py => racetrack.py} (84%) create mode 100644 projects/codes/envs/register.py create mode 100644 projects/codes/envs/wrappers.py create mode 100644 projects/codes/scripts/Sarsa_task0.sh diff --git a/projects/PARL/DQN.ipynb b/projects/PARL/DQN.ipynb deleted file mode 100644 index 57b0746..0000000 --- a/projects/PARL/DQN.ipynb +++ /dev/null @@ -1,318 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 定义模型\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "import paddle\n", - "import paddle.nn as nn\n", - "import paddle.nn.functional as F\n", - "import parl\n", - "\n", - "class CartpoleModel(parl.Model):\n", - " \"\"\" Linear network to solve Cartpole problem.\n", - " Args:\n", - " n_states (int): Dimension of observation space.\n", - " n_actions (int): Dimension of action space.\n", - " \"\"\"\n", - "\n", - " def __init__(self, n_states, n_actions):\n", - " super(CartpoleModel, self).__init__()\n", - " hid1_size = 128\n", - " hid2_size = 128\n", - " self.fc1 = nn.Linear(n_states, hid1_size)\n", - " self.fc2 = nn.Linear(hid1_size, hid2_size)\n", - " self.fc3 = nn.Linear(hid2_size, n_actions)\n", - "\n", - " def forward(self, obs):\n", - " h1 = F.relu(self.fc1(obs))\n", - " h2 = F.relu(self.fc2(h1))\n", - " Q = self.fc3(h2)\n", - " return Q" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "import parl\n", - "import paddle\n", - "import numpy as np\n", - "\n", - "\n", - "class CartpoleAgent(parl.Agent):\n", - " \"\"\"Agent of Cartpole env.\n", - " Args:\n", - " algorithm(parl.Algorithm): algorithm used to solve the problem.\n", - " \"\"\"\n", - "\n", - " def __init__(self, algorithm, n_actions, e_greed=0.1, e_greed_decrement=0):\n", - " super(CartpoleAgent, self).__init__(algorithm)\n", - " assert isinstance(n_actions, int)\n", - " self.n_actions = n_actions\n", - "\n", - " self.global_step = 0\n", - " self.update_target_steps = 200\n", - "\n", - " self.e_greed = e_greed\n", - " self.e_greed_decrement = e_greed_decrement\n", - "\n", - " def sample(self, obs):\n", - " \"\"\"Sample an action `for exploration` when given an observation\n", - " Args:\n", - " obs(np.float32): shape of (n_states,)\n", - " Returns:\n", - " act(int): action\n", - " \"\"\"\n", - " sample = np.random.random()\n", - " if sample < self.e_greed:\n", - " act = np.random.randint(self.n_actions)\n", - " else:\n", - " if np.random.random() < 0.01:\n", - " act = np.random.randint(self.n_actions)\n", - " else:\n", - " act = self.predict(obs)\n", - " self.e_greed = max(0.01, self.e_greed - self.e_greed_decrement)\n", - " return act\n", - "\n", - " def predict(self, obs):\n", - " \"\"\"Predict an action when given an observation\n", - " Args:\n", - " obs(np.float32): shape of (n_states,)\n", - " Returns:\n", - " act(int): action\n", - " \"\"\"\n", - " obs = paddle.to_tensor(obs, dtype='float32')\n", - " pred_q = self.alg.predict(obs)\n", - " act = pred_q.argmax().numpy()[0]\n", - " return act\n", - "\n", - " def learn(self, obs, act, reward, next_obs, terminal):\n", - " \"\"\"Update model with an episode data\n", - " Args:\n", - " obs(np.float32): shape of (batch_size, n_states)\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, n_states)\n", - " terminal(np.float32): shape of (batch_size)\n", - " Returns:\n", - " loss(float)\n", - " \"\"\"\n", - " if self.global_step % self.update_target_steps == 0:\n", - " self.alg.sync_target()\n", - " self.global_step += 1\n", - "\n", - " act = np.expand_dims(act, axis=-1)\n", - " reward = np.expand_dims(reward, axis=-1)\n", - " terminal = np.expand_dims(terminal, axis=-1)\n", - "\n", - " obs = paddle.to_tensor(obs, dtype='float32')\n", - " act = paddle.to_tensor(act, dtype='int32')\n", - " reward = paddle.to_tensor(reward, dtype='float32')\n", - " next_obs = paddle.to_tensor(next_obs, dtype='float32')\n", - " terminal = paddle.to_tensor(terminal, dtype='float32')\n", - " loss = self.alg.learn(obs, act, reward, next_obs, terminal)\n", - " return loss.numpy()[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import gym\n", - "import numpy as np\n", - "import parl\n", - "\n", - "from parl.utils import logger, ReplayMemory\n", - "from parl.algorithms import DQN\n", - "\n", - "LEARN_FREQ = 5 # training frequency\n", - "MEMORY_SIZE = 200000\n", - "MEMORY_WARMUP_SIZE = 200\n", - "BATCH_SIZE = 64\n", - "LEARNING_RATE = 0.0005\n", - "GAMMA = 0.99\n", - "\n", - "# train an episode\n", - "def run_train_episode(agent, env, rpm):\n", - " total_reward = 0\n", - " obs = env.reset()\n", - " step = 0\n", - " while True:\n", - " step += 1\n", - " action = agent.sample(obs)\n", - " next_obs, reward, done, _ = env.step(action)\n", - " rpm.append(obs, action, reward, next_obs, done)\n", - "\n", - " # train model\n", - " if (len(rpm) > MEMORY_WARMUP_SIZE) and (step % LEARN_FREQ == 0):\n", - " # s,a,r,s',done\n", - " (batch_obs, batch_action, batch_reward, batch_next_obs,\n", - " batch_done) = rpm.sample_batch(BATCH_SIZE)\n", - " train_loss = agent.learn(batch_obs, batch_action, batch_reward,\n", - " batch_next_obs, batch_done)\n", - "\n", - " total_reward += reward\n", - " obs = next_obs\n", - " if done:\n", - " break\n", - " return total_reward\n", - "\n", - "\n", - "# evaluate 5 episodes\n", - "def run_evaluate_episodes(agent, env, eval_episodes=5, render=False):\n", - " eval_reward = []\n", - " for i in range(eval_episodes):\n", - " obs = env.reset()\n", - " episode_reward = 0\n", - " while True:\n", - " action = agent.predict(obs)\n", - " obs, reward, done, _ = env.step(action)\n", - " episode_reward += reward\n", - " if render:\n", - " env.render()\n", - " if done:\n", - " break\n", - " eval_reward.append(episode_reward)\n", - " return np.mean(eval_reward)\n", - "\n", - "\n", - "def main(args):\n", - " env = gym.make('CartPole-v0')\n", - " n_states = env.observation_space.shape[0]\n", - " n_actions = env.action_space.n\n", - " logger.info('n_states {}, n_actions {}'.format(n_states, n_actions))\n", - "\n", - " # set action_shape = 0 while in discrete control environment\n", - " rpm = ReplayMemory(MEMORY_SIZE, n_states, 0)\n", - "\n", - " # build an agent\n", - " model = CartpoleModel(n_states=n_states, n_actions=n_actions)\n", - " alg = DQN(model, gamma=GAMMA, lr=LEARNING_RATE)\n", - " agent = CartpoleAgent(\n", - " alg, n_actions=n_actions, e_greed=0.1, e_greed_decrement=1e-6)\n", - "\n", - " # warmup memory\n", - " while len(rpm) < MEMORY_WARMUP_SIZE:\n", - " run_train_episode(agent, env, rpm)\n", - "\n", - " max_episode = args.max_episode\n", - "\n", - " # start training\n", - " episode = 0\n", - " while episode < max_episode:\n", - " # train part\n", - " for i in range(50):\n", - " total_reward = run_train_episode(agent, env, rpm)\n", - " episode += 1\n", - "\n", - " # test part\n", - " eval_reward = run_evaluate_episodes(agent, env, render=False)\n", - " logger.info('episode:{} e_greed:{} Test reward:{}'.format(\n", - " episode, agent.e_greed, eval_reward))\n", - "\n", - " # save the parameters to ./model.ckpt\n", - " save_path = './model.ckpt'\n", - " agent.save(save_path)\n", - "\n", - " # save the model and parameters of policy network for inference\n", - " save_inference_path = './inference_model'\n", - " input_shapes = [[None, env.observation_space.shape[0]]]\n", - " input_dtypes = ['float32']\n", - " agent.save_inference_model(save_inference_path, input_shapes, input_dtypes)\n", - "\n", - "\n", - "\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32m[08-01 21:48:19 MainThread @3996942455.py:64]\u001b[0m obs_dim 4, act_dim 2\n", - "\u001b[32m[08-01 21:48:19 MainThread @3996942455.py:92]\u001b[0m episode:50 e_greed:0.0988929999999989 Test reward:18.4\n", - "\u001b[32m[08-01 21:48:20 MainThread @3996942455.py:92]\u001b[0m episode:100 e_greed:0.09794799999999795 Test reward:9.6\n", - "\u001b[32m[08-01 21:48:20 MainThread @3996942455.py:92]\u001b[0m episode:150 e_greed:0.0973899999999974 Test reward:37.8\n", - "\u001b[32m[08-01 21:48:20 MainThread @3996942455.py:92]\u001b[0m episode:200 e_greed:0.09684299999999685 Test reward:8.8\n", - "\u001b[32m[08-01 21:48:20 MainThread @3996942455.py:92]\u001b[0m episode:250 e_greed:0.09635499999999636 Test reward:9.4\n", - "\u001b[32m[08-01 21:48:21 MainThread @3996942455.py:92]\u001b[0m episode:300 e_greed:0.09585299999999586 Test reward:9.2\n", - "\u001b[32m[08-01 21:48:21 MainThread @3996942455.py:92]\u001b[0m episode:350 e_greed:0.09535799999999536 Test reward:9.2\n", - "\u001b[32m[08-01 21:48:21 MainThread @3996942455.py:92]\u001b[0m episode:400 e_greed:0.09486399999999487 Test reward:10.0\n", - "\u001b[32m[08-01 21:48:21 MainThread @3996942455.py:92]\u001b[0m episode:450 e_greed:0.09435299999999436 Test reward:9.2\n", - "\u001b[32m[08-01 21:48:22 MainThread @3996942455.py:92]\u001b[0m episode:500 e_greed:0.09384899999999385 Test reward:9.4\n", - "\u001b[32m[08-01 21:48:22 MainThread @3996942455.py:92]\u001b[0m episode:550 e_greed:0.09302299999999303 Test reward:69.0\n", - "\u001b[32m[08-01 21:48:25 MainThread @3996942455.py:92]\u001b[0m episode:600 e_greed:0.08774199999998775 Test reward:141.2\n", - "\u001b[32m[08-01 21:48:30 MainThread @3996942455.py:92]\u001b[0m episode:650 e_greed:0.0791019999999791 Test reward:184.0\n", - "\u001b[32m[08-01 21:48:35 MainThread @3996942455.py:92]\u001b[0m episode:700 e_greed:0.07011299999997012 Test reward:182.0\n", - "\u001b[32m[08-01 21:48:40 MainThread @3996942455.py:92]\u001b[0m episode:750 e_greed:0.06089099999996089 Test reward:197.4\n", - "\u001b[32m[08-01 21:48:45 MainThread @3996942455.py:92]\u001b[0m episode:800 e_greed:0.05139199999995139 Test reward:183.4\n", - "\u001b[32m[08-01 21:48:50 MainThread @3996942455.py:92]\u001b[0m episode:850 e_greed:0.042255999999942256 Test reward:153.0\n", - "\u001b[32m[08-01 21:48:55 MainThread @3996942455.py:92]\u001b[0m episode:900 e_greed:0.033495999999933496 Test reward:192.6\n", - "\u001b[32m[08-01 21:49:00 MainThread @3996942455.py:92]\u001b[0m episode:950 e_greed:0.024318999999924318 Test reward:166.6\n", - "\u001b[32m[08-01 21:49:06 MainThread @3996942455.py:92]\u001b[0m episode:1000 e_greed:0.014873999999916176 Test reward:187.0\n" - ] - } - ], - "source": [ - "import argparse\n", - "parser = argparse.ArgumentParser()\n", - "parser.add_argument(\n", - " '--max_episode',\n", - " type=int,\n", - " default=1000,\n", - " help='stop condition: number of max episode')\n", - "args = parser.parse_args(args=[])\n", - "\n", - "main(args)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.7.12 ('rl_tutorials')", - "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.12" - }, - "orig_nbformat": 4, - "vscode": { - "interpreter": { - "hash": "4f613f1ab80ec98dc1b91d6e720de51301598a187317378e53e49b773c1123dd" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/projects/PARL/README.md b/projects/PARL/README.md deleted file mode 100644 index a8ddbb7..0000000 --- a/projects/PARL/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[PARL](https://github.com/PaddlePaddle/PARL)是一个高性能、灵活的强化学习框架,由百度AI Studio开发。 - -## 安装 - -1. 安装parl,参考[PARL Github](https://github.com/PaddlePaddle/PARL) -2. 安装paddlepaddle:```pip install paddlepaddle``` - -## 常见问题 - -```jupyter-client 7.3.1 requires pyzmq>=22.3, but you have pyzmq 18.1.1 which is incompatible.```: -```pip install -U pyzmq``` \ No newline at end of file diff --git a/projects/README.md b/projects/README.md index bd112d9..84d96b9 100644 --- a/projects/README.md +++ b/projects/README.md @@ -11,7 +11,6 @@ 项目内容主要包含以下几个部分: * [Jupyter Notebook](./notebooks/):使用Notebook写的算法,有比较详细的实战引导,推荐新手食用 * [codes](./codes/):这些是基于Python脚本写的算法,风格比较接近实际项目的写法,推荐有一定代码基础的人阅读,下面会说明其具体的一些架构 -* [parl](./PARL/):应业务需求,写了一些基于百度飞浆平台和```parl```模块的RL实例 * [附件](./assets/):目前包含强化学习各算法的中文伪代码 diff --git a/projects/codes/PolicyGradient/main.py b/projects/codes/PolicyGradient/main.py new file mode 100644 index 0000000..2e4c5e4 --- /dev/null +++ b/projects/codes/PolicyGradient/main.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# coding=utf-8 +''' +Author: John +Email: johnjim0816@gmail.com +Date: 2020-11-22 23:21:53 +LastEditor: John +LastEditTime: 2022-08-25 20:59:23 +Discription: +Environment: +''' +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 +import torch +import datetime +import argparse +from itertools import count +import torch.nn.functional as F +from pg import PolicyGradient +from common.utils import save_results, make_dir,all_seed,save_args,plot_rewards +from common.models import MLP +from common.memories import PGReplay +from common.launcher import Launcher +from envs.register import register_env + + +class PGNet(MLP): + ''' instead of outputing action, PG Net outputs propabilities of actions, we can use class inheritance from MLP here + ''' + def forward(self, x): + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + x = F.sigmoid(self.fc3(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='PolicyGradient',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('--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('--lr',default=0.005,type=float,help="learning rate") + parser.add_argument('--update_fre',default=8,type=int) + parser.add_argument('--hidden_dim',default=36,type=int) + parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") + parser.add_argument('--seed',default=1,type=int,help="seed") + parser.add_argument('--save_fig',default=True,type=bool,help="if save figure or not") + parser.add_argument('--show_fig',default=False,type=bool,help="if show 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']) + n_states = env.observation_space.shape[0] + n_actions = env.action_space.n # action dimension + print(f"state dim: {n_states}, action dim: {n_actions}") + cfg.update({"n_states":n_states,"n_actions":n_actions}) # update to cfg paramters + model = PGNet(n_states,1,hidden_dim=cfg['hidden_dim']) + memory = PGReplay() + agent = PolicyGradient(model,memory,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 = [] + for i_ep in range(cfg['train_eps']): + state = env.reset() + ep_reward = 0 + for _ in count(): + action = agent.sample_action(state) # sample action + next_state, reward, done, _ = env.step(action) + ep_reward += reward + if done: + reward = 0 + agent.memory.push((state,float(action),reward)) + state = next_state + if done: + print(f"Episode:{i_ep+1}/{cfg['train_eps']}, Reward:{ep_reward:.2f}") + break + if (i_ep+1) % cfg['update_fre'] == 0: + agent.update() + rewards.append(ep_reward) + print('Finish training!') + env.close() # close environment + res_dic = {'episodes':range(len(rewards)),'rewards':rewards} + return res_dic + + def test(self,cfg,env,agent): + print("Start testing!") + print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") + rewards = [] + for i_ep in range(cfg['test_eps']): + state = env.reset() + ep_reward = 0 + for _ in count(): + action = agent.predict_action(state) + next_state, reward, done, _ = env.step(action) + ep_reward += reward + if done: + reward = 0 + state = next_state + if done: + print(f"Episode: {i_ep+1}/{cfg['test_eps']},Reward: {ep_reward:.2f}") + break + rewards.append(ep_reward) + print("Finish testing!") + env.close() + return {'episodes':range(len(rewards)),'rewards':rewards} + +if __name__ == "__main__": + main = Main() + main.run() + + diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/params.json b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/params.json deleted file mode 100644 index 0dca316..0000000 --- a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/params.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "algo_name": "PolicyGradient", - "env_name": "CartPole-v0", - "train_eps": 200, - "test_eps": 20, - "gamma": 0.99, - "lr": 0.005, - "update_fre": 8, - "hidden_dim": 36, - "device": "cpu", - "seed": 1, - "result_path": "/Users/jj/Desktop/rl-tutorials/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/", - "model_path": "/Users/jj/Desktop/rl-tutorials/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/models/", - "save_fig": true, - "show_fig": false -} \ No newline at end of file diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/models/checkpoint.pt b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/models/checkpoint.pt similarity index 100% rename from projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/models/checkpoint.pt rename to projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/models/checkpoint.pt diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/params.json b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/params.json new file mode 100644 index 0000000..2a3810d --- /dev/null +++ b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/params.json @@ -0,0 +1 @@ +{"algo_name": "PolicyGradient", "env_name": "CartPole-v0", "train_eps": 200, "test_eps": 20, "gamma": 0.99, "lr": 0.005, "update_fre": 8, "hidden_dim": 36, "device": "cpu", "seed": 1, "save_fig": true, "show_fig": false, "result_path": "/Users/jj/Desktop/rl-tutorials/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/", "model_path": "/Users/jj/Desktop/rl-tutorials/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/models/", "n_states": 4, "n_actions": 2} \ No newline at end of file diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/testing_curve.png b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/testing_curve.png similarity index 100% rename from projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/testing_curve.png rename to projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/testing_curve.png diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/testing_results.csv b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/testing_results.csv similarity index 100% rename from projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/testing_results.csv rename to projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/testing_results.csv diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/training_curve.png b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/training_curve.png similarity index 100% rename from projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/training_curve.png rename to projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/training_curve.png diff --git a/projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/training_results.csv b/projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/training_results.csv similarity index 100% rename from projects/codes/PolicyGradient/outputs/CartPole-v0/20220822-174059/results/training_results.csv rename to projects/codes/PolicyGradient/outputs/CartPole-v0/20220825-205930/results/training_results.csv diff --git a/projects/codes/PolicyGradient/pg.py b/projects/codes/PolicyGradient/pg.py index 8cd8688..aeef3f8 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-22 17:35:34 +LastEditTime: 2022-08-25 20:58:59 Discription: Environment: ''' @@ -19,12 +19,12 @@ import numpy as np class PolicyGradient: - def __init__(self, n_states,model,memory,cfg): - self.gamma = cfg.gamma - self.device = torch.device(cfg.device) + def __init__(self, model,memory,cfg): + self.gamma = cfg['gamma'] + self.device = torch.device(cfg['device']) self.memory = memory self.policy_net = model.to(self.device) - self.optimizer = torch.optim.RMSprop(self.policy_net.parameters(), lr=cfg.lr) + self.optimizer = torch.optim.RMSprop(self.policy_net.parameters(), lr=cfg['lr']) def sample_action(self,state): diff --git a/projects/codes/PolicyGradient/task0.py b/projects/codes/PolicyGradient/task0.py deleted file mode 100644 index 8f42f25..0000000 --- a/projects/codes/PolicyGradient/task0.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -''' -Author: John -Email: johnjim0816@gmail.com -Date: 2020-11-22 23:21:53 -LastEditor: John -LastEditTime: 2022-08-22 17:40:07 -Discription: -Environment: -''' -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 -import torch -import datetime -import argparse -from itertools import count -import torch.nn.functional as F -from pg import PolicyGradient -from common.utils import save_results, make_dir,all_seed,save_args,plot_rewards -from common.models import MLP -from common.memories import PGReplay - - -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='PolicyGradient',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('--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('--lr',default=0.005,type=float,help="learning rate") - parser.add_argument('--update_fre',default=8,type=int) - parser.add_argument('--hidden_dim',default=36,type=int) - parser.add_argument('--device',default='cpu',type=str,help="cpu or cuda") - parser.add_argument('--seed',default=1,type=int,help="seed") - 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") - parser.add_argument('--show_fig',default=False,type=bool,help="if show figure or not") - args = parser.parse_args([]) - return args - -class PGNet(MLP): - ''' instead of outputing action, PG Net outputs propabilities of actions, we can use class inheritance from MLP here - ''' - def forward(self, x): - x = F.relu(self.fc1(x)) - x = F.relu(self.fc2(x)) - x = F.sigmoid(self.fc3(x)) - return x - -def env_agent_config(cfg): - env = gym.make(cfg.env_name) - 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.n # action dimension - print(f"state dim: {n_states}, action dim: {n_actions}") - model = PGNet(n_states,1,hidden_dim=cfg.hidden_dim) - memory = PGReplay() - agent = PolicyGradient(n_states,model,memory,cfg) - return env,agent - -def train(cfg,env,agent): - print('Start training!') - print(f'Env:{cfg.env_name}, Algo:{cfg.algo_name}, Device:{cfg.device}') - rewards = [] - for i_ep in range(cfg.train_eps): - state = env.reset() - ep_reward = 0 - for _ in count(): - action = agent.sample_action(state) # sample action - next_state, reward, done, _ = env.step(action) - ep_reward += reward - if done: - reward = 0 - agent.memory.push((state,float(action),reward)) - state = next_state - if done: - print(f'Episode:{i_ep+1}/{cfg.train_eps}, Reward:{ep_reward:.2f}') - break - if (i_ep+1) % cfg.update_fre == 0: - agent.update() - rewards.append(ep_reward) - print('Finish training!') - env.close() # close environment - res_dic = {'episodes':range(len(rewards)),'rewards':rewards} - return res_dic - - -def test(cfg,env,agent): - print("start testing!") - print(f"Env: {cfg.env_name}, Algo: {cfg.algo_name}, Device: {cfg.device}") - rewards = [] - for i_ep in range(cfg.test_eps): - state = env.reset() - ep_reward = 0 - for _ in count(): - action = agent.predict_action(state) - next_state, reward, done, _ = env.step(action) - ep_reward += reward - if done: - reward = 0 - state = next_state - if done: - print(f'Episode: {i_ep+1}/{cfg.test_eps},Reward: {ep_reward:.2f}') - break - rewards.append(ep_reward) - print("finish testing!") - env.close() - 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) - 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 = 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 = 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") - - diff --git a/projects/codes/QLearning/main.py b/projects/codes/QLearning/main.py index 5939722..8f423ef 100644 --- a/projects/codes/QLearning/main.py +++ b/projects/codes/QLearning/main.py @@ -5,7 +5,7 @@ Author: John Email: johnjim0816@gmail.com Date: 2020-09-11 23:03:00 LastEditor: John -LastEditTime: 2022-08-24 11:27:01 +LastEditTime: 2022-08-25 14:59:15 Discription: Environment: ''' @@ -18,136 +18,102 @@ sys.path.append(parent_path) # add path to system path import gym import datetime import argparse -from envs.gridworld_env import CliffWalkingWapper,FrozenLakeWapper +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 plot_rewards,save_args,all_seed -from common.utils import save_results,make_dir - -def get_args(): - 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(cfg): - ''' create env and agent - ''' - if cfg['env_name'] == 'CliffWalking-v0': - env = gym.make(cfg['env_name']) - env = CliffWalkingWapper(env) - if cfg['env_name'] == 'FrozenLake-v1': - env = gym.make(cfg['env_name'],is_slippery=False) - if cfg['seed'] !=0: # set random seed - all_seed(env,seed=cfg["seed"]) - n_states = env.observation_space.n # state dimension - 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 main(cfg,env,agent,tag = 'train'): - print(f"Start {tag}ing!") - print(f"Env: {cfg['env_name']}, Algorithm: {cfg['algo_name']}, Device: {cfg['device']}") - rewards = [] # 记录奖励 - for i_ep in range(cfg.train_eps): - ep_reward = 0 # 记录每个回合的奖励 - state = env.reset() # 重置环境,即开始新的回合 - while True: - if tag == 'train':action = agent.sample_action(state) # 根据算法采样一个动作 - else: agent.predict_action(state) - next_state, reward, done, _ = env.step(action) # 与环境进行一次动作交互 - if tag == 'train':agent.update(state, action, reward, next_state, done) # Q学习算法更新 - state = next_state # 更新状态 - ep_reward += reward - if done: - break - rewards.append(ep_reward) - print(f"回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.1f},Epsilon:{agent.epsilon}") - print(f"Finish {tag}ing!") - return {"rewards":rewards} - -def train(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(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} +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"]) + n_states = env.observation_space.n # state dimension + 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__": - cfg = get_args() - # training - env, agent = env_agent_config(cfg) - res_dic = 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 = 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 = 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() + diff --git a/projects/codes/QLearning/outputs/FrozenLake-v1/20220824-112735/models/Qleaning_model.pkl b/projects/codes/QLearning/outputs/FrozenLake-v1/20220824-112735/models/Qleaning_model.pkl deleted file mode 100644 index 852450152c8452413c7ba068d3795ad64f4ebf0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2543 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 z 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 GdG8;~7aAM@ literal 0 HcmV?d00001 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 new file mode 100644 index 0000000..4177f08 --- /dev/null +++ b/projects/codes/QLearning/outputs/FrozenLakeNoSlippery-v1/20220825-114335/results/training_results.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,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/Sarsa/main.py b/projects/codes/Sarsa/main.py new file mode 100644 index 0000000..1ea4527 --- /dev/null +++ b/projects/codes/Sarsa/main.py @@ -0,0 +1,136 @@ +#!/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-25 14:26:36 +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 save_results,make_dir,plot_rewards,save_args,all_seed + +def get_args(): + 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('--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(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(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(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 + while True: + # 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__": + 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) # save parameters + agent.save(path=cfg.model_path) # save model + save_results(res_dic, tag='train', + path=cfg.result_path) + plot_rewards(res_dic['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'], cfg, tag="test") # 画出结果 + + + diff --git a/projects/codes/Sarsa/sarsa.py b/projects/codes/Sarsa/sarsa.py index 79b5997..c10d226 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-04 22:22:16 +LastEditTime: 2022-08-25 00:23:22 Discription: Environment: ''' @@ -14,45 +14,51 @@ from collections import defaultdict import torch import math class Sarsa(object): - def __init__(self, - n_actions,cfg): - self.n_actions = n_actions - self.lr = cfg.lr - self.gamma = cfg.gamma - self.sample_count = 0 - self.epsilon_start = cfg.epsilon_start - self.epsilon_end = cfg.epsilon_end - self.epsilon_decay = cfg.epsilon_decay - self.Q = defaultdict(lambda: np.zeros(n_actions)) # Q table - def sample(self, state): + def __init__(self,cfg): + 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.Q_table = defaultdict(lambda: np.zeros(self.n_actions)) # Q table + def sample_action(self, state): + ''' another way to represent e-greedy policy + ''' self.sample_count += 1 self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \ math.exp(-1. * self.sample_count / self.epsilon_decay) # The probability to select a random action, is is log decayed - best_action = np.argmax(self.Q[state]) + best_action = np.argmax(self.Q_table[state]) action_probs = np.ones(self.n_actions, dtype=float) * self.epsilon / self.n_actions action_probs[best_action] += (1.0 - self.epsilon) action = np.random.choice(np.arange(len(action_probs)), p=action_probs) return action - def predict(self,state): - return np.argmax(self.Q[state]) - def update(self, state, action, reward, next_state, next_action,done): - Q_predict = self.Q[state][action] - if done: - Q_target = reward # 终止状态 - else: - Q_target = reward + self.gamma * self.Q[next_state][next_action] # 与Q learning不同,Sarsa是拿下一步动作对应的Q值去更新 - self.Q[state][action] += self.lr * (Q_target - Q_predict) - def save(self,path): - '''把 Q表格 的数据保存到文件中 + def predict_action(self,state): + ''' predict action while testing ''' + action = np.argmax(self.Q_table[state]) + return action + def update(self, state, action, reward, next_state, next_action,done): + Q_predict = self.Q_table[state][action] + if done: + Q_target = reward # terminal state + else: + Q_target = reward + self.gamma * self.Q_table[next_state][next_action] # the only difference from Q learning + self.Q_table[state][action] += self.lr * (Q_target - Q_predict) + def save_model(self,path): import dill + from pathlib import Path + # create path + Path(path).mkdir(parents=True, exist_ok=True) torch.save( - obj=self.Q, - f=path+"sarsa_model.pkl", + obj=self.Q_table_table, + f=path+"checkpoint.pkl", pickle_module=dill ) - def load(self, path): - '''从文件中读取数据到 Q表格 - ''' + print("Model saved!") + def load_model(self, path): import dill - self.Q =torch.load(f=path+'sarsa_model.pkl',pickle_module=dill) \ No newline at end of file + self.Q_table_table =torch.load(f=path+'checkpoint.pkl',pickle_module=dill) + print("Mode loaded!") \ No newline at end of file diff --git a/projects/codes/Sarsa/task0.py b/projects/codes/Sarsa/task0.py deleted file mode 100644 index fb84222..0000000 --- a/projects/codes/Sarsa/task0.py +++ /dev/null @@ -1,118 +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-04 22:28:51 -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) # 添加路径到系统路径 - -import datetime -import argparse -from envs.racetrack_env import RacetrackEnv -from Sarsa.sarsa import Sarsa -from common.utils import save_results,make_dir,plot_rewards,save_args - -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='Sarsa',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=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=200,type=int) # 每回合最大的部署 - 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") # e-greedy策略中初始epsilon - parser.add_argument('--epsilon_end',default=0.01,type=float,help="final value of epsilon") # e-greedy策略中的终止epsilon - parser.add_argument('--epsilon_decay',default=200,type=int,help="decay rate of epsilon") # e-greedy策略中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('--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 = RacetrackEnv() - n_actions = 9 # 动作数 - agent = Sarsa(n_actions,cfg) - return env,agent - -def train(cfg,env,agent): - print('开始训练!') - print(f'环境:{cfg.env_name}, 算法:{cfg.algo_name}, 设备:{cfg.device}') - rewards = [] # 记录奖励 - for i_ep in range(cfg.train_eps): - state = env.reset() - action = agent.sample(state) - ep_reward = 0 - # while True: - for _ in range(cfg.ep_max_steps): - next_state, reward, done = env.step(action) - ep_reward+=reward - next_action = agent.sample(next_state) - agent.update(state, action, reward, next_state, next_action,done) - state = next_state - action = next_action - if done: - break - rewards.append(ep_reward) - if (i_ep+1)%2==0: - print(f"回合:{i_ep+1}/{cfg.train_eps},奖励:{ep_reward:.1f},Epsilon:{agent.epsilon}") - print('完成训练!') - return {"rewards":rewards} - -def test(cfg,env,agent): - print('开始测试!') - print(f'环境:{cfg.env_name}, 算法:{cfg.algo_name}, 设备:{cfg.device}') - rewards = [] - for i_ep in range(cfg.test_eps): - state = env.reset() - ep_reward = 0 - # while True: - for _ in range(cfg.ep_max_steps): - action = agent.predict(state) - next_state, reward, done = env.step(action) - ep_reward+=reward - state = next_state - if done: - break - rewards.append(ep_reward) - print(f"回合数:{i_ep+1}/{cfg.test_eps}, 奖励:{ep_reward:.1f}") - print('完成测试!') - return {"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) # save parameters - agent.save(path=cfg.model_path) # save model - save_results(res_dic, tag='train', - path=cfg.result_path) - plot_rewards(res_dic['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'], cfg, tag="test") # 画出结果 - - - diff --git a/projects/codes/common/launcher.py b/projects/codes/common/launcher.py new file mode 100644 index 0000000..d26bce1 --- /dev/null +++ b/projects/codes/common/launcher.py @@ -0,0 +1,32 @@ +from common.utils import save_args,save_results,plot_rewards +class Launcher: + def __init__(self) -> None: + pass + def get_args(self): + cfg = {} + return cfg + def env_agent_config(self,cfg): + 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 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") diff --git a/projects/codes/envs/gridworld_env.py b/projects/codes/envs/gridworld_env.py index ae3f871..9d0724a 100644 --- a/projects/codes/envs/gridworld_env.py +++ b/projects/codes/envs/gridworld_env.py @@ -72,84 +72,6 @@ class FrozenLakeWapper(gym.Wrapper): self.move_player(x_pos, y_pos) -class CliffWalkingWapper(gym.Wrapper): - def __init__(self, env): - gym.Wrapper.__init__(self, env) - self.t = None - self.unit = 50 - self.max_x = 12 - self.max_y = 4 - - def draw_x_line(self, y, x0, x1, color='gray'): - assert x1 > x0 - self.t.color(color) - self.t.setheading(0) - self.t.up() - self.t.goto(x0, y) - self.t.down() - self.t.forward(x1 - x0) - - def draw_y_line(self, x, y0, y1, color='gray'): - assert y1 > y0 - self.t.color(color) - self.t.setheading(90) - self.t.up() - self.t.goto(x, y0) - self.t.down() - self.t.forward(y1 - y0) - - def draw_box(self, x, y, fillcolor='', line_color='gray'): - self.t.up() - self.t.goto(x * self.unit, y * self.unit) - self.t.color(line_color) - self.t.fillcolor(fillcolor) - self.t.setheading(90) - self.t.down() - self.t.begin_fill() - for i in range(4): - self.t.forward(self.unit) - self.t.right(90) - self.t.end_fill() - - def move_player(self, x, y): - self.t.up() - self.t.setheading(90) - self.t.fillcolor('red') - self.t.goto((x + 0.5) * self.unit, (y + 0.5) * self.unit) - - def render(self): - if self.t == None: - self.t = turtle.Turtle() - self.wn = turtle.Screen() - self.wn.setup(self.unit * self.max_x + 100, - self.unit * self.max_y + 100) - self.wn.setworldcoordinates(0, 0, self.unit * self.max_x, - self.unit * self.max_y) - self.t.shape('circle') - self.t.width(2) - self.t.speed(0) - self.t.color('gray') - for _ in range(2): - self.t.forward(self.max_x * self.unit) - self.t.left(90) - self.t.forward(self.max_y * self.unit) - self.t.left(90) - for i in range(1, self.max_y): - self.draw_x_line( - y=i * self.unit, x0=0, x1=self.max_x * self.unit) - for i in range(1, self.max_x): - self.draw_y_line( - x=i * self.unit, y0=0, y1=self.max_y * self.unit) - - for i in range(1, self.max_x - 1): - self.draw_box(i, 0, 'black') - self.draw_box(self.max_x - 1, 0, 'yellow') - self.t.shape('turtle') - - x_pos = self.s % self.max_x - y_pos = self.max_y - 1 - int(self.s / self.max_x) - self.move_player(x_pos, y_pos) - if __name__ == '__main__': # 环境1:FrozenLake, 可以配置冰面是否是滑的 diff --git a/projects/codes/envs/racetrack_env.py b/projects/codes/envs/racetrack.py similarity index 84% rename from projects/codes/envs/racetrack_env.py rename to projects/codes/envs/racetrack.py index e3a7413..69836d5 100644 --- a/projects/codes/envs/racetrack_env.py +++ b/projects/codes/envs/racetrack.py @@ -1,10 +1,3 @@ -# Please do not make changes to this file - it will be overwritten with a clean -# version when your work is marked. -# -# This file contains code for the racetrack environment that you will be using -# as part of the second part of the CM50270: Reinforcement Learning coursework. - -import imp import time import random import numpy as np @@ -12,23 +5,20 @@ import os import matplotlib.pyplot as plt import matplotlib.patheffects as pe from IPython.display import clear_output -from gym.spaces import Discrete +from gym.spaces import Discrete,Box from matplotlib import colors +import gym -class RacetrackEnv(object) : +class RacetrackEnv(gym.Env) : """ Class representing a race-track environment inspired by exercise 5.12 in Sutton & Barto 2018 (p.111). Please do not make changes to this class - it will be overwritten with a clean version when it comes to marking. The dynamics of this environment are detailed in this coursework exercise's jupyter notebook, although I have included rather verbose comments here for those of you who are interested in how the environment has been - implemented (though this should not impact your solution code). - - If you find any *bugs* with this code, please let me know immediately - thank you for finding them, sorry that I didn't! - However, please do not suggest optimisations - some things have been purposely simplified for readability's sake. + implemented (though this should not impact your solution code).ss """ - ACTIONS_DICT = { 0 : (1, -1), # Acc Vert., Brake Horiz. 1 : (1, 0), # Acc Vert., Hold Horiz. @@ -61,18 +51,15 @@ class RacetrackEnv(object) : for x in range(self.track.shape[1]) : if (self.CELL_TYPES_DICT[self.track[y, x]] == "start") : self.initial_states.append((y, x)) - + high= np.array([np.finfo(np.float32).max, np.finfo(np.float32).max, np.finfo(np.float32).max, np.finfo(np.float32).max]) + self.observation_space = Box(low=-high, high=high, shape=(4,), dtype=np.float32) self.action_space = Discrete(9) self.is_reset = False - #print("Racetrack Environment File Loaded Successfully.") - #print("Be sure to call .reset() before starting to initialise the environment and get an initial state!") - - def step(self, action : int) : """ Takes a given action in the environment's current state, and returns a next state, - reward, and whether the next state is terminal or not. + reward, and whether the next state is done or not. Arguments: action {int} -- The action to take in the environment's current state. Should be an integer in the range [0-8]. @@ -86,7 +73,7 @@ class RacetrackEnv(object) : A tuple of:\n {(int, int, int, int)} -- The next state, a tuple of (y_pos, x_pos, y_velocity, x_velocity).\n {int} -- The reward earned by taking the given action in the current environment state.\n - {bool} -- Whether the environment's next state is terminal or not.\n + {bool} -- Whether the environment's next state is done or not.\n """ @@ -131,7 +118,7 @@ class RacetrackEnv(object) : new_position = (self.position[0] + self.velocity[0], self.position[1] + self.velocity[1]) reward = 0 - terminal = False + done = False # If position is out-of-bounds, return to start and set velocity components to zero. if (new_position[0] < 0 or new_position[1] < 0 or new_position[0] >= self.track.shape[0] or new_position[1] >= self.track.shape[1]) : @@ -150,7 +137,7 @@ class RacetrackEnv(object) : elif (self.CELL_TYPES_DICT[self.track[new_position]] == "goal") : self.position = new_position reward += 10 - terminal = True + done = True # If this gets reached, then the student has touched something they shouldn't have. Naughty! else : raise RuntimeError("You've met with a terrible fate, haven't you?\nDon't modify things you shouldn't!") @@ -158,12 +145,12 @@ class RacetrackEnv(object) : # Penalise every timestep. reward -= 1 - # Require a reset if the current state is terminal. - if (terminal) : + # Require a reset if the current state is done. + if (done) : self.is_reset = False # Return next state, reward, and whether the episode has ended. - return (self.position[0], self.position[1], self.velocity[0], self.velocity[1]), reward, terminal + return np.array([self.position[0], self.position[1], self.velocity[0], self.velocity[1]]), reward, done,{} def reset(self) : @@ -184,10 +171,10 @@ class RacetrackEnv(object) : self.is_reset = True - return (self.position[0], self.position[1], self.velocity[0], self.velocity[1]) + return np.array([self.position[0], self.position[1], self.velocity[0], self.velocity[1]]) - def render(self, sleep_time : float = 0.1) : + def render(self, mode = 'human') : """ Renders a pretty matplotlib plot representing the current state of the environment. Calling this method on subsequent timesteps will update the plot. @@ -230,13 +217,9 @@ class RacetrackEnv(object) : # Draw everything. #fig.canvas.draw() #fig.canvas.flush_events() - plt.show() - - # Sleep if desired. - if (sleep_time > 0) : - time.sleep(sleep_time) - + # time sleep + time.sleep(0.1) def get_actions(self) : """ @@ -244,18 +227,16 @@ class RacetrackEnv(object) : of integers in the range [0-8]. """ return [*self.ACTIONS_DICT] +if __name__ == "__main__": + num_steps = 1000000 + env = RacetrackEnv() + state = env.reset() + print(state) + for _ in range(num_steps) : -# num_steps = 1000000 + next_state, reward, done,_ = env.step(random.choice(env.get_actions())) + print(next_state) + env.render() -# env = RacetrackEnv() -# state = env.reset() -# print(state) - -# for _ in range(num_steps) : - -# next_state, reward, terminal = env.step(random.choice(env.get_actions())) -# print(next_state) -# env.render() - -# if (terminal) : -# _ = env.reset() + if (done) : + _ = env.reset() diff --git a/projects/codes/envs/register.py b/projects/codes/envs/register.py new file mode 100644 index 0000000..d92a93d --- /dev/null +++ b/projects/codes/envs/register.py @@ -0,0 +1,34 @@ + +from gym.envs.registration import register + +def register_env(env_name): + if env_name == 'Racetrack-v0': + register( + id='Racetrack-v0', + entry_point='racetrack:RacetrackEnv', + max_episode_steps=1000, + kwargs={} + ) + elif env_name == 'FrozenLakeNoSlippery-v1': + register( + id='FrozenLakeNoSlippery-v1', + entry_point='gym.envs.toy_text.frozen_lake:FrozenLakeEnv', + kwargs={'map_name':"4x4",'is_slippery':False}, + ) + else: + print("The env name must be wrong or the environment donot need to register!") + +# if __name__ == "__main__": +# import random +# import gym +# env = gym.make('FrozenLakeNoSlippery-v1') +# num_steps = 1000000 +# state = env.reset() +# n_actions = env.action_space.n +# print(state) +# for _ in range(num_steps) : +# next_state, reward, done,_ = env.step(random.choice(range(n_actions))) +# print(next_state) +# if (done) : +# _ = env.reset() + \ No newline at end of file diff --git a/projects/codes/envs/wrappers.py b/projects/codes/envs/wrappers.py new file mode 100644 index 0000000..0baa03b --- /dev/null +++ b/projects/codes/envs/wrappers.py @@ -0,0 +1,78 @@ +import gym +class CliffWalkingWapper(gym.Wrapper): + def __init__(self, env): + gym.Wrapper.__init__(self, env) + self.t = None + self.unit = 50 + self.max_x = 12 + self.max_y = 4 + + def draw_x_line(self, y, x0, x1, color='gray'): + assert x1 > x0 + self.t.color(color) + self.t.setheading(0) + self.t.up() + self.t.goto(x0, y) + self.t.down() + self.t.forward(x1 - x0) + + def draw_y_line(self, x, y0, y1, color='gray'): + assert y1 > y0 + self.t.color(color) + self.t.setheading(90) + self.t.up() + self.t.goto(x, y0) + self.t.down() + self.t.forward(y1 - y0) + + def draw_box(self, x, y, fillcolor='', line_color='gray'): + self.t.up() + self.t.goto(x * self.unit, y * self.unit) + self.t.color(line_color) + self.t.fillcolor(fillcolor) + self.t.setheading(90) + self.t.down() + self.t.begin_fill() + for i in range(4): + self.t.forward(self.unit) + self.t.right(90) + self.t.end_fill() + + def move_player(self, x, y): + self.t.up() + self.t.setheading(90) + self.t.fillcolor('red') + self.t.goto((x + 0.5) * self.unit, (y + 0.5) * self.unit) + + def render(self): + if self.t == None: + self.t = turtle.Turtle() + self.wn = turtle.Screen() + self.wn.setup(self.unit * self.max_x + 100, + self.unit * self.max_y + 100) + self.wn.setworldcoordinates(0, 0, self.unit * self.max_x, + self.unit * self.max_y) + self.t.shape('circle') + self.t.width(2) + self.t.speed(0) + self.t.color('gray') + for _ in range(2): + self.t.forward(self.max_x * self.unit) + self.t.left(90) + self.t.forward(self.max_y * self.unit) + self.t.left(90) + for i in range(1, self.max_y): + self.draw_x_line( + y=i * self.unit, x0=0, x1=self.max_x * self.unit) + for i in range(1, self.max_x): + self.draw_y_line( + x=i * self.unit, y0=0, y1=self.max_y * self.unit) + + for i in range(1, self.max_x - 1): + self.draw_box(i, 0, 'black') + self.draw_box(self.max_x - 1, 0, 'yellow') + self.t.shape('turtle') + + x_pos = self.s % self.max_x + y_pos = self.max_y - 1 - int(self.s / self.max_x) + self.move_player(x_pos, y_pos) \ No newline at end of file diff --git a/projects/codes/scripts/Qlearning_task1.sh b/projects/codes/scripts/Qlearning_task1.sh index 57cc23d..fadb1a6 100644 --- a/projects/codes/scripts/Qlearning_task1.sh +++ b/projects/codes/scripts/Qlearning_task1.sh @@ -11,4 +11,5 @@ else 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 FrozenLake-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 +python $codes_dir/envs/register.py # register environment +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/Sarsa_task0.sh b/projects/codes/scripts/Sarsa_task0.sh new file mode 100644 index 0000000..49358de --- /dev/null +++ b/projects/codes/scripts/Sarsa_task0.sh @@ -0,0 +1,13 @@ +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/envs/register.py # register environment +python $codes_dir/Sarsa/main.py \ No newline at end of file