使用 Q-Table 进行 Q-Learning
您可以在ch-13b.ipynb
中按照本节的代码进行操作。 由于我们的离散空间的尺寸为[10,10,10,10],因此我们的 Q 表的尺寸为[10,10,10,10,2]:
# create a Q-Table of shape (10,10,10,10, 2) representing S X A -> R
q_table = np.zeros(shape = np.append(n_s,n_a))
我们根据exploration_rate
定义了一个利用或探索的 Q-Table 策略:
def policy_q_table(state, env):
# Exploration strategy - Select a random action
if np.random.random() < explore_rate:
action = env.action_space.sample()
# Exploitation strategy - Select the action with the highest q
else:
action = np.argmax(q_table[tuple(state)])
return action
定义运行单个剧集的episode()
函数,如下所示:
- 首先初始化变量和第一个状态:
obs = env.reset()
state_prev = discretize_state(obs,s_bounds,n_s)
episode_reward = 0
done = False
t = 0
- 选择操作并观察下一个状态:
action = policy(state_prev, env)
obs, reward, done, info = env.step(action)
state_new = discretize_state(obs,s_bounds,n_s)
- 更新 Q 表:
best_q = np.amax(q_table[tuple(state_new)])
bellman_q = reward + discount_rate * best_q
indices = tuple(np.append(state_prev,action))
q_table[indices] += learning_rate*( bellman_q - q_table[indices])
- 将下一个状态设置为上一个状态,并将奖励添加到剧集的奖励中:
state_prev = state_new
episode_reward += reward
experiment()
函数调用剧集函数并累积报告奖励。您可能希望修改该函数以检查连续获胜以及特定于您的游戏或游戏的其他逻辑:
# collect observations and rewards for each episode
def experiment(env, policy, n_episodes,r_max=0, t_max=0):
rewards=np.empty(shape=[n_episodes])
for i in range(n_episodes):
val = episode(env, policy, r_max, t_max)
rewards[i]=val
print('Policy:{}, Min reward:{}, Max reward:{}, Average reward:{}'
.format(policy.__name__,
np.min(rewards),
np.max(rewards),
np.mean(rewards)))
现在,我们要做的就是定义参数,例如learning_rate
,discount_rate
和explore_rate
,并运行experiment()
函数,如下所示:
learning_rate = 0.8
discount_rate = 0.9
explore_rate = 0.2
n_episodes = 1000
experiment(env, policy_q_table, n_episodes)
对于 1000 集,基于我们的简单实现,基于 Q-Table 的策略的最大奖励为 180:
Policy:policy_q_table, Min reward:8.0, Max reward:180.0, Average reward:17.592
我们对算法的实现很容易解释。但是,您可以对代码进行 od odify 以将探索率设置为最初,然后随着时间步长的过去而衰减。同样,您还可以实现学习和折扣率的衰减逻辑。让我们看看,由于我们的 Q 函数学得更快,我们是否可以用更少的剧集获得更高的奖励。