对于结合神经网络的标准Q学习来说,事情或多或少是比较简单的。在与环境交互时存储(s,a,r,s’),并使用
target = Qnew(s,a) = (1 - alpha) * Qold(s,a) + alpha * ( r + gamma * max_{a’} Qold(s’, a’) )
作为神经网络逼近Q函数的目标值。因此,ANN的输入是(s,a),输出是标量Qnew(s,a)。深度Q学习的论文/教程改变了Q函数的结构。它不再为状态-动作对(s,a)提供单一的Q值,而是应该为状态s提供所有可能动作的Q值,所以是Q(s)而不是Q(s,a)。
这就引出了我的问题。对于特定的状态s,数据库中填充的(s,a,r,s’)并不包含所有动作的奖励。可能只包含某些动作的奖励,甚至可能只有一个动作的奖励。那么,如何在没有状态s的所有奖励数据的情况下,为网络Q(s) = [Q(a_1), …. , Q(a_n) ]
设置目标值呢?我见过不同的损失函数/目标值,但所有这些都包含奖励。
如您所见,我很困惑。有人能帮我吗?网上有很多教程,但这一步通常描述得不够详细,甚至在理论上也没有充分的动机说明…
回答:
您只需获取与观察s,a,r,s'
中存在的动作对应的目标值。基本上,您会获取所有动作的目标值,然后选择其中的最大值,正如您自己写的:max_{a'} Qold(s', a')
。然后,将其与r(s,a)相加,结果就是目标值。例如,假设您有10个动作,观察结果是(s_0, a=5, r(s_0,a=5)=123, s_1)
。那么,目标值是r(s_0,a=5)+ \gamma* \max_{a'} Q_target(s_1,a')
。例如,使用tensorflow
,它可能是这样的:
Q_Action = tf.reduce_sum(tf.multiply(Q_values,tf.one_hot(action,output_dim)), axis = 1) # dim: [batchSize , ]
其中Q_values
的大小是batchSize, output_dim
。因此,输出是一个大小为batchSize
的向量,然后存在一个相同大小的向量作为目标值。损失是它们差异的平方。
在计算损失值时,您也只对现有动作进行反向传播,其他动作的梯度为零。因此,您只需要现有动作的奖励。