为什么我的值字典需要浅拷贝才能正确更新?

我在使用Python 2.7.11开发一个Agent类,该类使用马尔可夫决策过程(MDP)在GridWorld中搜索最优策略π。我正在实现一个基本的价值迭代,用于对所有GridWorld状态进行100次迭代,使用以下贝尔曼方程:

enter image description here

  • T(s,a,s’)是从当前状态s通过采取行动a成功过渡到后续状态s’的概率函数。
  • R(s,a,s’)是从s过渡到s’的奖励。
  • γ(gamma)是折扣因子,其中0 ≤ γ ≤ 1
  • Vk(s’)是在达到s’后重复计算的递归调用。
  • Vk+1(s)表示经过足够的k次迭代后,Vk迭代值将收敛并与Vk+1等价。

这个方程是从取Q值函数的最大值中得出的,这是我在程序中使用的:

enter image description here

在构建我的Agent时,会传入一个MDP,这是一个包含以下方法的抽象类:

# 返回GridWorld中的所有状态def getStates()# 返回给定当前状态下代理可以采取的所有合法行动def getPossibleActions(state)# 返回从当前状态通过给定行动可以过渡到的所有可能的后续状态,以及采取该行动达到每个状态的概率def getTransitionStatesAndProbs(state, action)# 返回从当前状态到后续状态的奖励def getReward(state, action, nextState)

我的Agent还被传入一个折扣因子和迭代次数。我还使用了一个字典来跟踪我的值。以下是我的代码:

class IterationAgent:    def __init__(self, mdp, discount = 0.9, iterations = 100):        self.mdp = mdp        self.discount = discount        self.iterations = iterations        self.values = util.Counter() # Counter是一个默认值为0的字典        for transition in range(0, self.iterations, 1):            states = self.mdp.getStates()            valuesCopy = self.values.copy()            for state in states:                legalMoves = self.mdp.getPossibleActions(state)                convergedValue = 0                for move in legalMoves:                    value = self.computeQValueFromValues(state, move)                    if convergedValue <= value or convergedValue == 0:                        convergedValue = value                valuesCopy.update({state: convergedValue})            self.values = valuesCopy    def computeQValueFromValues(self, state, action):        successors = self.mdp.getTransitionStatesAndProbs(state, action)        reward = self.mdp.getReward(state, action, successors)        qValue = 0        for successor, probability in successors:            # Q值方程:Q*(a,s) = T(s,a,s')[R(s,a,s') + gamma(V*(s'))]            qValue += probability * (reward + (self.discount * self.values[successor]))        return qValue

这个实现是正确的,但我不知道为什么需要valuesCopy来成功更新我的self.values字典。我尝试了以下方法来省略拷贝,但它不起作用,因为它返回了略有错误的值:

for i in range(0, self.iterations, 1):    states = self.mdp.getStates()    for state in states:        legalMoves = self.mdp.getPossibleActions(state)        convergedValue = 0        for move in legalMoves:            value = self.computeQValueFromValues(state, move)            if convergedValue <= value or convergedValue == 0:                convergedValue = value        self.values.update({state: convergedValue})

我的问题是,为什么在每次迭代中valuesCopy = self.values.copy()都会对字典进行拷贝的情况下,还需要包含self.values字典的拷贝来正确更新我的值?难道在原始字典中更新值不会产生相同的更新结果吗?


回答:

是否使用拷贝在算法上是有区别的:

# 你在这里更新你的拷贝,所以原始的将保持不变,这与没有拷贝的情况不同valuesCopy.update({state: convergedValue})# 如果你有拷贝,你将在这里使用存储在self.value中的旧值,而不是更新后的值qValue += probability * (reward + (self.discount * self.values[successor]))

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注