强化学习(reinforcement learning)的过程,强化学习中有状态(state)、动作(action)、奖赏(reward)这三个要素。
智能体需要根据当前状态来采取动作,获得相应的奖赏之后,再去改进这些动作,使得下次再到相同状态时,智能体能做出更优的动作。
下面以一个综合全面的例子来理解Q-learning的过程。
http://mnemstudio.org/path-finding-q-learning-tutorial.htm
https://github.com/JasonQSY/ML-Weekly/blob/master/P5-Reinforcement-Learning/Q-learning/Q-Learning-Get-Started.ipynb
如上图是一个房间结构,一个robot(Agent, 智能体)初始可能在0-4中的任何一个房间,目的达到5这个外部空间,可以理解为出去这个建筑物, 如何能够无论初始在哪个房间都能最快的出去?
如上图是图1的简化,其中0-5为状态,箭头指向表示动作, 箭头上的之值表示这个动作的reward值。初始状态全为0。
注意 Q矩阵跟R矩阵是不同的,R矩阵表示转态到action的reward值, 而Q矩阵表示在当前 state 和 action的情况下,整体的回报值(会看完全部的路径)。
Q-learning 算法的转移规则比较简单,Q矩阵的更新:
Q(state, action) = R(state, action) + Gamma * Max[Q(next state, all actions)]
其中当前state 和 action 的 回报 等于, 当前的state 采取 action 的reward值,可以直接从表中读出。
然后Gamma是折扣因子,表示时间的远近对回报的影响程度,为0表示之看当前状态采取行动的reward。
Max[Q(next state, all actions)] 是一个递归函数,表示一直看到所有的情况,最后选择一个目前回报最佳的路经。
epsilon-greedy 表示: Epsilon greedy 是用在决策上的一种策略, 比如 epsilon = 0.9 时, 就说明有90% 的情况我会按照 Q 表的最优值选择行为, 10% 的时间使用随机选行为.
手动演算几个 episode ,超参数 Gamma=0.8, epsilon-greedy中epsilon=0.4.
Episode=1:
随机选择状态是 state=1,首先确定 action, 在转态1的时候可能的动作有3和5,刚开始初始值都一样,随机选择为 state5. 在状态5的时候可能的动作为1,4,5,这时候可以计算 Q(1,5)的值:
Q(1,5) = R(1,5) + 0.8 * max{Q{5,1}, Q(5,4), Q(5,5)} = 100 + 0 = 100.
此时 state5是目标state,那么更新Q矩阵,仅 更新 Q(1,5) = 100。
Episode=2:
随机选择状态是 state=3,首先确定 action, 在转态1的时候可能的动作有1,2,4,选择max{Q(3,1), Q{3,2}, Q(3,4)} ,三个值都是0,选择action1,那么state变成1,在状态1的时候可能的动作为3,5,这时候可以计算 Q(3,1)的值:
Q(3,1) = R(3,1) + 0.8 * max{Q(1,3), Q(1,5)} = 0 + 80 = 80, 更新 Q(3,1) = 80。
但此时state1还不是最终状态5, 所以还的继续探索。
此时假设还是选择最优策略,确定action,Q(1,action) = max{Q(1,3), Q(1,5)}, 选择action=5,那么进入状态5,同前面一样 Q(1,5) = R(1,5) + 0.8 * max{Q{5,1}, Q(5,4), Q(5,5)} = 100 + 0 = 100. 更新 Q(1,5) = 100
就这样一直迭代下去, 整个过程由于两个超参数,结果是不可预估的。
Code:
import numpy as np
# Q 矩阵初始化为0
q = np.matrix(np.zeros([6, 6]))
# Reward 矩阵为提前定义好的。 类似与HMM的生成矩阵。-1表示无相连接的边
r = np.matrix([[-1, -1, -1, -1, 0, -1],
[-1, -1, -1, 0, -1, 100],
[-1, -1, -1, 0, -1, -1],
[-1, 0, 0, -1, 0, -1],
[ 0, -1, -1, 0, -1, 100],
[-1, 0, -1, -1, 0, 100]])
# hyperparameter
#折扣因子
gamma = 0.8
#是否选择最后策略的概率
epsilon = 0.4
# the main training loop
for episode in range(101):
# random initial state
state = np.random.randint(0, 6)
# 如果不是最终转态
while (state != 5):
# 选择可能的动作
# Even in random case, we cannot choose actions whose r[state, action] = -1.
possible_actions = []
possible_q = []
for action in range(6):
if r[state, action] >= 0:
possible_actions.append(action)
possible_q.append(q[state, action])
# Step next state, here we use epsilon-greedy algorithm.
action = -1
if np.random.random() < epsilon:
# choose random action
action = possible_actions[np.random.randint(0, len(possible_actions))]
else:
# greedy
action = possible_actions[np.argmax(possible_q)]
# Update Q value
q[state, action] = r[state, action] + gamma * q[action].max()
# Go to the next state
state = action
# Display training progress
if episode % 10 == 0:
print("------------------------------------------------")
print("Training episode: %d" % episode)
print(q)