强化学习-价值迭代代码实现
1. 前言
上一篇博客我们介绍了价值迭代的原理。这一节我们实现强化学习里面的价值迭代的部分代码(完整代码GitHub)。
2. 价值迭代回顾
我们把注意点放在值函数上,等值函数收敛了,我们的策略也会收敛到最优值。
\[v^{T+1}(s) =max_{a} \sum_{s_{t+1}}p(s_{t+1}|s_t,a_t)[r_{a_t}^{s_{t+1}} + \gamma * v^T_{\pi}(s_{t+1})]
\]
再对收敛值函数算状态-行动值函数,通过状态-行动值函数寻找最好的那个策略。这个步骤和策略迭代一样,属于策略提升,不同的是,价值迭代只要计算一次就能拿到最好的策略。
\[q^T_{\pi}(s_t,a_t)=\sum_{s_{t+1}}p(s_{t+1}|s_t,a_t)[r_{a_t}^{s_{t+1}} + \gamma * v^T_{\pi}(s_{t+1})]\;\;\;\;\;\;(2)
\]
\[\pi^{T+1}(s) = argmax_aq^T_{\pi}(s,a)\;\;\;\;\;\;(3)
\]
实现代码:
class ValueIteration(object):
def value_iteration(self, agent, max_iter=-1):
"""
:param obj agent: 智能体
:param int max_iter: 最大迭代数
"""
iteration = 0
while True:
iteration += 1
# 保存算出的值函数
new_value_pi = np.zeros_like(agent.value_pi)
for i in range(1, agent.s_len):
value_sas = []
for j in range(0, agent.a_len):
# 对每一个状态s和行动a,计算值函数
value_sa = np.dot(agent.p[j, i, :], agent.r + agent.gamma * agent.value_pi)
value_sas.append(value_sa)
# 从每个行动中,选出最好的值函数
new_value_pi[i] = max(value_sas)
# 前后2次值函数的变化小于一个阈值,结束
diff = np.sqrt(np.sum(np.power(agent.value_pi - new_value_pi, 2)))
if diff < 1e-6:
break
else:
agent.value_pi = new_value_pi
if iteration == max_iter:
break
print('Iter {} rounds converge'.format(iteration))
for i in range(1, agent.s_len):
for j in range(0, agent.a_len):
# 计算收敛后值函数的状态-行动值函数
agent.value_q[i, j] = np.dot(agent.p[j, i, :], agent.r + agent.gamma * agent.value_pi)
# 取出最大的行动
max_act = np.argmax(agent.value_q[i, :])
agent.pi[i] = max_act
3. 总结
到现在为止,我们介绍完了强化学习中的两个基本的最优策略算法。策略迭代和价值迭代。
但一个可悲的事实是,在很多实际问题中,我们无法得到游戏的全貌,也就是说,状态转移的信息\(P(s_{t+1}|s_t, a_t)\)无法获得。
一般来说,我们知晓状态转移概率的问题称为“基于模型”的问题(Model-based),将不知晓的称为“无模型”问题(Model-free)。后面我们要继续升级我们的问题,模拟一个真人去玩游戏,无法知道所有游戏的全貌。