📅  最后修改于: 2023-12-03 15:29:16.635000             🧑  作者: Mango
深度强化学习算法A3C (Asynchronous Advantage Actor-Critic) 是一种使用神经网络和多线程的方法来训练智能体进行决策的算法。本文将介绍A3C算法中所涉及的基本函数。
A3C算法旨在训练一个多层神经网络来预测智能体在每个状态下选择每个可能行动的概率,以及预测智能体在这个状态下采取每个行动后获得的预期奖励。通常情况下,A3C 的神经网络结构可分为三个部分:
1.输入层: 接受智能体当前的状态作为输入。
2.策略网络: 输出智能体在当前状态下选择每个可能行动的概率。
3.价值网络: 输出智能体在当前状态下采取所有行动后获得的预期奖励的估计值。
在训练过程中,我们需要定义一个损失函数,分别对策略和价值网络进行优化,即策略损失函数和价值损失函数。
策略损失函数是由误差信号的加权和形成的,误差信号的加权是指智能体在执行动作后得到的奖励乘以logarithmic的似然概率,即:
$$ \pi \log{P(A_t|S_t)} * (R_t - V(S_t) ) $$
其中,$\pi$ 是智能体的策略,$S_t$ 是当前状态,$A_t$ 是智能体采取的动作,$P(A_t|S_t)$ 是智能体在当前状态下采取行动$A_t$ 的概率,$V(S_t)$ 是价值网络估计的预期总奖励,$R_t$ 是智能体执行动作 $A_t$ 后所获得的回报。
价值损失函数是用来训练价值网络的,大致公式为:
$$ (R_t - V(S_t))^2 $$
其中,$R_t$ 为智能体执行动作 $A_t$ 后所获得的回报,$V(S_t)$ 是价值网络估计的预期总奖励.
在A3C算法中,多线程实现是必要的,其中有如下几个核心函数:
在A3C算法中,每个线程都是独立地运行并采取自己的动作。这意味着每个线程都产生了一个自己的策略梯度和价值信号。在更新神经网络时,我们需要组合所有线程的梯度,计算其策略和价值网络的平均值。具体实现如下:
loss = policy_loss + value_loss + entropy_loss
gradients = tf.gradients(loss, local_model.trainable_weights)
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimizer.apply_gradients(zip(gradients, global_model.trainable_weights))
其中,local_model.trainable_weights 是线程本地副本中的可训练变量,global_model.trainable_weights 是共享的全局模型变量。代码中也用到了梯度裁剪函数 tf.clip_by_global_norm 可以限制梯度更新的大小,避免过拟合或不稳定等问题。
同步更新在理论上很好,但却不实际。为了训练一个多线程的A3C算法,我们需要用到异步训练。在异步训练中,每个线程都是独立地运行,并且具有自己的副本。线程之间相互协作,共同更新整个系统的权重和梯度。这样可以大大提高训练速度和效率。
异步训练的实现方法如下:
while not coord.should_stop():
# 拿到当前状态
s = env.reset()
episode_reward = 0
episode_steps = 0
d = False
while not d:
# 拿到动作
a, v = agent.act(s)
# 执行动作
s_, r, d, info = env.step(a)
episode_reward += r
# 记录参数
agent.remember(s, a, r, s_, d, v)
if len(agent.memory) >= batch_size:
agent.replay()
# 参数更新
agent.update_local_model()
s = s_
episode_steps += 1
这里的 agent 是用来控制训练过程的主体, 调用 agent.act(s) 实现动作的选择,调用agent.update_local_model() 实现本地模型的更新。
经验重放是一种用于减少决策间相关性和提高梯度稳定性的技术。具体实现方法是在训练过程中,将先前的状态、动作、回报,下一个状态存储在记忆库中,然后从存储的经验中随机抽取一个样本,最后将这些样本传入深度神经网络中进行训练。
实现代码如下:
def remember(self, state, action, reward, next_state, done, value):
self.memory.append((state, action, reward, next_state, done, value))
def replay(self):
minibatch = random.sample(self.memory, self.batch_size)
states = np.array([item[0] for item in minibatch])
actions = np.array([item[1] for item in minibatch])
rewards = np.array([item[2] for item in minibatch])
next_states = np.array([item[3] for item in minibatch])
dones = np.array([item[4] for item in minibatch])
values = np.array([item[5] for item in minibatch])
其中,self.memory 是一个动态的环形缓存,负责存储智能体的经验。 self.replay() 为训练函数,在每一个线程中都被执行。 这里将存储的经验样本分别存入四个数组 states, actions, rewards 和 next_states 中,用于训练神经网络。
本文介绍了A3C算法涉及的核心函数,包括神经网络结构、策略损失和价值损失、组合损失、异步训练和经验重放等。这些函数在多线程的A3C算法实现中起到了至关重要的作用,促进了智能体的稳定学习。