落成估值网络,学习笔记TF03八

Q-Learning,学习Action对应期望值(Expected
Utility)。1九玖零年,沃特kins提议。收敛性,1九九四年,Watkins和Dayan共同验证。学习期望价值,从此时此刻一步到独具继续手续,总希望获得最大价值(Q值、Value)。Action->Q函数,最棒战略,在每一个state下,选择Q值最高的Action。不依赖遭逢模型。有限马尔科夫决策进程(马克ov
Dectision Process) ,Q-Learning被证实最后能够找到最优政策。

上学笔记TF03八:达成估值网络,tf03八估值

Q-Learning,学习Action对应期望值(Expected
Utility)。1九8捌年,沃特kins提议。收敛性,一九玖二年,沃特kins和Dayan共同认证。学习期望价值,从此时此刻一步到具备继续手续,总希望获取最大价值(Q值、Value)。Action->Q函数,最好战术,在各种state下,采纳Q值最高的Action。不依赖情况模型。有限马尔科夫决策进程(马克ov
Dectision Process) ,Q-Learning被表明最后得以找到最优政策。

Q-Learning目的,求解函数Q(st,at),依据当下条件气象,估摸Action期望价值。Q-Learning磨练模型,以(状态、行为、嘉勉、下一气象)构成元组(st,at,rt+1,st+一)样本磨炼,st当前景观,at当前境况下推行action,rt+一实践Action后获取褒奖,st+1下壹处境,(当前景况,行动,嘉奖,下一境况)。特征(st,at)。学习目标(期望价值)
rt+1+γ·maxaQ(st+壹,a),当前Action得到Reward,加下一步可获得最大梦想价值,当前情景行动嘉奖,加下一动静行动最大希望价值。学习目标包括Q-Learning函数本人,递归求解。下一步可获最大梦想价值乘γ(衰减全面discount
factor),以后奖赏的学习权重。discount factor
0,模型学习不到其余以往表彰新闻,变短视,只关怀目前便宜。discount factor
>=
壹,算法大概无法消失,期望价值持续抬高未有衰减(discount),期望价值发散。discount
factor一般比1稍小。Qnew(st,at)<-(一-α)·Qold(st,at)+α·(rt+一+γ·maxaQ(st+壹,a)),Q-Learning学习进度式子。旧Q-Learning函数Qold(st,at),向学习目的(当前获取Reward加下一步可获取最大希望价值),按异常的小学习速率α学习,获得新Q-Learning函数Qnew(st,at)。学习速率决定新得到样本音信覆盖率前左右到消息比率,常常设极小值,保障学习进程稳定,确认保证最终收敛性。Q-Learning须求起始值Q0,比较高开头值,鼓励模型多探寻。

学学Q-Learning模型用神经互连网,获得模型是估值网络。用相比较深的神经互连网,正是DQN。谷歌(Google)DeepMind,《Nature》故事集,《Human-level control through deep
reinforcement
learning》建议。DeepMind用DQN成立达到规定的规范人类专家水平玩Atari2600种类游戏Agent。

state of the art DQN
Trick。第一个Trick。DQN引进卷积层。模型通过Atari游戏录像图像理解情形音讯并学习攻略。DQN必要明白接收图像,具备图像识别才干。卷积神经互联网,利用可领取空间组织音信卷积层抽取特征。卷积层提取图像中关键目标特征传给后层做分类、回归。DQN用卷积层做强化学习练习,根据条件图像输出决策。

第3个Trick。Experience Replay。深度学习需求大批量样书,古板Q-Learning
online
update方法(逐一对新样本学习)不切合DQN。增大样本,八个epoch操练,图像反复使用。Experience
Replay,积攒Agent
Experience样本,每一遍陶冶随机收取部分样书供互连网学习。牢固变成学习职分,制止短视只学习最新接触样本,综合反复使用过往多量样本学习。创立储存Experience缓存buffer,积累一定量较新样本。体积满了,用新样本替换最旧样本,保证大部分样本周边概率被抽到。不替换旧样本,练习进程被抽到可能率永世比新样本高诸多。每回必要练习样本,直接从buffer随机抽出一定量给DQN演练,保持样本高利用率,让模型学习到较新样本。

其四个Trick。用第3个DQN网络支持演习,target
DQN,协助总结目标Q值,提供学习目的公式里的maxaQ(st+一,a)。三个互连网,一个创造学习目标,三个实在磨练,让Q-Learning陶冶目的保持安静。强化学习
Q-Learning学习目标每便更动,学习目的分局是模型本人输出,每便换代模型参数会产生学习目的转移,更新往往幅度大,演习进度会丰富不安静、失控,DQN练习会沦为目的Q值与臆想Q值反馈循环(陷入震荡发散,难消失)。须要安静target
DQN支持互连网计算目的Q值。target
DQN,低频率、缓慢学习,输出目的Q值波动比较小,减小磨练过程影响。

第四个Trick。Double DQN。DeepMind 《Deep Reinforcement Learning with
Double Q-Learning》。守旧DQN高估Action
Q值,高估不均匀,导致次优Action被高估超过最优Action。target DQN
担当生成目标Q值,先爆发Q(st+一,a),再经过maxa选拔最大Q值。Double
DQN,在主DQN上通过最大Q值选择Action,再获得Action在target DQN
Q值。主网选择Action,targetDQN生成Action
Q值。被挑选Q值,不必然总是最大,幸免被高估次优Action总是超过最优Action,导致发现不了真正最棒Action。学习目的公式:Target=rt+一+γ·Qtarget(st+一,argmaxa(Qmain(st+1,a)))。

第五个Trick。Dueling DQN。谷歌(Google) 《Dueling Network Architectures for Deep
Reinforcement Learning》。Dueling
DQN,Q值函数Q(st,at)拆分,1部分静态景况气象有所价值V(st),Value;另一片段动态选拔Action额外带来价值A(at),Advantage。公式,Q(st,at)=V(st)+A(at)。互联网独家总括意况Value和选用Action
Advantage。Advantage,Action与其余Action比较,零均值。互联网最终,不再直接输出Action数量Q值,输出二个Value,及Action数量
Advantage值。V值分别加到每种Advantage值上,得最后结果。让DQN学习目的更显明,假如当中期望价值首要由意况气象调整,Value值大,全部Advantage波动相当小;纵然愿意价值首要由Action决定,Value值小,Advantage波动大。分解让学习目的更安宁、正确,DQN对景况气象揣度技能越来越强。

完结带Trick DQN。义务意况GridWorld导航类水言纟工。GridWorld包蕴四个hero,多少个goal,一个fire。调节hero移动,每回向上、下、左、右方向活动一步,多触碰goal(表彰值1),避开fire(奖励值-一)。游戏目标,限度步数内得到最多分数。Agent
间接通过GridWorld图像学习决定hero移动最优政策。

始建GridWorld职责意况。载入重视库,itertools迭代操作,scipy.misc、matplotlib.pyplot绘图,练习时间长,os定期积攒模型文件。

创造遭遇内物体对象class。蒙受物体属性,coordinates(x,y坐标)、size(尺寸)、intensity(亮度值)、channel(福睿斯GB颜色通道)、reward(奖赏值)、name(名称)。

创制GridWorld景况class,开始化方法只传入参数蒙受size。遭受长、宽为输入size,情形Action
Space设四,开头化情形物体对象列表。self.reset()方法复位情况,得到发轫observation(GridWorld图像),plt.imshow呈现observation。

概念情形reset方法。创制全部GridWorld物体,二个hero(用户调节目的)、5个goal(reward
1)、3个fire(reward
-一),增添到实体对象列表self.objects。self.newPosition()成立物体地点,随机选取未有被占用新职分。物有物体size、intensity
1,hero channel 二(深灰),goal channel 一(梅红),fire channel
0(栗褐)。self.renderEnv()绘制GridWorld图像,state。

兑现移动英雄剧中人物方法,传入值0、壹、2、三五个数字,分别表示上、下、左、右。函数依照输入操作好汉移动。尽管运动该方向会招致好汉出界,不会开展其余活动。

概念newPosition方法,选拔3个跟现存物体不争持地方。itertools.product方法获得多少个变量全体组成,创立情况size允许持有职位群集points,获取目前有所物体地方会集currentPositions,从points去掉currentPositions,剩下可用地方。np.random.choice随机收取3个可用地方重返。

定义checkGoal函数。检查hero是不是触碰goal、fire。从objects获取hero,其余物体对象放置others列表。编历others列表,假诺物体和坐标与hero完全1致,剖断触碰。依据触碰物体销毁,self.newPosition()方法在随心所欲地点再一次生成物体,再次回到物体reward值(goal
一,fire -1)。

成立长宛size+二、颜色通道数 三图片。初阶值全壹,代表全藤黄。最外侧内部像素颜色值全体赋0,代表橄榄黄。遍历物体对象列表self.objects,设置物体亮度值。scipy.misc.imresize将图像从原本大小resize
8肆x八4x叁尺寸,符合规律游玩图像尺寸。

概念GridWorld景况进行一步Action方法。输入参数Action,self.moveChart(action)移动hero地点,self.checkGoal()检查评定hero是不是触碰物体,得到reward、done标志。self.renderEnv获取碰到图像state,重回state、reward、done。

调用gameEnv类初步化方法,设置size
5,创造伍x中国共产党第五次全国代表大会小GridWorld境况,每回创制GridWorld景况随机变化。小尺寸遭受相对容术数习,大尺寸较难,陶冶时间越来越长。

规划DQN(Deep
Q-Network)互连网。使用卷积层,能够直接从遭遇原始像素学习计策。输入scalarInput,扁平化长为八4x八四x叁=21168向量,复苏成[-1,84,84,3]尺寸图片ImageIn。tf.contrib.layers.convolution二d创办第3个卷积层,卷积核尺寸八x8,步长四x4,输出通道数(filter数量)3二,padding模型VALID,bias伊始化器空。用4x四上升的幅度和VALID模型padding,第一层卷积输出维度20x20x3二。第三层卷积尺寸四x4,步长二x二,输出通道数6四,输出维度玖x九x64。第3层卷积尺寸三x三,步长一x壹,输出通道数64,输出维度7x七x6四。第5层卷积尺寸7×7,步长1×1,输出通道数51二,空间尺寸只允许在3个岗位卷积,,输出维度一x1x51贰。

tf.split(),第陆个卷积层输出conv4平均拆分两段,streamAC、streamVC,Dueling
DQN Advantage Function(Action带来的市场股票总值)和Value
Function(蒙受本人价值)。tf.split函数第一参数代表要拆分成几段。第三参数代表要拆分多少个维度。tf.contrib.layers.flatten将streamAC和streamVC转遍平的steamA和steamV。成立streamA和streamV线性全连接层参数AW和VW。tf.random_normal伊始化权重,tf.matmul做全连接层矩阵乘法,得到self.Advantage和self.Value。Advantage针对Action,输出数量为Action数量。Value针对情状统一的,输出数量
一。Q值由Value、advantage复合成,Value加上减少均值Advantage。Advantage减去均值操作
tf.subtract,均值总括tf.reduce_mean函数(reduce_indices
壹,代表Action数量维度)。最后输出Action,Q值最大Action,tf.argmax。

概念Double
DQN目标Q值targetQ输入placeholder,Agent动作actions输入placeholder。计算目的Q值,action由主DQN选拔,Q值由协理target
DQN生成。总结预测Q值,scalar形式actions转onehot编码格局,主DQN生成的Qout乘以actions_onehot,得预测Q值(Qout和actions都源于主DQN)。

定义loss,tf.square、tf.reduce_mean计算targetQ和Q均方标称误差,学习速率1e-四Adam优化器优化预测Q值和对象Q值偏差。

实现Experience Replay策略。定义experience_buffer
class。伊始化定义buffer_size存款和储蓄样本最大体积,创立buffer列表。定义向经buffer添日成分方法。假若高出buffer最大体量,清空最早样本,列表末尾加多新成分。定义样本抽样方式,用random.sample()函数随机收取一定数额样本。

概念8四x八四x3 states扁平化 一维向量函数processState,方便后边聚积样本。

updateTargetGraph函数,更新target DQN模型参数(主DQN用DQN class
self.updateModel方法立异模型参数)。输入变量tfVars,TensorFlow
Graph全体参数。tau,target
DQN向主DQN学习的速率。函数updateTargetGraph取tfVars前1/2参数,主DQN模型参数。再令援救targetDQN参数朝向主DQN参数前进极小比例(tau,0.00一),target
DQN缓慢学习主DQN。磨练时,目的Q值不能够在几遍迭代间波动太大,磨炼11分不平稳、失控,陷入目标Q值和预测Q值反馈循环。供给稳定目的Q值陶冶网络,缓慢学习target
DQN互连网出口目的Q值,主网络优化目标Q值和预测Q值间loss,target
DQN跟随主DQN缓慢学习。函数updateTargetGraph创造立异target
DQN模型参数操作,函数updateTarget实行操作。

DQN网络磨炼进度参数。batch_size,每一次从experience
buffer获取样本数,32。更新频率update_freq,每隔多少step实行三遍模型参数更新,四。Q值衰减周密(discount
factor)γ,0.99。startE开始实践随机Action可能率。endE最后施行随机Action可能率。anneling_steps从早先随机可能率降到最终随机可能率所需步数。num_episodes总共多少次GridWorld遇到试验。pre_train_steps正式用DQN选用Action前实行多少步随机Action测试。max_epLength每一种episode举办多少步Action。load_model是或不是读取此前磨练模型。path模型累积路线。h_size是DQN互连网最终全连接层隐含节点数。tau是target
DQN向主DQN学习速率。

Qnetwork类开头化mainQN和辅助targetQN。开首化全数模型参数。trainables获取具备可演习参数。updateTargetGraph成立立异target
DQN模型参数操作。

experience_buffer创制experience replay
class,设置当前随机Action可能率e,总结e每一步衰减值stepDrop。起头化积攒各样episode的reward列表rList,总步数total_steps。创立模型练习保存器(Saver)检查保存目录是或不是留存。

创建暗中认可Session,假诺load_model标记True,检查模型文件路线checkpoint,读取载入已封存模型。实行参数初叶化操作,实行更新targetQN模型参数操作。创设GridWorld试验循环,创制各个episode内部experience_buffer,内部buffer不参预当前迭代替练习练,演习只行使从前episode样本。开头化遭遇得第一个条件音信s,processState()函数扁平化。初始化私下认可done标志d、episode内总reward值rAll、episode内步数j。

始建内层循环,每一趟迭代实施Action。总步数稍低于pre_train_steps,强制用随机Action,只从随机Action学习,不深化进度。达到pre_train_steps,保留极小概率随机选取Action。不随机采用Action,传入当前状态s给主DQN,预测得到应有试行Action。env.step()实行一步Action,获得接下来事态s一、reward、done标志。processState对s1扁平化管理,s、a、r、s1、d传入episodeBuffer存款和储蓄。

总步数抢先pre_train_steps,持续下滑随机选拔Action可能率e,直到最低值endE。每当总步数达到update_freq整数部,进行3遍演练,模型参数更新。从myBuffer中sample出三个batch_size样本。练习样本第三列信息,下一情状s一,传入mainQN,试行main.predict,获得主模型采取Action。s一传出协理targetQN,得到s1状态下全体Action的Q值。mainQN输出Action
,选用targetQN输出Q,获得doubleQ。多少个DQN互联网把挑选Action和出口Q值七个操作分隔绝,Double
DQN。陶冶样本第3列音信,当前reward,加doubleQ乘以衰减周详γ,得到读书目标targetQ。传入当前状态s,学习目的targetQ和骨子里运用Action,实行updateTarget函数,施行targetQN模型参数更新(缓慢向mainQN学习)。完整达成一遍陶冶过程。各种step甘休,累计当前那步获取reward,更新当前事态为下一步试验做筹划。假诺done标志为True,直接中断episode试验。

episode内部episodeBuffer增多到myBuffer,作以往练习抽样数据集。当前episode
reward加多到rList。每二四个episode体现平均reward值。每一千个episode或任何磨炼实现,保存当前模型。

始发200个episode内,完全随机Action的前一千0步内,平均能够获取reward在贰左近,基础baseline。

锻练最后episode输出,平均reward 22,非常大进步。

计量每玖拾肆个episode平均reward,plt.plot呈现reward变化趋势。从第捌00个episode初叶,reward快捷进步,到第5000个episode基本达到顶峰,前面进去平台期,提高十分小。

    import numpy as np
    import random
    import tensorflow as tf
    import os
    %matplotlib inline
    from gridworld import gameEnv
    env = gameEnv(size=5)
    class Qnetwork():
        def __init__(self,h_size):
            #The network recieves a frame from the game, flattened into an array.
            #It then resizes it and processes it through four convolutional layers.
            self.scalarInput =  tf.placeholder(shape=[None,21168],dtype=tf.float32)
            self.imageIn = tf.reshape(self.scalarInput,shape=[-1,84,84,3])
            self.conv1 = tf.contrib.layers.convolution2d( \
                inputs=self.imageIn,num_outputs=32,kernel_size=[8,8],stride=[4,4],padding='VALID', biases_initializer=None)
            self.conv2 = tf.contrib.layers.convolution2d( \
                inputs=self.conv1,num_outputs=64,kernel_size=[4,4],stride=[2,2],padding='VALID', biases_initializer=None)
            self.conv3 = tf.contrib.layers.convolution2d( \
                inputs=self.conv2,num_outputs=64,kernel_size=[3,3],stride=[1,1],padding='VALID', biases_initializer=None)
            self.conv4 = tf.contrib.layers.convolution2d( \
                inputs=self.conv3,num_outputs=512,kernel_size=[7,7],stride=[1,1],padding='VALID', biases_initializer=None)

            #We take the output from the final convolutional layer and split it into separate advantage and value streams.
            self.streamAC,self.streamVC = tf.split(self.conv4,2,3)
            self.streamA = tf.contrib.layers.flatten(self.streamAC)
            self.streamV = tf.contrib.layers.flatten(self.streamVC)
            self.AW = tf.Variable(tf.random_normal([h_size//2,env.actions]))
            self.VW = tf.Variable(tf.random_normal([h_size//2,1]))
            self.Advantage = tf.matmul(self.streamA,self.AW)
            self.Value = tf.matmul(self.streamV,self.VW)

            #Then combine them together to get our final Q-values.
            self.Qout = self.Value + tf.subtract(self.Advantage,tf.reduce_mean(self.Advantage,reduction_indices=1,keep_dims=True))
            self.predict = tf.argmax(self.Qout,1)

            #Below we obtain the loss by taking the sum of squares difference between the target and prediction Q values.
            self.targetQ = tf.placeholder(shape=[None],dtype=tf.float32)
            self.actions = tf.placeholder(shape=[None],dtype=tf.int32)
            self.actions_onehot = tf.one_hot(self.actions,env.actions,dtype=tf.float32)

            self.Q = tf.reduce_sum(tf.multiply(self.Qout, self.actions_onehot), reduction_indices=1)

            self.td_error = tf.square(self.targetQ - self.Q)
            self.loss = tf.reduce_mean(self.td_error)
            self.trainer = tf.train.AdamOptimizer(learning_rate=0.0001)
            self.updateModel = self.trainer.minimize(self.loss)

    class experience_buffer():
        def __init__(self, buffer_size = 50000):
            self.buffer = []
            self.buffer_size = buffer_size

        def add(self,experience):
            if len(self.buffer) + len(experience) >= self.buffer_size:
                self.buffer[0:(len(experience)+len(self.buffer))-self.buffer_size] = []
            self.buffer.extend(experience)

        def sample(self,size):
            return np.reshape(np.array(random.sample(self.buffer,size)),[size,5])

    def processState(states):
        return np.reshape(states,[21168])

    def updateTargetGraph(tfVars,tau):
        total_vars = len(tfVars)
        op_holder = []
        for idx,var in enumerate(tfVars[0:total_vars//2]):
            op_holder.append(tfVars[idx+total_vars//2].assign((var.value()*tau) + ((1-tau)*tfVars[idx+total_vars//2].value())))
        return op_holder
    def updateTarget(op_holder,sess):
        for op in op_holder:
            sess.run(op)
    batch_size = 32 #How many experiences to use for each training step.
    update_freq = 4 #How often to perform a training step.
    y = .99 #Discount factor on the target Q-values
    startE = 1 #Starting chance of random action
    endE = 0.1 #Final chance of random action
    anneling_steps = 10000. #How many steps of training to reduce startE to endE.
    num_episodes = 10000#How many episodes of game environment to train network with.
    pre_train_steps = 10000 #How many steps of random actions before training begins.
    max_epLength = 50 #The max allowed length of our episode.
    load_model = False #Whether to load a saved model.
    path = "./dqn" #The path to save our model to.
    h_size = 512 #The size of the final convolutional layer before splitting it into Advantage and Value streams.
    tau = 0.001 #Rate to update target network toward primary network
    tf.reset_default_graph()
    mainQN = Qnetwork(h_size)
    targetQN = Qnetwork(h_size)
    init = tf.global_variables_initializer()
    trainables = tf.trainable_variables()
    targetOps = updateTargetGraph(trainables,tau)
    myBuffer = experience_buffer()
    #Set the rate of random action decrease. 
    e = startE
    stepDrop = (startE - endE)/anneling_steps
    #create lists to contain total rewards and steps per episode
    rList = []
    total_steps = 0
    #Make a path for our model to be saved in.
    saver = tf.train.Saver()
    if not os.path.exists(path):
        os.makedirs(path)
    #%%
    with tf.Session() as sess:
        if load_model == True:
            print('Loading Model...')
            ckpt = tf.train.get_checkpoint_state(path)
            saver.restore(sess,ckpt.model_checkpoint_path)
        sess.run(init)
        updateTarget(targetOps,sess) #Set the target network to be equal to the primary network.
        for i in range(num_episodes+1):
            episodeBuffer = experience_buffer()
            #Reset environment and get first new observation
            s = env.reset()
            s = processState(s)
            d = False
            rAll = 0
            j = 0
            #The Q-Network
            while j < max_epLength: #If the agent takes longer than 200 moves to reach either of the blocks, end the trial.
                j+=1
                #Choose an action by greedily (with e chance of random action) from the Q-network
                if np.random.rand(1) < e or total_steps < pre_train_steps:
                    a = np.random.randint(0,4)
                else:
                    a = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:[s]})[0]
                s1,r,d = env.step(a)
                s1 = processState(s1)
                total_steps += 1
                episodeBuffer.add(np.reshape(np.array([s,a,r,s1,d]),[1,5])) #Save the experience to our episode buffer.

                if total_steps > pre_train_steps:
                    if e > endE:
                        e -= stepDrop

                    if total_steps % (update_freq) == 0:
                        trainBatch = myBuffer.sample(batch_size) #Get a random batch of experiences.
                        #Below we perform the Double-DQN update to the target Q-values
                        A = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,3])})
                        Q = sess.run(targetQN.Qout,feed_dict={targetQN.scalarInput:np.vstack(trainBatch[:,3])})
                        doubleQ = Q[range(batch_size),A]
                        targetQ = trainBatch[:,2] + y*doubleQ
                        #Update the network with our target values.
                        _ = sess.run(mainQN.updateModel, \
                            feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,0]),mainQN.targetQ:targetQ, mainQN.actions:trainBatch[:,1]})

                        updateTarget(targetOps,sess) #Set the target network to be equal to the primary network.
                rAll += r
                s = s1

                if d == True:
                    break

            #Get all experiences from this episode and discount their rewards.
            myBuffer.add(episodeBuffer.buffer)
            rList.append(rAll)
            #Periodically save the model.
            if i>0 and i % 25 == 0:
                print('episode',i,', average reward of last 25 episode',np.mean(rList[-25:]))
            if i>0 and i % 1000 == 0:
                saver.save(sess,path+'/model-'+str(i)+'.cptk')
                print("Saved Model")            
        saver.save(sess,path+'/model-'+str(i)+'.cptk')
    #%%
    rMat = np.resize(np.array(rList),[len(rList)//100,100])
    rMean = np.average(rMat,1)
    plt.plot(rMean)

 

参考资料:
《TensorFlow实战》

招待付费咨询(150元每时辰),作者的微信:qingxingfengzi

http://www.bkjia.com/cjjc/1222006.htmlwww.bkjia.comtruehttp://www.bkjia.com/cjjc/1222006.htmlTechArticle学习笔记TF038:实现估值网络,tf038估值
Q-Learning,学习Action对应期望值(Expected
Utility)。一九八陆年,沃特kins建议。收敛性,1九玖伍年,沃特kins和Dayan共同证…

Q-Learning目的,求解函数Q(st,at),根据近来环情,推测Action期望价值。Q-Learning操练模型,以(状态、行为、奖赏、下一情状)构成元组(st,at,rt+一,st+一)样本磨练,st当前处境,at当前情形下试行action,rt+一推行Action后收获奖赏,st+一下一地方,(当前情景,行动,表彰,下一动静)。特征(st,at)。学习目的(期望价值)
rt+壹+γ·maxaQ(st+1,a),当前Action得到Reward,加下一步可收获最大梦想价值,当前情状行动表彰,加下壹情况行动最大期待价值。学习目标包罗Q-Learning函数自个儿,递归求解。下一步可获最大梦想价值乘γ(衰减周到discount
factor),以后嘉奖的就学权重。discount factor
0,模型学习不到任何今后奖励新闻,变短视,只关注当下补益。discount factor
>=
一,算法大概相当的小概消失,期望价值不断累加未有衰减(discount),期望价值发散。discount
factor一般比一稍小。Qnew(st,at)<-(一-α)·Qold(st,at)+α·(rt+1+γ·maxaQ(st+1,a)),Q-Learning学习进程式子。旧Q-Learning函数Qold(st,at),向学习目标(当前拿走Reward加下一步可获得最大希望价值),按非常小学习速率α学习,获得新Q-Learning函数Qnew(st,at)。学习速率决定新收获样本新闻覆盖率前左右到新闻比率,平时设极小值,保障学习进度牢固,确定保证最终收敛性。Q-Learning须求起首值Q0,相比高初叶值,鼓励模型多搜求。

上学Q-Learning模型用神经互连网,获得模型是估值网络。用比较深的神经互联网,正是DQN。谷歌(Google)DeepMind,《Nature》散文,《Human-level control through deep
reinforcement
learning》提出。DeepMind用DQN创设达到规定的标准人类专家水平玩Atari2600类别游戏Agent。

state of the art DQN
Trick。第3个Trick。DQN引进卷积层。模型通过Atari游戏录像图像领会情状音信并学习计谋。DQN要求驾驭接收图像,具有图像识别才干。卷积神经互联网,利用可领到空间协会音讯卷积层收取特征。卷积层提取图像中最首要指标特征传给后层做分类、回归。DQN用卷积层做强化学习磨练,依据意况图像输出决策。

第3个Trick。Experience Replay。深度学习须求大批量样书,守旧Q-Learning
online
update方法(逐1对新样本学习)不合乎DQN。增大样本,三个epoch锻练,图像反复使用。Experience
Replay,储存Agent
Experience样本,每一回磨炼随机抽取部分样本供互连网学习。牢固产生学习任务,防止短视只学习最新接触样本,综合反复使用过往大批量样书学习。成立储存Experience缓存buffer,累积一定量较新样本。体积满了,用新样本替换最旧样本,保证超过五分之3样本周围概率被抽到。不替换旧样本,磨练进度被抽到可能率永世比新样本高许多。每一遍须要磨练样本,直接从buffer随机抽出一定量给DQN操练,保持样本高利用率,让模型学习到较新样本。

其四个Trick。用第三个DQN网络协理练习,target
DQN,协理总计目的Q值,提供就学目的公式里的maxaQ(st+1,a)。多少个网络,一个创立学习目的,2个实际练习,让Q-Learning练习目标保持安澜。强化学习
Q-Learning学习目标每一遍改变,学习目的总局是模型本人输出,每回换代模型参数会导致学习目标转移,更新往往幅度大,练习过程会尤其动荡、失控,DQN磨炼会深陷目的Q值与估算Q值反馈循环(陷入震荡发散,难消失)。供给稳固target
DQN协理互联网总括目标Q值。target
DQN,低频率、缓慢学习,输出目的Q值波动相当小,减小练习进程影响。

第六个Trick。Double DQN。DeepMind 《Deep Reinforcement Learning with
Double Q-Learning》。古板DQN高估Action
Q值,高估不均匀,导致次优Action被高估超越最优Action。target DQN
担任生成目标Q值,首发生Q(st+一,a),再经过maxa选择最大Q值。Double
DQN,在主DQN上通过最大Q值选用Action,再获得Action在target DQN
Q值。主网选用Action,targetDQN生成Action
Q值。被采取Q值,不自然总是最大,制止被高估次优Action总是超越最优Action,导致发掘不了真正最棒Action。学习目的公式:Target=rt+一+γ·Qtarget(st+一,argmaxa(Qmain(st+一,a)))。

第多少个Trick。Dueling DQN。谷歌(Google) 《Dueling Network Architectures for Deep
Reinforcement Learning》。Dueling
DQN,Q值函数Q(st,at)拆分,壹部分静态情形境况有所价值V(st),Value;另一局地动态采纳Action额外带来价值A(at),Advantage。公式,Q(st,at)=V(st)+A(at)。网络独家总计景况Value和甄选Action
Advantage。Advantage,Action与其它Action比较,零均值。网络最终,不再直接输出Action数量Q值,输出2个Value,及Action数量
Advantage值。V值分别加到各样Advantage值上,得最终结果。让DQN学习目标更举世瞩目,假若当前希望价值首要由蒙受情形调节,Value值大,全数Advantage波动不大;假设指望价值首要由Action决定,Value值小,Advantage波动大。分解让学习目的更安宁、正确,DQN对情状情状臆想工夫越来越强。

福如东海带Trick DQN。职分环境GridWorld导航类水言纟工。GridWorld包涵三个hero,五个goal,三个fire。调整hero移动,每一回向上、下、左、右方向活动一步,多触碰goal(奖励值一),避开fire(奖赏值-1)。游戏目的,限度步数内得到最多分数。Agent
直接通过GridWorld图像学习决定hero移动最优政策。

创办GridWorld职分境况。载入重视库,itertools迭代操作,scipy.misc、matplotlib.pyplot绘图,陶冶时间长,os定期积累模型文件。

创造意况内物体对象class。景况物体属性,coordinates(x,y坐标)、size(尺寸)、intensity(亮度值)、channel(奥迪Q5GB颜色通道)、reward(嘉奖值)、name(名称)。

创设GridWorld碰着class,早先化方法只传入参数景况size。遭遇长、宽为输入size,遇到Action
Space设4,初步化遇到物体对象列表。self.reset()方法重新设置情况,获得初叶observation(GridWorld图像),plt.imshow彰显observation。

概念意况reset方法。创制全数GridWorld物体,3个hero(用户调整目的)、伍个goal(reward
壹)、二个fire(reward
-1),增添到实体对象列表self.objects。self.newPosition()创建物体地点,随机选拔未有被攻下新职务。物有物体size、intensity
一,hero channel 2(黑灰),goal channel 1(土红),fire channel
0(茶褐)。self.renderEnv()绘制GridWorld图像,state。

贯彻移动英豪剧中人物方法,传入值0、一、二、三多少个数字,分别代表上、下、左、右。函数依据输入操作大侠移动。假如运动该方向会变成大侠出界,不会进行任何活动。

概念newPosition方法,选拔三个跟现存物体不顶牛地点。itertools.product方法获得多少个变量全体组成,成立遭遇size允许全部地方集结points,获取近来享有物体地点集结currentPositions,从points去掉currentPositions,剩下可用地方。np.random.choice随机抽出二个可用地方再次来到。

定义checkGoal函数。检查hero是或不是触碰goal、fire。从objects获取hero,别的物体对象放置others列表。编历others列表,假如物体和坐标与hero完全壹致,判别触碰。遵照触碰物体销毁,self.newPosition()方法在随便地方再一次生成物体,重回物体reward值(goal
一,fire -一)。

创造长宛size+二、颜色通道数 叁图片。早先值全壹,代表全青黑。最外侧内部像素颜色值全体赋0,代表浅灰褐。遍历物体对象列表self.objects,设置物体亮度值。scipy.misc.imresize将图像从原始大小resize
捌4x84x三尺寸,平常游玩图像尺寸。

概念GridWorld情形进行一步Action方法。输入参数Action,self.moveChart(action)移动hero地点,self.checkGoal()检查实验hero是不是触碰物体,获得reward、done标志。self.renderEnv获取景况图像state,重临state、reward、done。

调用gameEnv类起先化方法,设置size
伍,创造5×5大小GridWorld情形,每一回创设GridWorld情况随机生成。小尺寸景况相对容命理术数习,大尺寸较难,操练时间更加长。

设计DQN(Deep
Q-Network)互连网。使用卷积层,能够直接从景况原始像素学习战术。输入scalarInput,扁平化长为八4x84x三=2116八向量,恢复生机成[-1,84,84,3]尺寸图片ImageIn。tf.contrib.layers.convolution贰d创立第三个卷积层,卷积核尺寸八x八,步长四x四,输出通道数(filter数量)32,padding模型VALID,bias早先化器空。用4x肆肥瘦和VALID模型padding,第二层卷积输出维度20x20x3二。第二层卷积尺寸四x四,步长2x二,输出通道数6四,输出维度玖x九x6四。第三层卷积尺寸叁x三,步长一x1,输出通道数6四,输出维度柒x柒x64。第5层卷积尺寸柒x柒,步长一x1,输出通道数51二,空间尺寸只同意在八个职位卷积,,输出维度一x一x512。

tf.split(),第5个卷积层输出conv四平均拆分两段,streamAC、streamVC,Dueling
DQN Advantage Function(Action带来的股票总值)和Value
Function(情形本人价值)。tf.split函数第三参数代表要拆分成几段。第壹参数代表要拆分几个维度。tf.contrib.layers.flatten将streamAC和streamVC转遍平的steamA和steamV。成立streamA和streamV线性全连接层参数AW和VW。tf.random_normal伊始化权重,tf.matmul做全连接层矩阵乘法,获得self.Advantage和self.Value。Advantage针对Action,输出数量为Action数量。Value针对情状统壹的,输出数量
一。Q值由Value、advantage复合成,Value加上减少均值Advantage。Advantage减去均值操作
tf.subtract,均值计算tf.reduce_mean函数(reduce_indices
1,代表Action数量维度)。最后输出Action,Q值最大Action,tf.argmax。

概念Double
DQN目的Q值targetQ输入placeholder,Agent动作actions输入placeholder。总计目标Q值,action由主DQN选取,Q值由协助target
DQN生成。总计预测Q值,scalar格局actions转onehot编码方式,主DQN生成的Qout乘以actions_onehot,得预测Q值(Qout和actions都出自己作主DQN)。

定义loss,tf.square、tf.reduce_mean总计targetQ和Q均方误差,学习速率一e-四Adam优化器优化预测Q值和目的Q值偏差。

实现Experience Replay策略。定义experience_buffer
class。早先化定义buffer_size存款和储蓄样本最大体量,创设buffer列表。定义向经buffer添美金素方法。倘诺超过buffer最大体量,清空最早样本,列表末尾增多新成分。定义样本抽样方式,用random.sample()函数随机收取一定数量样本。

概念八四x八四x三 states扁平化 一维向量函数processState,方便前边堆成堆样本。

updateTargetGraph函数,更新target DQN模型参数(主DQN用DQN class
self.updateModel方法立异模型参数)。输入变量tfVars,TensorFlow
Graph全体参数。tau,target
DQN向主DQN学习的速率。函数updateTargetGraph取tfVars前一半参数,主DQN模型参数。再令协助targetDQN参数朝向主DQN参数前进十分的小比例(tau,0.001),target
DQN缓慢学习主DQN。练习时,目的Q值不能够在三遍迭代间波动太大,演练10分不平稳、失控,陷入目标Q值和预测Q值反馈循环。须求安静目的Q值磨练互联网,缓慢学习target
DQN互联网出口目标Q值,主网络优化目的Q值和展望Q值间loss,target
DQN跟随主DQN缓慢学习。函数updateTargetGraph创制立异target
DQN模型参数操作,函数updateTarget施行操作。

DQN互连网磨练进度参数。batch_size,每趟从experience
buffer获取样本数,3二。更新频率update_freq,每隔多少step实践叁次模型参数更新,肆。Q值衰减周详(discount
factor)γ,0.9九。startE开首实行随机Action概率。endE最终试行随机Action可能率。anneling_steps从开首随机概率降到最终随机可能率所需步数。num_episodes总共多少次GridWorld碰到试验。pre_train_steps正式用DQN选用Action前开始展览多少步随机Action测试。max_epLength每一个episode举办多少步Action。load_model是不是读取此前陶冶模型。path模型积攒路线。h_size是DQN网络最终全连接层隐含节点数。tau是target
DQN向主DQN学习速率。

Qnetwork类起首化mainQN和扶助targetQN。早先化全部模型参数。trainables获取具备可练习参数。updateTargetGraph创造立异target
DQN模型参数操作。

experience_buffer创立experience replay
class,设置当前随机Action可能率e,总计e每一步衰减值stepDrop。开头化累积每种episode的reward列表rList,总步数total_steps。创建模型磨练保存器(Saver)检查保存目录是还是不是留存。

创制暗中认可Session,假设load_model标记True,检查模型文件路线checkpoint,读取载入已保存模型。实施参数开始化操作,实践更新targetQN模型参数操作。创立GridWorld试验循环,创设每一种episode内部experience_buffer,内部buffer不参与当前迭代替陶冶练,训练只使用在此以前episode样本。伊始化情况得第三个境遇音信s,processState()函数扁平化。伊始化暗中同意done标识d、episode内总reward值rAll、episode内步数j。

创设内层循环,每一次迭代推行Action。总步数稍差于pre_train_steps,强制用随机Action,只从随机Action学习,不加剧进度。达到pre_train_steps,保留十分小可能率随机采纳Action。不随机选用Action,传入当前状态s给主DQN,预测获得应该实施Action。env.step()奉行一步Action,获得接下来事态s一、reward、done标识。processState对s一扁平化管理,s、a、r、s一、d传入episodeBuffer存款和储蓄。

总步数超过pre_train_steps,持续下落随机采用Action概率e,直到最低值endE。每当总步数达到update_freq整数部,进行三遍磨练,模型参数更新。从myBuffer中sample出两个batch_size样本。磨练样本第叁列消息,下一状态s壹,传入mainQN,推行main.predict,获得主模型采取Action。s一流传补助targetQN,获得s一状态下全体Action的Q值。mainQN输出Action
,选拔targetQN输出Q,获得doubleQ。四个DQN网络把选取Action和出口Q值五个操作分隔断,Double
DQN。陶冶样本第二列音讯,当前reward,加doubleQ乘以衰减周到γ,获得读书目的targetQ。传入当前状态s,学习目的targetQ和骨子里行使Action,推行updateTarget函数,试行targetQN模型参数更新(缓慢向mainQN学习)。完整完毕壹遍陶冶进程。每种step甘休,累计当前那步获取reward,更新当前情景为下一步试验做希图。假诺done标识为True,直接中断episode试验。

episode内部episodeBuffer加多到myBuffer,作以往磨练抽样数据集。当前episode
reward加多到rList。每贰伍个episode体现平均reward值。每1000个episode或任何磨炼实现,保存当前模型。

开端200个episode内,完全随机Action的前一千0步内,平均能够得到reward在贰左近,基础baseline。

练习最终episode输出,平均reward 2二,相当的大升高。

总结每九十七个episode平均reward,plt.plot显示reward变化趋势。从第700个episode开端,reward赶快进步,到第四000个episode基本达到规定的规范顶峰,前边进去平台期,进步相当的小。

    import numpy as np
    import random
    import tensorflow as tf
    import os
    %matplotlib inline
    from gridworld import gameEnv
    env = gameEnv(size=5)
    class Qnetwork():
        def __init__(self,h_size):
            #The network recieves a frame from the game, flattened into an array.
            #It then resizes it and processes it through four convolutional layers.
            self.scalarInput =  tf.placeholder(shape=[None,21168],dtype=tf.float32)
            self.imageIn = tf.reshape(self.scalarInput,shape=[-1,84,84,3])
            self.conv1 = tf.contrib.layers.convolution2d( \
                inputs=self.imageIn,num_outputs=32,kernel_size=[8,8],stride=[4,4],padding='VALID', biases_initializer=None)
            self.conv2 = tf.contrib.layers.convolution2d( \
                inputs=self.conv1,num_outputs=64,kernel_size=[4,4],stride=[2,2],padding='VALID', biases_initializer=None)
            self.conv3 = tf.contrib.layers.convolution2d( \
                inputs=self.conv2,num_outputs=64,kernel_size=[3,3],stride=[1,1],padding='VALID', biases_initializer=None)
            self.conv4 = tf.contrib.layers.convolution2d( \
                inputs=self.conv3,num_outputs=512,kernel_size=[7,7],stride=[1,1],padding='VALID', biases_initializer=None)

            #We take the output from the final convolutional layer and split it into separate advantage and value streams.
            self.streamAC,self.streamVC = tf.split(self.conv4,2,3)
            self.streamA = tf.contrib.layers.flatten(self.streamAC)
            self.streamV = tf.contrib.layers.flatten(self.streamVC)
            self.AW = tf.Variable(tf.random_normal([h_size//2,env.actions]))
            self.VW = tf.Variable(tf.random_normal([h_size//2,1]))
            self.Advantage = tf.matmul(self.streamA,self.AW)
            self.Value = tf.matmul(self.streamV,self.VW)

            #Then combine them together to get our final Q-values.
            self.Qout = self.Value + tf.subtract(self.Advantage,tf.reduce_mean(self.Advantage,reduction_indices=1,keep_dims=True))
            self.predict = tf.argmax(self.Qout,1)

            #Below we obtain the loss by taking the sum of squares difference between the target and prediction Q values.
            self.targetQ = tf.placeholder(shape=[None],dtype=tf.float32)
            self.actions = tf.placeholder(shape=[None],dtype=tf.int32)
            self.actions_onehot = tf.one_hot(self.actions,env.actions,dtype=tf.float32)

            self.Q = tf.reduce_sum(tf.multiply(self.Qout, self.actions_onehot), reduction_indices=1)

            self.td_error = tf.square(self.targetQ - self.Q)
            self.loss = tf.reduce_mean(self.td_error)
            self.trainer = tf.train.AdamOptimizer(learning_rate=0.0001)
            self.updateModel = self.trainer.minimize(self.loss)

    class experience_buffer():
        def __init__(self, buffer_size = 50000):
            self.buffer = []
            self.buffer_size = buffer_size

        def add(self,experience):
            if len(self.buffer) + len(experience) >= self.buffer_size:
                self.buffer[0:(len(experience)+len(self.buffer))-self.buffer_size] = []
            self.buffer.extend(experience)

        def sample(self,size):
            return np.reshape(np.array(random.sample(self.buffer,size)),[size,5])

    def processState(states):
        return np.reshape(states,[21168])

    def updateTargetGraph(tfVars,tau):
        total_vars = len(tfVars)
        op_holder = []
        for idx,var in enumerate(tfVars[0:total_vars//2]):
            op_holder.append(tfVars[idx+total_vars//2].assign((var.value()*tau) + ((1-tau)*tfVars[idx+total_vars//2].value())))
        return op_holder
    def updateTarget(op_holder,sess):
        for op in op_holder:
            sess.run(op)
    batch_size = 32 #How many experiences to use for each training step.
    update_freq = 4 #How often to perform a training step.
    y = .99 #Discount factor on the target Q-values
    startE = 1 #Starting chance of random action
    endE = 0.1 #Final chance of random action
    anneling_steps = 10000. #How many steps of training to reduce startE to endE.
    num_episodes = 10000#How many episodes of game environment to train network with.
    pre_train_steps = 10000 #How many steps of random actions before training begins.
    max_epLength = 50 #The max allowed length of our episode.
    load_model = False #Whether to load a saved model.
    path = "./dqn" #The path to save our model to.
    h_size = 512 #The size of the final convolutional layer before splitting it into Advantage and Value streams.
    tau = 0.001 #Rate to update target network toward primary network
    tf.reset_default_graph()
    mainQN = Qnetwork(h_size)
    targetQN = Qnetwork(h_size)
    init = tf.global_variables_initializer()
    trainables = tf.trainable_variables()
    targetOps = updateTargetGraph(trainables,tau)
    myBuffer = experience_buffer()
    #Set the rate of random action decrease. 
    e = startE
    stepDrop = (startE - endE)/anneling_steps
    #create lists to contain total rewards and steps per episode
    rList = []
    total_steps = 0
    #Make a path for our model to be saved in.
    saver = tf.train.Saver()
    if not os.path.exists(path):
        os.makedirs(path)
    #%%
    with tf.Session() as sess:
        if load_model == True:
            print('Loading Model...')
            ckpt = tf.train.get_checkpoint_state(path)
            saver.restore(sess,ckpt.model_checkpoint_path)
        sess.run(init)
        updateTarget(targetOps,sess) #Set the target network to be equal to the primary network.
        for i in range(num_episodes+1):
            episodeBuffer = experience_buffer()
            #Reset environment and get first new observation
            s = env.reset()
            s = processState(s)
            d = False
            rAll = 0
            j = 0
            #The Q-Network
            while j < max_epLength: #If the agent takes longer than 200 moves to reach either of the blocks, end the trial.
                j+=1
                #Choose an action by greedily (with e chance of random action) from the Q-network
                if np.random.rand(1) < e or total_steps < pre_train_steps:
                    a = np.random.randint(0,4)
                else:
                    a = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:[s]})[0]
                s1,r,d = env.step(a)
                s1 = processState(s1)
                total_steps += 1
                episodeBuffer.add(np.reshape(np.array([s,a,r,s1,d]),[1,5])) #Save the experience to our episode buffer.

                if total_steps > pre_train_steps:
                    if e > endE:
                        e -= stepDrop

                    if total_steps % (update_freq) == 0:
                        trainBatch = myBuffer.sample(batch_size) #Get a random batch of experiences.
                        #Below we perform the Double-DQN update to the target Q-values
                        A = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,3])})
                        Q = sess.run(targetQN.Qout,feed_dict={targetQN.scalarInput:np.vstack(trainBatch[:,3])})
                        doubleQ = Q[range(batch_size),A]
                        targetQ = trainBatch[:,2] + y*doubleQ
                        #Update the network with our target values.
                        _ = sess.run(mainQN.updateModel, \
                            feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,0]),mainQN.targetQ:targetQ, mainQN.actions:trainBatch[:,1]})

                        updateTarget(targetOps,sess) #Set the target network to be equal to the primary network.
                rAll += r
                s = s1

                if d == True:
                    break

            #Get all experiences from this episode and discount their rewards.
            myBuffer.add(episodeBuffer.buffer)
            rList.append(rAll)
            #Periodically save the model.
            if i>0 and i % 25 == 0:
                print('episode',i,', average reward of last 25 episode',np.mean(rList[-25:]))
            if i>0 and i % 1000 == 0:
                saver.save(sess,path+'/model-'+str(i)+'.cptk')
                print("Saved Model")            
        saver.save(sess,path+'/model-'+str(i)+'.cptk')
    #%%
    rMat = np.resize(np.array(rList),[len(rList)//100,100])
    rMean = np.average(rMat,1)
    plt.plot(rMean)

 

参考资料:
《TensorFlow实战》

招待付费咨询(150元每时辰),小编的微信:qingxingfengzi

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注