如何找出策略迭代的值?

时间:2018-07-07 09:50:11

标签: python machine-learning reinforcement-learning markov

我的老师提出了以下问题: 考虑以下具有3个状态和奖励的MDP。有两种可能的操作-红色和蓝色。在边缘给出状态转移概率,并且S2是终端状态。假设初始策略为:π(S0)= B; π(S1)=R。 MDP

我们被问到最优策略是什么γ值(0 <γ<1):

(a)π∗(S0)= R; π∗(S1)= B;

(b)π∗(S0)= B; π∗(S1)= R;

(c)π∗(S0)= R; π∗(S1)= R;

我已经证明,对于(a),答案是γ= 0.1,并且找不到(b)和(c)的γ值。老师说,对于(b),任何γ> 0.98都是有效的,对于(c)γ= 0.5。我认为他错了,并且写了the following python script,它遵循教科书中的算法(Russell和Norvig AIMA),实际上对于任何γ值,我得到的唯一策略是(a)。但是老师说他没错,我的剧本一定是马车。我怎么能肯定地表明这种政策是不可能的?

S0 = "S0"
S1 = "S1"
S2 = "S2"
BLUE = "blue"
RED = "red"
gamma = 0.5  # TODO MODIFY GAMMA HERE

# P(s'|s,a)
P_destination_start_action = \
{
(S0,S0, BLUE):0.5,(S0,S0,RED):0.9, (S0,S1,BLUE):0.8,(S0,S1,RED):0, (S0,S2, BLUE):0,(S0,S2,RED):0,
(S1,S0, BLUE):0.5,(S1,S0,RED):0, (S1,S1,BLUE):0.2,(S1,S1,RED):0.6, (S1,S2, BLUE):0,(S1,S2,RED):0,
(S2,S0, BLUE):0, (S2,S0,RED):0.1, (S2,S1,BLUE):0  ,(S2,S1,RED):0.4,(S2,S2, BLUE):1,(S2,S2,RED):1
}

class MDP:
    def __init__(self):
        self.states = [S0, S1, S2]
        self.actions = [BLUE, RED]


        self.P_dest_start_action = P_destination_start_action
        self.rewards = {S0: -2, S1: -5, S2: 0}

def POLICY_EVALUATION(policy_vec, utility_vec, mdp):
    new_utility_vector = {}
    for s in mdp.states:
        to_sum = [(mdp.P_dest_start_action[(s_tag, s, policy_vec[s])] * utility_vec[s_tag])
                  for s_tag in mdp.states]
        new_utility_vector[s] = mdp.rewards[s] + gamma * sum(to_sum)
    return new_utility_vector

def POLICY_ITERATION(mdp):
    utility_vector = {state: 0 for state in mdp.states}
    policy_vector = {S0: BLUE, S1: RED, S2: RED}
    unchanged = False

    while not unchanged:
        utility_vector = POLICY_EVALUATION(policy_vector, utility_vector, mdp)
        unchanged = True
        for s in mdp.states:
            BLUE_sum = sum([(mdp.P_dest_start_action[(s_tag, s, BLUE)] * utility_vector[s_tag])
                            for s_tag in mdp.states])
            RED_sum = sum([(mdp.P_dest_start_action[(s_tag, s, RED)] * utility_vector[s_tag])
                           for s_tag in mdp.states])
            if policy_vector[s] == RED and BLUE_sum > RED_sum:
                policy_vector[s] = BLUE
                unchanged = False

            elif policy_vector[s] == BLUE and RED_sum > BLUE_sum:
                policy_vector[s] = RED
                unchanged = False

    return policy_vector

if __name__ == "__main__":
    Q2_mdp = MDP()
    new_policy_vec = POLICY_ITERATION(Q2_mdp)
    print("===========================END===============================")
    print("S_O policy =", new_policy_vec[S0], " ,S_1 Policy =", new_policy_vec[S1])

1 个答案:

答案 0 :(得分:1)

您的老师似乎(大部分)是正确的。

这似乎不一定是必须以编程方式解决的问题,也可以通过数学方式解决(这可能是您的老师所做的事情,以及为什么他说您的代码必须在不查看的情况下进行错误处理)。

基于数学的解决方案

V(S, C)表示在状态C下选择颜色S的值。对于所有颜色V(S2, C) = 0,我们都有一个C

V(S0, R)V(S1, R)中写下用于选择红色动作的真实值S0S1很容易,因为它们不依赖于值其他任何状态(从技术上讲,它们的确取决于S2的值,但是这些值为0,因此我们可以将它们忽略):

  • V(S0, R) = 0.9 * (-2 + gamma * V(S0, R))
  • V(S1, R) = 0.6 * (-5 + gamma * V(S1, R))

通过一些算术运算,可以将它们重写为:

  • V(S0, R) = -1.8 / (1 - 0.9 * gamma)
  • V(S1, R) = -3 / (1 - 0.6 * gamma)

观察到在两个状态BS0中都选择S1(蓝色)的策略永远不会是最优的,这也很有用。这样的政策永远不会达到S2,而只会继续收集无数的负面奖励。

认识到这一点,我们可以轻松地用V(S0, B)V(S0, B)来写V(S1, R)。我们不必考虑值V(S1, B)中的V(S0, B)项,因为在考虑以下情况时,最好不要在B中玩S1也已经在B中玩过S0

V(S0, B) = 0.5 * (-2 + gamma * V(S0, B)) + 0.5 * (-5 + gamma * V(S1, R))

它简化为:

V(S0, B) = -3.5 + 0.5 * gamma * V(S0, B) + 0.5 * gamma * (-3 / (1 - 0.6 * gamma))

现在我们对V(S0, R)V(S0, B)有很好的表达式,我们可以从另一个中减去一个表达式:如果表达式V(S0, B) - V(S0, R)为正,则最佳策略将发挥{{1} B中的}。如果为负,则将播放S0

通过更多的算术运算,现在应该有可能解决像R这样的不等式。一个更简单的解决方案(尽管您的老师可能不希望您尝试考试)是将两个值(= V(S0, B) > V(S0, R))的推论插入Google并查看情节与{{1 }}轴:位于(-3.5 + (-1.5x / (1 - 0.6x))) / (1 - 0.5x) + (1.8 / (1 - 0.9x))(例如x)处。因此,看来您的老师在该解决方案(b)实际上适用于任何x = 0.96而不是任何gamma = 0.96的情况下犯了一个小错误。

当然,相同的推理和算术方法也可以用于我尚未考虑的其他值函数,例如gamma > 0.96


基于编程的解决方案

关于为什么您的基于编程的解决方案不起作用的原因,确实确实存在一个小错误。在政策评估步骤中,您仅循环浏览所有状态一次。可能需要连续多个这样的循环。看看Russel和Norvig的书中确实提到了 Value Iteration 的修改版本可以用于此功能,该功能本身一直循环运行,直到实用程序几乎不变为止。

根据萨顿和巴托的《强化学习》一书中的伪代码,可以将“策略评估”功能固定如下:

gamma > 0.98

进行此更改后,实际上,例如,您将获得

V(S1, B)

作为def POLICY_EVALUATION(policy_vec, utility_vec, mdp): new_utility_vector = utility_vec delta = 100000.0 while delta > 0.00001: delta = 0.0 for s in mdp.states: old_vs = {s: new_utility_vector[s] for s in new_utility_vector} to_sum = [(mdp.P_dest_start_action[(s_tag, s, policy_vec[s])] * new_utility_vector[s_tag]) for s_tag in mdp.states] new_utility_vector[s] = mdp.rewards[s] + gamma * sum(to_sum) delta = max(delta, max([abs(new_utility_vector[s] - old_vs[s]) for s in old_vs])) return new_utility_vector 的输出(不只是===========================END=============================== ('S_O policy =', 'blue', ' ,S_1 Policy =', 'red') ),这是基于基于数学的解决方案所期望的。