update codes

This commit is contained in:
johnjim0816
2021-12-28 18:46:52 +08:00
parent 41fb561d25
commit bd51b5a7ad
52 changed files with 305 additions and 292 deletions

View File

@@ -6,7 +6,7 @@
<img src="../../easy_rl_book/res/ch12/assets/pendulum_1.png" alt="image-20210915161550713" style="zoom:50%;" />
该环境的状态有三个,设摆针竖直方向上的顺时针旋转角为$\theta$$\theta$设在$[-\pi,\pi]$之间,则相应的状态为$[cos\theta,sin\theta,\dot{\theta}]$,即表示角度和角速度,我们的动作则是一个-2到2之间的力矩它是一个连续量因而该环境不能用离散动作的算法比如 DQN 来解决。关于奖励是根据相关的物理原理而计算出的等式,如下:
该环境的状态维度有三个,设摆针竖直方向上的顺时针旋转角为$\theta$$\theta$设在$[-\pi,\pi]$之间,则相应的状态为$[cos\theta,sin\theta,\dot{\theta}]$,即表示角度和角速度,我们的动作则是一个-2到2之间的力矩它是一个连续量因而该环境不能用离散动作的算法比如 DQN 来解决。关于奖励是根据相关的物理原理而计算出的等式,如下:
$$
-\left(\theta^{2}+0.1 * \hat{\theta}^{2}+0.001 * \text { action }^{2}\right)
$$
@@ -90,15 +90,15 @@ class OUNoise(object):
self.max_sigma = max_sigma
self.min_sigma = min_sigma
self.decay_period = decay_period
self.n_actions = action_space.shape[0]
self.action_dim = action_space.shape[0]
self.low = action_space.low
self.high = action_space.high
self.reset()
def reset(self):
self.obs = np.ones(self.n_actions) * self.mu
self.obs = np.ones(self.action_dim) * self.mu
def evolve_obs(self):
x = self.obs
dx = self.theta * (self.mu - x) + self.sigma * np.random.randn(self.n_actions)
dx = self.theta * (self.mu - x) + self.sigma * np.random.randn(self.action_dim)
self.obs = x + dx
return self.obs
def get_action(self, action, t=0):

View File

@@ -14,21 +14,21 @@ CartPole-v0是一个经典的入门环境如下图它通过向左(动作=0
import gym
env = gym.make('CartPole-v0') # 建立环境
env.seed(1) # 随机种子
n_states = env.observation_space.shape[0] # 状态
n_actions = env.action_space.n # 动作
state_dim = env.observation_space.shape[0] # 状态维度
action_dim = env.action_space.n # 动作维度
state = env.reset() # 初始化环境
print(f"状态{n_states},动作{n_actions}")
print(f"状态维度{state_dim},动作维度{action_dim}")
print(f"初始状态:{state}")
```
可以得到结果:
```bash
状态4动作2
状态维度4动作维度2
初始状态:[ 0.03073904 0.00145001 -0.03088818 -0.03131252]
```
该环境状态是四个,分别为车的位置、车的速度、杆的角度以及杆顶部的速度,动作为两个并且是离散的向左或者向右。理论上达到最优化算法的情况下推车杆是一直能保持平衡的也就是每回合的步数是无限但是这不方便训练所以环境内部设置了每回合的最大步数为200也就是说理想情况下只需要我们每回合的奖励达到200就算训练完成。
该环境状态维度是四个,分别为车的位置、车的速度、杆的角度以及杆顶部的速度,动作维度为两个并且是离散的向左或者向右。理论上达到最优化算法的情况下推车杆是一直能保持平衡的也就是每回合的步数是无限但是这不方便训练所以环境内部设置了每回合的最大步数为200也就是说理想情况下只需要我们每回合的奖励达到200就算训练完成。
## DQN基本接口
@@ -125,7 +125,7 @@ class ReplayBuffer:
class MLP(nn.Module):
def __init__(self, input_dim,output_dim,hidden_dim=128):
""" 初始化q网络为全连接网络
input_dim: 输入的特征数即环境的状态
input_dim: 输入的特征数即环境的状态维度
output_dim: 输出的动作维度
"""
super(MLP, self).__init__()
@@ -157,7 +157,7 @@ def choose_action(self, state):
q_values = self.policy_net(state)
action = q_values.max(1)[1].item() # 选择Q值最大的动作
else:
action = random.randrange(self.n_actions)
action = random.randrange(self.action_dim)
```
可以看到跟Q学习算法其实是一样的都是用的$\epsilon-greedy$策略只是使用神经网络的话我们需要通过Torch或者Tensorflow工具来处理相应的数据。

View File

@@ -27,21 +27,21 @@ env = gym.make('CliffWalking-v0') # 定义环境
env = CliffWalkingWapper(env) # 装饰环境
```
这里我们在程序中使用了一个装饰器重新定义环境但不影响对环境的理解感兴趣的同学具体看相关代码。可以由于gym环境封装得比较好所以我们想要使用这个环境只需要使用gym.make命令输入函数名即可然后我们可以查看环境的状态和动作目:
这里我们在程序中使用了一个装饰器重新定义环境但不影响对环境的理解感兴趣的同学具体看相关代码。可以由于gym环境封装得比较好所以我们想要使用这个环境只需要使用gym.make命令输入函数名即可然后我们可以查看环境的状态和动作维度目:
```python
n_states = env.observation_space.n # 状态
n_actions = env.action_space.n # 动作
print(f"状态{n_states},动作{n_actions}")
state_dim = env.observation_space.n # 状态维度
action_dim = env.action_space.n # 动作维度
print(f"状态维度{state_dim},动作维度{action_dim}")
```
打印出来的结果如下:
```bash
状态48动作4
状态维度48动作维度4
```
我们的状态是48个这里我们设置的是智能体当前所在网格的编号而动作是4这表示有0123对应着上下左右四个动作。另外我们也可以初始化环境并打印当前所在的状态
我们的状态维度是48个这里我们设置的是智能体当前所在网格的编号而动作维度是4这表示有0123对应着上下左右四个动作。另外我们也可以初始化环境并打印当前所在的状态
```python
state = env.reset()
@@ -72,9 +72,9 @@ print(state)
env = gym.make('CliffWalking-v0') # 定义环境
env = CliffWalkingWapper(env) # 装饰环境
env.seed(1) # 设置随机种子
n_states = env.observation_space.n # 状态
n_actions = env.action_space.n # 动作
agent = QLearning(n_states,n_actions,cfg) # cfg存储算法相关参数
state_dim = env.observation_space.n # 状态维度
action_dim = env.action_space.n # 动作维度
agent = QLearning(state_dim,action_dim,cfg) # cfg存储算法相关参数
for i_ep in range(cfg.train_eps): # cfg.train_eps表示最大训练的回合数
ep_reward = 0 # 记录每个回合的奖励
state = env.reset() # 重置环境
@@ -126,7 +126,7 @@ def choose_action(self, state):
if np.random.uniform(0, 1) > self.epsilon:
action = np.argmax(self.Q_table[str(state)]) # 选择Q(s,a)最大对应的动作
else:
action = np.random.choice(self.n_actions) # 随机选择动作
action = np.random.choice(self.action_dim) # 随机选择动作
return action
```