深度强化学习之A3C网络—理论及代码(小车上山)
A3C
由于DQN学习过程需要强大的计算能力和大量的训练过程。为此,DeeoMind团队提出了一种新的算法,称为异步优势行为者评论家(A3C)算法,该算法要优于其他深度强化学习算法,因为其需要较少的计算能力和训练时间。A3C的主要思想是通过多个智能体并行学习并整合其所有经验。
A3C网络还可以与其他算法产生更好的精度,在连续和离散行为空间中均有很好的效果。该网络是使用多个智能,且每个智能体在实际环境副本中以不同的探索策略进行并行学习。然后,将这些智能体所获得的经验整合在一起构成全局智能体。全局智能体也称为主网络或全局网络,而其他智能体称为工人。
异步优势行为者
在继续之前,首先分析什么是A3C?其中3个A有什么含义?
在A3C中,第1个A是异步,表明了它是如何工作的。 并不是像在DQN中只有一个智能体来学习最优策略,在此有多个智能体与环境交互。由于同时有多个智能体与环境交互,因此需对每个智能体提供环境副本,以便每个智能体都能与其各自的环境副本进行交互。因此,这些多个智能体称为工人智能体,且有一个称为全局网络的独立智能体、所有智能体均向其汇报。这种全局网络将经验整合在一起。
第2个A是指优势, 在讨论DQN的对抗网络架构时已了解了什么是优势函数。优势函数可定义为Q函数与值函数之差。已知Q函数是确定某一状态下行为的好坏程度,值函数是确定所处状态的好坏程度。那么,直观地考虑Q函数与值函数之差意味着什么呢?其实表明了与其他所有行为相比,智能体在状态s下执行动作a的好坏程度。
第3个A是行为者评论家,网络架构有两种类型:行为者和评论家。 行为者的作用是学习一种策略,而评论家的作用是对行为者所学习的策略评估其好坏。
A3C架构
如上所述,图10.1中有多个工人智能体,且每个智能体都与其各自的环境副本进行交互。。然后,工人智能体学习策略,计算策略损失的梯度,并在全局网络中更新梯度。这个全局网络是同时由每个智能体进行更新的。A3C的最大优点之一就是在此不使用经验回放记忆。由于有多个智能体与环境交互,并将各自的信息整合到全局网络,因此,经验之间的相关性很小,甚至无相关性。经验回放需要大量记忆单元来保存所有的经验。由于A3C无需记忆,因此可大大减少存储空间和计算时间。
A3C工作原理
首先,工人智能体重置全局网络,然后开始与环境进行交互。每个工人智能体按照不同的探索策略来学习一个最优策略。接下来,计算值和策略损失,然后计算损失梯度,并在全局网络中更新梯度。工人智能体又重新开始重置全局网络并重复上述相同过程,周而复始。在分析值函数和策略损失函数之前,先了解如何计算优势函数。正如人们所知,优势函数是Q函数与值函数之差:
A(s,a)=Q(s,a)−V(s)A(s, a)=Q(s, a)-V(s)A(s,a)=Q(s,a)−V(s)
由于在A3C中实际上并没有直接计算Q值,在此使用折扣回报作为Q值的估计值。折扣回报R可表示为:
R=rn+γrn−1+γ2rn−2R=r_{n}+\gamma r_{n-1}+\gamma^{2} r_{n-2}R=rn+γrn−1+γ2rn−2
用折扣函数R来代替Q函数:
A(s,a)=R−V(s)A(s, a)=R-V(s)A(s,a)=R−V(s)
这时,可以得到值损失为折扣回报与状态值之间的均方差:
值损失(Lp)=∑(R−V(s))2(L_{p})=\sum(R-V(s))^{2}(Lp)=∑(R−V(s))2
那么,策略损失就可定义如下:
策略损失(Lp)=log(π(s))A(s)βH(π)(L_{p})=\log (\pi(s)) A(s) \beta H(\pi)(Lp)=log(π(s))A(s)βH(π)
好的,那么上式中的新项H(π)H(\pi)H(π)是什么?这是熵,用于确保策略得到充分探索。熵表明了行为概率的传播。当熵值较大时,每个行为的概率都是相同的,因此,智能体不能确定执行哪个行为,而当熵值较小时,某一行为将会比其他行为具有更高的概率,那么智能体就会选择概率较大的行为。这样,在损失函数中增加熵将会鼓励智能体进一步探索,从
而避免陷人局部最优。
基于A3C爬山
在此,以山地车为例来理解A3C。此时智能体是山地车,置于两座山之间。智能体的目标是向右侧爬山。然而,汽车不能一次就爬上山,必
须来回行驶来产生动力。若智能体花费了较少的能量来爬山,那么就会得到较高的奖励。
代码:
import gym
import multiprocessing
import threading
import numpy as np
import os
import shutil
import matplotlib.pyplot as plt
import tensorflow as tf
初始化所有参数
# number of worker agents
no_of_workers = multiprocessing.cpu_count() # maximum number of steps per episode 每个情景中最大的时间步
no_of_ep_steps = 200 # total number of episodes
no_of_episodes = 2000 global_net_scope = 'Global_Net'# sets how often the global network should be updated 设置全局网络更新频率
update_global = 10# discount factor
gamma = 0.90 # entropy factor 熵因数
entropy_beta = 0.01 # learning rate for actor 行为者的学习速率
lr_a = 0.0001 # learning rate for critic 评论家的学习速率
lr_c = 0.001 # boolean for rendering the environment 是否渲染环境
render=False # directory for storing logs 保存日志文件
log_dir = 'logs'
初始化MountainCar环境:
env = gym.make('MountainCarContinuous-v0')
env.reset()
得到states和actions值,以及action_bound:
# we get the number of states, actions and also the action bound
no_of_states = env.observation_space.shape[0]
no_of_actions = env.action_space.shape[0]
action_bound = [env.action_space.low, env.action_space.high]
在ActorCritic类中定义行为者评论家网络:
class ActorCritic(object):def __init__(self, scope, sess, globalAC=None):# first we initialize the session and RMS prop optimizer(RMS概率优化器) for both# our actor and critic networksself.sess=sessself.actor_optimizer = tf.train.RMSPropOptimizer(lr_a, name='RMSPropA')self.critic_optimizer = tf.train.RMSPropOptimizer(lr_c, name='RMSPropC')# now, if our network is global then,if scope == global_net_scope:with tf.variable_scope(scope):# initialize states and build actor and critic networkself.s = tf.placeholder(tf.float32, [None, no_of_states], 'S')# get the parameters of actor and critic networksself.a_params, self.c_params = self._build_net(scope)[-2:]# if our network is local then,else:with tf.variable_scope(scope):# initialize state, action and also target value as v_target(目标值)self.s = tf.placeholder(tf.float32, [None, no_of_states], 'S')self.a_his = tf.placeholder(tf.float32, [None, no_of_actions], 'A')self.v_target = tf.placeholder(tf.float32, [None, 1], 'Vtarget')# since we are in continuous actions space, we will calculate# mean and variance for choosing action 由于是在连续行为空间,因此需计算选择行为的均值和方差mean, var, self.v, self.a_params, self.c_params = self._build_net(scope)# then we calculate td error as the difference between v_target - v 由v_target与v之间的差值来计算td误差td = tf.subtract(self.v_target, self.v, name='TD_error')# minimize the TD errorwith tf.name_scope('critic_loss'):self.critic_loss = tf.reduce_mean(tf.square(td))# 通过均值乘以行为边界并将方差增加0.0001来更新均值与方差with tf.name_scope('wrap_action'):mean, var = mean * action_bound[1], var + 1e-4# we can generate distribution using this updated mean and var 根据更新的均值和方差来生成概率分布normal_dist = tf.contrib.distributions.Normal(mean, var)# now we shall calculate the actor loss. Recall the loss function.with tf.name_scope('actor_loss'):# calculate first term of loss which is log(pi(s)) 计算损失的第一项log(pi(s))log_prob = normal_dist.log_prob(self.a_his)exp_v = log_prob * td# calculate entropy from our action distribution for ensuring exploration 行为分布中计算熵,以确保探索entropy = normal_dist.entropy()# we can define our final loss as, 定义总损失为self.exp_v = exp_v + entropy_beta * entropy# then, we try to minimize the loss self.actor_loss = tf.reduce_mean(-self.exp_v)# now, we choose action by drawing from the distribution and clipping it between action bounds,# 现在,通过绘制分布曲线并在行为范围内裁剪来选择一个行为 with tf.name_scope('choose_action'):self.A = tf.clip_by_value(tf.squeeze(normal_dist.sample(1), axis=0), action_bound[0], action_bound[1])# calculate gradients for both of our actor and critic networks, 计算行为者和评论家网络的梯度with tf.name_scope('local_grad'):self.a_grads = tf.gradients(self.actor_loss, self.a_params)self.c_grads = tf.gradients(self.critic_loss, self.c_params)# now, we update our global network weights,with tf.name_scope('sync'):# pull the global network weights to the local networks 将全局网络的权重复制到局部网络with tf.name_scope('pull'):self.pull_a_params_op = [l_p.assign(g_p) for l_p, g_p in zip(self.a_params, globalAC.a_params)]self.pull_c_params_op = [l_p.assign(g_p) for l_p, g_p in zip(self.c_params, globalAC.c_params)]# push the local gradients to the global network 将局部网络的梯度传给全局网络with tf.name_scope('push'):self.update_a_op = self.actor_optimizer.apply_gradients(zip(self.a_grads, globalAC.a_params))self.update_c_op = self.critic_optimizer.apply_gradients(zip(self.c_grads, globalAC.c_params))# next, we define a function called _build_net for building our actor and critic networkdef _build_net(self, scope):# initialize weightsw_init = tf.random_normal_initializer(0., .1)with tf.variable_scope('actor'):l_a = tf.layers.dense(self.s, 200, tf.nn.relu6, kernel_initializer=w_init, name='la')mean = tf.layers.dense(l_a, no_of_actions, tf.nn.tanh,kernel_initializer=w_init, name='mean')var = tf.layers.dense(l_a, no_of_actions, tf.nn.softplus, kernel_initializer=w_init, name='var')with tf.variable_scope('critic'):l_c = tf.layers.dense(self.s, 100, tf.nn.relu6, kernel_initializer=w_init, name='lc')v = tf.layers.dense(l_c, 1, kernel_initializer=w_init, name='v')a_params = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=scope + '/actor')c_params = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=scope + '/critic')return mean, var, v, a_params, c_params# update the local gradients to the global networkdef update_global(self, feed_dict):self.sess.run([self.update_a_op, self.update_c_op], feed_dict)# get the global parameters to the local networksdef pull_global(self):self.sess.run([self.pull_a_params_op, self.pull_c_params_op])# select actiondef choose_action(self, s):s = s[np.newaxis, :]return self.sess.run(self.A, {self.s: s})[0]
现在,初始化worker类:
class Worker(object):def __init__(self, name, globalAC, sess):# intialize environment for each worker 对每个工人智能体初始化环境self.env = gym.make('MountainCarContinuous-v0').unwrappedself.name = name# create ActorCritic agent for each workerself.AC = ActorCritic(name, sess, globalAC)self.sess=sessdef work(self):global global_rewards, global_episodestotal_step = 1# store state, action, rewardbuffer_s, buffer_a, buffer_r = [], [], []# loop if the coordinator is active and global episode is less than the maximum episode# 如果合作者处于活动状态且全局情景小于最大回合,则继续循环while not coord.should_stop() and global_episodes < no_of_episodes:# initialize the environment by resetting 通过重设下列表来初始化环境s = self.env.reset()# store the episodic reward 保存情景奖励ep_r = 0for ep_t in range(no_of_ep_steps):# Render the environment for only worker 1 仅对工人/渲染环境if self.name == 'W_0' and render:self.env.render()# choose the action based on the policy 根据策略来选择行为a = self.AC.choose_action(s)# perform the action (a), recieve reward (r) and move to the next state (s_)s_, r, done, info = self.env.step(a)# set done as true if we reached maximum step per episode 若每个情景达到最大时间步,则设done为真done = True if ep_t == no_of_ep_steps - 1 else Falseep_r += r# store the state, action and rewards in the buffer(缓存中)buffer_s.append(s)buffer_a.append(a)# normalize the rewardbuffer_r.append((r+8)/8)# we Update the global network after particular time step 经过一定时间步之后,更新全局网络if total_step % update_global == 0 or done:if done:v_s_ = 0else:v_s_ = self.sess.run(self.AC.v, {self.AC.s: s_[np.newaxis, :]})[0, 0]# buffer for target v 目标v值的缓存buffer_v_target = []for r in buffer_r[::-1]:v_s_ = r + gamma * v_s_buffer_v_target.append(v_s_)buffer_v_target.reverse()buffer_s, buffer_a, buffer_v_target = np.vstack(buffer_s), np.vstack(buffer_a), np.vstack(buffer_v_target)feed_dict = {self.AC.s: buffer_s,self.AC.a_his: buffer_a,self.AC.v_target: buffer_v_target,}# update global networkself.AC.update_global(feed_dict)buffer_s, buffer_a, buffer_r = [], [], []# get global parameters to local ActorCriticself.AC.pull_global()s = s_total_step += 1if done:if len(global_rewards) < 5:global_rewards.append(ep_r)else:global_rewards.append(ep_r)global_rewards[-1] =(np.mean(global_rewards[-5:]))global_episodes += 1break
这时,启动Tensorflow会话,运行模型:
# create a list for string global rewards and episodes 创建保存全局奖励和情景的列表
global_rewards = []
global_episodes = 0# start tensorflow session
sess = tf.Session()with tf.device("/cpu:0"):# create an instance to our ActorCritic Class 创建一个类实例global_ac = ActorCritic(global_net_scope,sess)workers = []# loop for each workersfor i in range(no_of_workers):i_name = 'W_%i' % iworkers.append(Worker(i_name, global_ac,sess))coord = tf.train.Coordinator()
sess.run(tf.global_variables_initializer())# log everything so that we can visualize the graph in tensorboard
# 日志任何信息,以便在tensorboard中可视化图表if os.path.exists(log_dir):shutil.rmtree(log_dir)tf.summary.FileWriter(log_dir, sess.graph)worker_threads = []# start workersfor worker in workers:job = lambda: worker.work()t = threading.Thread(target=job)t.start()worker_threads.append(t)
coord.join(worker_threads)
深度强化学习之A3C网络—理论及代码(小车上山)相关推荐
- 深度强化学习-Double DQN算法原理与代码
深度强化学习-Double DQN算法原理与代码 引言 1 DDQN算法简介 2 DDQN算法原理 3 DDQN算法伪代码 4 仿真验证 引言 Double Deep Q Network(DDQN)是 ...
- 两种深度强化学习算法在网络调度上的应用与优化(DQN A3C)
首先给出论文地址和代码, Reinforcement Learning Based Scheduling Algorithm for Optimizing Age of Information in ...
- 深度强化学习Soft-Actor Critic算法高性能Pytorch代码(改写自spinningup,低环境依赖,低阅读障碍)
写在前面 DRL各种算法在github上各处都是,例如莫凡的DRL代码.ElegantDRL(易读性NO.1) 很多代码不是原算法的最佳实现,在具体实现细节上也存在差异,不建议直接用在科研上. 这篇博 ...
- 论坛报名 | 从捉迷藏、星际争霸到新一代人工智能:多智能体深度强化学习的理论与实践...
与6位图灵奖得主和100多位专家 共同探讨人工智能的下一个十年 长按图片或点击阅读原文,内行盛会,首次免费注册 2020年6月21-24日,第二届北京智源大会(官网:https://2020.baai ...
- 深度强化学习DQN网络
DQN网络 DQN(Deep Q Networks)网络属于深度强化学习中的一种网络,它是深度学习与Q学习的结合,在传统的Q学习中,我们需要维护一张Q(s,a)表,在实际运用中,Q表往往是巨大的,并且 ...
- 中科院自动化所介绍深度强化学习进展:从AlphaGo到AlphaGo Zero
来源:德先生 概要:2016年初,AlphaGo战胜李世石成为人工智能的里程碑事件.其核心技术深度强化学习受到人们的广泛关注和研究,取得了丰硕的理论和应用成果. 深度强化学习进展: 从AlphaGo ...
- 深度强化学习在天基信息网络中的应用——现状与前景
源自:系统工程与电子技术 作者:唐斯琪 潘志松 胡谷雨 吴炀 李云波 摘 要 未来天基信息网络(space information network, SIN)领域将面临由结构复杂.环境动态.业 ...
- DeepMind 综述深度强化学习:智能体和人类相似度竟然如此高!
来源:AI科技评论 近年来,深度强化学习(Deep reinforcement learning)方法在人工智能方面取得了瞩目的成就,从 Atari 游戏.到围棋.再到无限制扑克等领域,AI 的表现都 ...
- 如何更高效地压缩时序数据?基于深度强化学习的探索
简介: 随着移动互联网.IoT.5G 等的应用和普及,一步一步地我们走进了数字经济时代.随之而来的海量数据将是一种客观的存在,并发挥出越来越重要的作用.时序数据是海量数据中的一个重要组成部分,除了挖掘 ...
- 深度强化学习在时序数据压缩中的应用--ICDE 2020收录论文
彼节者有间,而刀刃者无厚:以无厚入有间,恢恢乎其于游刃必有余地矣 ----- 庖丁解牛 前言:随着移动互联网.IoT.5G等的应用和普及,一步一步地我们走进了数字经济时代.随之而来的海量数据将是一种客 ...
最新文章
- UVA10537 The Toll! Revisited (思维、最短路、输出字典序最小路径)
- mysql 排序 简介
- 域控 批量导入 用户_kerberos域用户提权分析
- 找对象不能只看TA的外表
- 7-3 银行排队问题之单队列多窗口服务 (25 分)
- new关键字和newInstance()方法的区别?Class.forName()
- react 图表库 滚动_2019 年值得推荐的 React 可视化库
- Web存储(Web Storage)介绍
- 以4%参数量比肩GPT-3!Deepmind 发布检索型 LM,或将成为 LM 发展新趋势!?
- python破解b站验证码实现登陆
- hdu Intelligent IME
- 析取范式、合取范式、主析取和主合取
- cadence logic 库说明
- 考研线性代数手写笔记2 矩阵
- spring配置中加载properties文件方法
- linux下通过SD卡烧录.bin程序
- 说话人确认系统性能评价指标
- Unity跑酷游戏中的路点生成算法
- 公证在知识产权维权中的地位不可动摇
- 伸展树的基本操作与应用 IOI2004 国家集训队论文 杨思雨