通过前面的几篇文章可以知道,当我们要用 Q-learning 解决一个问题时,首先需要知道这个问题有多少个 state,每个 state 有多少 action,并且建立一个奖励表格 P,维度是 action * 4,这4列分别标记着采取每个 action 的概率,采取每个 action 下一步会到达的 new state,采取每个 action 会获得的奖励,以及游戏是否结束。
Q-learning 会先建立一个全是 0 的 Q-table,此时agent对环境一无所知,会先进行探索,就是随机选择一个 state,随机选择一个 action,这样通过表格 P,就能得到下一个状态,以及此时的奖励,于是由 Q-function 可以计算出这对 state-action 组合的 Q-value,进而 Q-table 得到更新。
一直重复上述过程,当 agent 对环境有一定的了解后,即 Q-table 有了一些数值后,就可以利用环境,即在选择 action 时不是随机选取,而是选择 Q-table 中当前 state 下所有 action 中选择 Q-value 最大的那个 action,用这对 state-action 得到的下一步状态和奖励来更新 Q-table。
重复上述的过程,最后得到一个收敛的 Q-table,然后就可以用查表的方法查看在每个状态时选哪个 action 会更好呢。
上面的思路用代码写出来就是:
代码语言:javascript复制!pip install cmake 'gym[atari]' scipy
import gym
env = gym.make("Taxi-v2").env
env.render()
import numpy as np
q_table = np.zeros([env.observation_space.n, env.action_space.n])
%%time
"""Training the agent"""
import random
from IPython.display import clear_output
# Hyperparameters
alpha = 0.1
gamma = 0.6
epsilon = 0.1
# For plotting metrics
all_epochs = []
all_penalties = []
for i in range(1, 100001):
state = env.reset()
epochs, penalties, reward, = 0, 0, 0
done = False
while not done:
if random.uniform(0, 1) < epsilon:
action = env.action_space.sample() # Explore action space
else:
action = np.argmax(q_table[state]) # Exploit learned values
next_state, reward, done, info = env.step(action)
old_value = q_table[state, action]
next_max = np.max(q_table[next_state])
new_value = (1 - alpha) * old_value alpha * (reward gamma * next_max)
q_table[state, action] = new_value
if reward == -10:
penalties = 1
state = next_state
epochs = 1
if i % 100 == 0:
clear_output(wait=True)
print(f"Episode: {i}")
print("Training finished.n")
q_table[328]
参考文献 https://www.learndatasci.com/tutorials/reinforcement-q-learning-scratch-python-openai-gym/