该算法(或至少是它的一个版本,在Coursera RL 顶点项目中实现)如下:
创建一个重放“缓冲区”,用于存储最后的#buffer_size
SARS(状态、动作、奖励、新状态)体验。
运行你的代理,让它在重放缓冲区中积累经验,直到它(缓冲区)至少有#batch_size
经验。
- 您可以根据特定策略选择动作(例如,离散动作空间的 soft-max,连续动作空间的高斯等)在您的 Q^(s,a;θ) 函数估计器。
一旦达到#batch_size
或更多:
制作函数估计器的副本(Q^(s,a;θ)) 在当前时间,即权重的副本 θ - 您“冻结”而不更新,并用于计算“真实”状态 Q^(s′,a′;θ). 运行num_replay
更新:
回放缓冲区中的示例#batch_size
体验。
使用采样经验对您的函数估计器进行批量更新(例如,在 Q-Learning 中Q^(s,a)=神经网络 - 更新网络的权重)。使用冻结权重作为“真实”动作值函数,但继续改进非冻结函数。
这样做直到你达到一个终端状态。
不要忘记不断将新体验附加到 Replay Buffer
根据需要运行尽可能多的剧集。
我所说的“真实”是什么意思:每次体验都可以被认为是“监督”学习二重奏,你有一个真实的价值函数Q(s,a)和一个函数估计器Q^(s,a). 您的目标是减少价值错误,例如∑(Q(s,a)−Q^(s,a))2. 由于您可能无法访问真正的动作值,因此您可以使用最后一个估计器的自举改进版本,同时考虑到新的经验和给予的奖励。在 Q-learning 中,“真正的”行动价值是Q(s,a)=Rt+1+γmaxa′Q^(s′,a′;θ) 在哪里 R 是奖励和 γ 是折扣因子。
这是代码的摘录:
def agent_step(self, reward, state):
action = self.policy(state)
terminal = 0
self.replay_buffer.append(self.last_state, self.last_action, reward, terminal, state)
if self.replay_buffer.size() > self.replay_buffer.minibatch_size:
current_q = deepcopy(self.network)
for _ in range(self.num_replay):
experiences = self.replay_buffer.sample()
optimize_network(experiences, self.discount, self.optimizer, self.network, current_q, self.tau)
self.last_state = state
self.last_action = action
return action