st+1)样本磨炼,学习Q-Learning模型用神经网络

Q-Learning,学习Action对应期望值(Expected
Utility)。1989年,沃特kins指出。收敛性,1992年,沃特kins和Dayan共同认证。学习期望价值,从当前一步到具备继续手续,总希望获取最大价值(Q值、Value)。Action->Q函数,最佳策略,在每个state下,拔取Q值最高的Action。不倚重环境模型。有限马尔科夫决策过程(Markov
Dectision Process) ,Q-Learning被证实最终得以找到最优政策。

学习笔记TF038:实现估值网络,tf038估值

Q-Learning,学习Action对应期望值(Expected
Utility)。1989年,沃特kins指出。收敛性,1992年,沃特(Wat)kins和Dayan共同认证。学习期望价值,从此时此刻一步到拥有继续手续,总希望拿到最大价值(Q值、Value)。Action->Q函数,最佳策略,在各类state下,采纳Q值最高的Action。不倚重环境模型。有限马尔科夫决策过程(马克(Mark)ov
Dectision Process) ,Q-Learning被申明最后可以找到最优政策。

Q-Learning目的,求解函数Q(st,at),遵照当下环境气象,估摸Action期望价值。Q-Learning锻炼模型,以(状态、行为、奖励、下一情景)构成元组(st,at,rt+1,st+1)样本磨炼,st当前情景,at当前情景下执行action,rt+1执行Action后取得奖励,st+1下一动静,(当前气象,行动,奖励,下一气象)。特征(st,at)。学习目的(期望价值)
rt+1+γ·maxaQ(st+1,a),当前Action得到Reward,加下一步可得到最大期待价值,当前事态行动奖励,加下一境况行动最大希望价值。学习目的包含Q-Learning函数本身,递归求解。下一步可获最大期待价值乘γ(衰减周全discount
factor),未来奖励的学习权重。discount factor
0,模型学习不到此外将来嘉奖音讯,变短视,只关心眼前补益。discount factor
>=
1,算法可能无法磨灭,期望价值持续抬高没有衰减(discount),期望价值发散。discount
factor一般比1稍小。Qnew(st,at)<-(1-α)·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。GoogleDeepMind,《Nature》小说,《Human-level control through deep
reinforcement
learning》提议。DeepMind用DQN创立达标人类专家水平玩Atari2600序列游戏Agent。

state of the art DQN
Trick。第一个Trick。DQN引入卷积层。模型通过Atari游戏录像图像精通环境音讯并学习策略。DQN需要精通接收图像,具有图像识别能力。卷积神经网络,利用可领取空间社团信息卷积层抽取特征。卷积层提取图像中根本目的特征传给后层做分类、回归。DQN用卷积层做强化学习磨炼,按照条件图像输出决策。

其次个Trick。Experience Replay。深度学习需要大量样书,传统Q-Learning
online
update方法(逐一对新样本学习)不切合DQN。增大样本,两个epoch练习,图像反复使用。Experience
Replay,储存Agent
Experience样本,每一遍磨练随机抽取部分样书供网络学习。稳定形成学习任务,防止短视只学习最新接触样本,综合反复使用过往大量样本学习。创制储存Experience缓存buffer,储存一定量较新样本。容量满了,用新样本替换最旧样本,保证大部分样本相近概率被抽到。不替换旧样本,训练过程被抽到概率永远比新样本高很多。每一次需要磨炼样本,直接从buffer随机抽取一定量给DQN锻炼,保持样本高利用率,让模型学习到较新样本。

其两个Trick。用第二个DQN网络帮助训练,target
DQN,襄助总括目的Q值,提供就学目标公式里的maxaQ(st+1,a)。多少个网络,一个制作学习目的,一个其实训练,让Q-Learning磨练目的保持安澜。强化学习
Q-Learning学习目的每一遍变更,学习目的分部是模型本身输出,每一次换代模型参数会导致学习目标转移,更新往往幅度大,磨练过程会特别不安定、失控,DQN练习会深陷目的Q值与估量Q值反馈循环(陷入震荡发散,难消失)。需要稳定target
DQN襄助网络总计目的Q值。target
DQN,低频率、缓慢学习,输出目的Q值波动较小,减小训练过程影响。

第4个Trick。Double DQN。DeepMind 《Deep Reinforcement Learning with
Double Q-Learning》。传统DQN高估Action
Q值,高估不均匀,导致次优Action被高估超越最优Action。target DQN
负责生成目的Q值,先爆发Q(st+1,a),再通过maxa采用最大Q值。Double
DQN,在主DQN上经过最大Q值采取Action,再得到Action在target DQN
Q值。主网采取Action,targetDQN生成Action
Q值。被选用Q值,不自然总是最大,避免被高估次优Action总是领先最优Action,导致发现不了真正最好Action。学习目的公式:Target=rt+1+γ·Qtarget(st+1,argmaxa(Qmain(st+1,a)))。

第5个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值,输出一个Value,及Action数量
Advantage值。V值分别加到每个Advantage值上,得末了结果。让DQN学习目的更精晓,假诺当前可望价值首要由环境气象控制,Value值大,所有Advantage波动不大;假使指望价值首要由Action决定,Value值小,Advantage波动大。分解让学习目的更安宁、精确,DQN对环境情况估算能力更强。

兑现带Trick DQN。任务环境
GridWorld导航类水言纟工。GridWorld包含一个hero,4个goal,2个fire。控制hero移动,每便向上、下、左、右方向活动一步,多触碰goal(奖励值1),避开fire(奖励值-1)。游戏目的,限度步数内得到最多分数。Agent
直接通过GridWorld图像学习决定hero移动最优政策。

成立GridWorld任务环境。载入依赖库,itertools迭代操作,scipy.misc、matplotlib.pyplot绘图,磨炼时间长,os定期储存模型文件。

创制环境内物体对象class。环境物体属性,coordinates(x,y坐标)、size(尺寸)、intensity(亮度值)、channel(RGB颜色通道)、reward(奖励值)、name(名称)。

创建GridWorld环境class,初阶化方法只传入参数环境size。环境长、宽为输入size,环境Action
Space设4,开头化环境物体对象列表。self.reset()方法重置环境,得到先河observation(GridWorld图像),plt.imshow体现observation。

概念环境reset方法。创设所有GridWorld物体,1个hero(用户控制目的)、4个goal(reward
1)、2个fire(reward
-1),添加到实体对象列表self.objects。self.newPosition()创立物体地方,随机选拔没有被占据新岗位。物有物体size、intensity
1,hero channel 2(褐色),goal channel 1(肉色),fire channel
0(黑色)。self.renderEnv()绘制GridWorld图像,state。

落实移动英雄角色方法,传入值0、1、2、3六个数字,分别代表上、下、左、右。函数依据输入操作英雄移动。假设运动该方向会招致英雄出界,不会开展任何活动。

概念newPosition方法,采纳一个跟现有物体不争辩地点。itertools.product方法赢得多少个变量所有结成,成立环境size允许持有职位集合points,获取最近有所物体地方集合currentPositions,从points去掉currentPositions,剩下可用地方。np.random.choice随机抽取一个可用地方再次来到。

定义checkGoal函数。检查hero是否触碰goal、fire。从objects获取hero,其他实体对象放置others列表。编历others列表,假使物体和坐标与hero完全一致,判定触碰。依照触碰物体销毁,self.newPosition()方法在任意位置再一次生成物体,再次回到物体reward值(goal
1,fire -1)。

创制长宛size+2、颜色通道数 3
图片。起初值全1,代表全白色。最外面内部像素颜色值全体赋0,代表青色。遍历物体对象列表self.objects,设置物体亮度值。scipy.misc.imresize将图像从原本大小resize
84x84x3尺寸,正常游玩图像尺寸。

概念GridWorld环境进行一步Action方法。输入参数Action,self.moveChart(action)移动hero地方,self.checkGoal()检测hero是否触碰物体,得到reward、done标记。self.renderEnv获取环境图像state,重回state、reward、done。

调用gameEnv类先河化方法,设置size
5,创立5×5大小GridWorld环境,每一回成立GridWorld环境随机变化。小尺寸环境相对容命理术数习,大尺寸较难,磨炼时间更长。

统筹DQN(Deep
Q-Network)网络。使用卷积层,可以平昔从环境原始像素学习策略。输入scalarInput,扁平化长为84x84x3=21168向量,恢复生机成[-1,84,84,3]尺寸图片ImageIn。tf.contrib.layers.convolution2d成立第1个卷积层,卷积核尺寸8×8,步长4×4,输出通道数(filter数量)32,padding模型VALID,bias伊始化器空。用4×4开间和VALID模型padding,第1层卷积输出维度20x20x32。第2层卷积尺寸4×4,步长2×2,输出通道数64,输出维度9x9x64。第3层卷积尺寸3×3,步长1×1,输出通道数64,输出维度7x7x64。第4层卷积尺寸7×7,步长1×1,输出通道数512,空间尺寸只允许在一个岗位卷积,,输出维度1x1x512。

tf.split(),第4个卷积层输出conv4平均拆分两段,streamAC、streamVC,Dueling
DQN Advantage Function(Action带来的市值)和Value
Function(环境本身价值)。tf.split函数第2参数代表要拆分成几段。第3参数代表要拆分多少个维度。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针对环境统一的,输出数量
1。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均方误差,学习速率1e-4
艾达(Ada)m优化器优化预测Q值和指标Q值偏差。

实现Experience Replay策略。定义experience_buffer
class。初叶化定义buffer_size存储样本最大容量,创立buffer列表。定义向经buffer添法郎素方法。假使跨越buffer最大容量,清空最早样本,列表末尾添加新元素。定义样本抽样格局,用random.sample()函数随机抽取一定数量样本。

概念84x84x3 states扁平化 1维向量函数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值不可能在四遍迭代间波动太大,磨练异常不稳定、失控,陷入目的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执行一次模型参数更新,4。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,得到接下来事态s1、reward、done标记。processState对s1扁平化处理,s、a、r、s1、d传入episodeBuffer存储。

总步数领先pre_train_steps,持续下跌随机采纳Action概率e,直到最低值endE。每当总步数达到update_freq整数部,举行两次锻练,模型参数更新。从myBuffer中sample出一个batch_size样本。锻练样本第3列信息,下一状态s1,传入mainQN,执行main.predict,拿到主模型接纳Action。s1传开扶助targetQN,拿到s1状态下拥有Action的Q值。mainQN输出Action
,选取targetQN输出Q,得到doubleQ。六个DQN网络把挑选Action和输出Q值三个操作分隔开,Double
DQN。训练样本第2列新闻,当前reward,加doubleQ乘以衰减周到γ,得到学习目的targetQ。传入当前状态s,学习目标targetQ和骨子里利用Action,执行updateTarget函数,执行targetQN模型参数更新(缓慢向mainQN学习)。完整完成四遍磨炼过程。每个step截至,累计当前这步获取reward,更新当前场合为下一步试验做准备。假使done标记为True,直接中断episode试验。

episode内部episodeBuffer添加到myBuffer,作将来锻炼抽样数据集。当前episode
reward添加到rList。每25个episode体现平均reward值。每1000个episode或任何教练成功,保存当前模型。

起头200个episode内,完全随机Action的前10000步内,平均可以博得reward在2相邻,基础baseline。

教练最终episode输出,平均reward 22,分外大进步。

计量每100个episode平均reward,plt.plot映现reward变化趋势。从第1000个episode先导,reward快速提高,到第4000个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)。1989年,沃特kins指出。收敛性,1992年,沃特(Wat)kins和Dayan共同证…

Q-Learning,学习Action对应期望值(Expected
Utility)。1989年,沃特kins提出。收敛性,1992年,沃特(Wat)kins和Dayan共同证实。学习期望价值,从眼前一步到所有继续手续,总希望得到最大价值(Q值、Value)。Action->Q函数,最佳策略,在各类state下,接纳Q值最高的Action。不依赖环境模型。有限马尔科夫决策过程(马克(Mark)ov
Dectision Process) ,Q-Learning被注解最后可以找到最优政策。

Q-Learning目标,求解函数Q(st,at),遵照当下条件气象,揣测Action期望价值。Q-Learning训练模型,以(状态、行为、奖励、下一情景)构成元组(st,at,rt+1,st+1)样本磨炼,st当前情景,at当前场所下执行action,rt+1执行Action后获取褒奖,st+1下一气象,(当前气象,行动,奖励,下一景观)。特征(st,at)。学习目的(期望价值)
rt+1+γ·maxaQ(st+1,a),当前Action得到Reward,加下一步可获取最大梦想价值,当前事态行动奖励,加下一状态行动最大希望价值。学习目标包含Q-Learning函数本身,递归求解。下一步可获最大梦想价值乘γ(衰减周全discount
factor),以后奖励的上学权重。discount factor
0,模型学习不到任何将来嘉奖信息,变短视,只关心当下补益。discount factor
>=
1,算法可能不可能消失,期望价值持续充足没有衰减(discount),期望价值发散。discount
factor一般比1稍小。Qnew(st,at)<-(1-α)·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目的,求解函数Q(st,at),依照当前环境情状,估计Action期望价值。Q-Learning磨练模型,以(状态、行为、奖励、下一动静)构成元组(st,at,rt+1,st+1)样本练习,st当前气象,at当前景观下执行action,rt+1执行Action后得到褒奖,st+1下一情形,(当前情状,行动,奖励,下一情状)。特征(st,at)。学习目的(期望价值)
rt+1+γ·maxaQ(st+1,a),当前Action得到Reward,加下一步可取得最大期待价值,当前情景行动奖励,加下一场所行动最大希望价值。学习目的包含Q-Learning函数本身,递归求解。下一步可获最大梦想价值乘γ(衰减周详discount
factor),将来嘉奖的学习权重。discount factor
0,模型学习不到另外未来嘉奖信息,变短视,只关注当下补益。discount factor
>=
1,算法可能无法消失,期望价值持续添加没有衰减(discount),期望价值发散。discount
factor一般比1稍小。Qnew(st,at)<-(1-α)·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。GoogleDeepMind,《Nature》随笔,《Human-level control through deep
reinforcement
learning》提议。DeepMind用DQN成立达标人类专家水平玩Atari2600体系游戏Agent。

学学Q-Learning模型用神经网络,得到模型是估值网络。用相比深的神经网络,就是DQN。GoogleDeepMind,《Nature》论文,《Human-level control through deep
reinforcement
learning》提议。DeepMind用DQN创设达标人类专家水平玩Atari2600体系游戏Agent。

state of the art DQN
Trick。首个Trick。DQN引入卷积层。模型通过Atari游戏视频图像了解环境消息并学习策略。DQN需要领会接收图像,具有图像识别能力。卷积神经网络,利用可领到空间社团音信卷积层抽取特征。卷积层提取图像中最首要对象特征传给后层做分类、回归。DQN用卷积层做强化学习磨练,按照环境图像输出决策。

state of the art DQN
Trick。第一个Trick。DQN引入卷积层。模型通过Atari游戏录像图像精晓环境音信并学习策略。DQN需要了解接收图像,具有图像识别能力。卷积神经网络,利用可领到空间社团信息卷积层抽取特征。卷积层提取图像中着重指标特征传给后层做分类、回归。DQN用卷积层做强化学习锻练,遵照环境图像输出决策。

第二个Trick。Experience Replay。深度学习需要大量样本,传统Q-Learning
online
update方法(逐一对新样本学习)不切合DQN。增大样本,五个epoch磨练,图像反复使用。Experience
Replay,储存Agent
Experience样本,每一次训练随机抽取部分样本供网络学习。稳定形成学习任务,防止短视只学习最新接触样本,综合反复使用过往大量样书学习。创设储存Experience缓存buffer,储存一定量较新样本。容量满了,用新样本替换最旧样本,保证大部分样本相近概率被抽到。不替换旧样本,锻炼过程被抽到概率永远比新样本高很多。每一次需要磨炼样本,直接从buffer随机抽取一定量给DQN磨炼,保持样本高利用率,让模型学习到较新样本。

其次个Trick。Experience Replay。深度学习需要大量样本,传统Q-Learning
online
update方法(逐一对新样本学习)不适合DQN。增大样本,四个epoch锻炼,图像反复使用。Experience
Replay,储存Agent
Experience样本,每一遍磨炼随机抽取部分样本供网络学习。稳定形成学习任务,防止短视只学习最新接触样本,综合反复使用过往大量样书学习。创制储存Experience缓存buffer,储存一定量较新样本。容量满了,用新样本替换最旧样本,保证大部分样本相近概率被抽到。不替换旧样本,操练过程被抽到概率永远比新样本高很多。每便需要磨炼样本,直接从buffer随机抽取一定量给DQN磨炼,保持样本高利用率,让模型学习到较新样本。

其五个Trick。用第二个DQN网络帮助操练,target
DQN,协理总括目的Q值,提供学习目的公式里的maxaQ(st+1,a)。多个网络,一个成立学习目标,一个事实上练习,让Q-Learning锻炼目的保持安静。强化学习
Q-Learning学习目的每一趟变更,学习目的分部是模型本身输出,每一次换代模型参数会导致学习目标转移,更新往往幅度大,操练过程会充分不安定、失控,DQN训练会沦为目的Q值与估量Q值反馈循环(陷入震荡发散,难消失)。需要稳定target
DQN协助网络总结目的Q值。target
DQN,低频率、缓慢学习,输出目标Q值波动较小,减小磨练过程影响。

其五个Trick。用第二个DQN网络帮忙训练,target
DQN,协理总括目的Q值,提供就学目的公式里的maxaQ(st+1,a)。三个网络,一个打造学习目的,一个实际上磨练,让Q-Learning训练目的保持安静。强化学习
Q-Learning学习目的每趟变更,学习目的分部是模型本身输出,每一回换代模型参数会造成学习目的转移,更新往往幅度大,训练过程会充裕不平稳、失控,DQN训练会沦为目的Q值与臆度Q值反馈循环(陷入震荡发散,难消失)。需要稳定target
DQN帮助网络总括目标Q值。target
DQN,低频率、缓慢学习,输出目标Q值波动较小,减小锻练过程影响。

第4个Trick。Double DQN。DeepMind 《Deep Reinforcement Learning with
Double Q-Learning》。传统DQN高估Action
Q值,高估不均匀,导致次优Action被高估超过最优Action。target DQN
负责生成目标Q值,先发生Q(st+1,a),再经过maxa选拔最大Q值。Double
DQN,在主DQN上通过最大Q值选拔Action,再赢得Action在target DQN
Q值。主网采纳Action,targetDQN生成Action
Q值。被增选Q值,不必然总是最大,防止被高估次优Action总是超越最优Action,导致发现不了真正最好Action。学习目的公式:Target=rt+1+γ·Qtarget(st+1,argmaxa(Qmain(st+1,a)))。

第4个Trick。Double DQN。DeepMind 《Deep Reinforcement Learning with
Double Q-Learning》。传统DQN高估Action
Q值,高估不均匀,导致次优Action被高估领先最优Action。target DQN
负责生成目的Q值,先爆发Q(st+1,a),再经过maxa采取最大Q值。Double
DQN,在主DQN上通过最大Q值选用Action,再赢得Action在target DQN
Q值。主网选用Action,targetDQN生成Action
Q值。被选拔Q值,不自然总是最大,制止被高估次优Action总是超越最优Action,导致发现不了真正最好Action。学习目的公式:Target=rt+1+γ·Qtarget(st+1,argmaxa(Qmain(st+1,a)))。

第5个Trick。Dueling DQN。谷歌 《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值,输出一个Value,及Action数量
Advantage值。V值分别加到每个Advantage值上,得最终结果。让DQN学习目的更强烈,如若当前希望价值紧要由环境意况控制,Value值大,所有Advantage波动不大;假诺指望价值重要由Action决定,Value值小,Advantage波动大。分解让学习目标更平稳、精确,DQN对环境意况臆度能力更强。

第5个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值,输出一个Value,及Action数量
Advantage值。V值分别加到每个Advantage值上,得最终结果。让DQN学习目的更彰着,如果当先前时期待价值紧要由环境气象控制,Value值大,所有Advantage波动不大;假如期待价值重要由Action决定,Value值小,Advantage波动大。分解让学习目的更稳定、精确,DQN对环境意况估算能力更强。

落实带Trick DQN。任务环境
GridWorld导航类水言纟工。GridWorld包含一个hero,4个goal,2个fire。控制hero移动,每便向上、下、左、右方向活动一步,多触碰goal(奖励值1),避开fire(奖励值-1)。游戏目的,限度步数内得到最多分数。Agent
直接通过GridWorld图像学习决定hero移动最优政策。

实现带Trick DQN。任务环境
GridWorld导航类水言纟工。GridWorld包含一个hero,4个goal,2个fire。控制hero移动,每一回向上、下、左、右方向活动一步,多触碰goal(奖励值1),避开fire(奖励值-1)。游戏目的,限度步数内得到最多分数。Agent
直接通过GridWorld图像学习决定hero移动最优政策。

开创GridWorld任务环境。载入倚重库,itertools迭代操作,scipy.misc、matplotlib.pyplot绘图,磨炼时间长,os定期储存模型文件。

创制GridWorld任务环境。载入依赖库,itertools迭代操作,scipy.misc、matplotlib.pyplot绘图,训练时间长,os定期储存模型文件。

成立环境内物体对象class。环境物体属性,coordinates(x,y坐标)、size(尺寸)、intensity(亮度值)、channel(RGB颜色通道)、reward(奖励值)、name(名称)。

创建环境内物体对象class。环境物体属性,coordinates(x,y坐标)、size(尺寸)、intensity(亮度值)、channel(RGB颜色通道)、reward(奖励值)、name(名称)。

创设GridWorld环境class,伊始化方法只传入参数环境size。环境长、宽为输入size,环境Action
Space设4,开首化环境物体对象列表。self.reset()方法重置环境,拿到起初observation(GridWorld图像),plt.imshow展示observation。

成立GridWorld环境class,起先化方法只传入参数环境size。环境长、宽为输入size,环境Action
Space设4,最先化环境物体对象列表。self.reset()方法重置环境,得到先河observation(GridWorld图像),plt.imshow体现observation。

概念环境reset方法。创设所有GridWorld物体,1个hero(用户控制目的)、4个goal(reward
1)、2个fire(reward
-1),添加到实体对象列表self.objects。self.newPosition()成立物体地方,随机选拔没有被霸占新职务。物有物体size、intensity
1,hero channel 2(肉色),goal channel 1(绿色),fire channel
0(黄色)。self.renderEnv()绘制GridWorld图像,state。

概念环境reset方法。创设所有GridWorld物体,1个hero(用户控制目的)、4个goal(reward
1)、2个fire(reward
-1),添加到物体对象列表self.objects。self.newPosition()制造物体地点,随机挑选没有被霸占新岗位。物有物体size、intensity
1,hero channel 2(红色),goal channel 1(红色),fire channel
0(黑色)。self.renderEnv()绘制GridWorld图像,state。

落实移动英雄角色方法,传入值0、1、2、3五个数字,分别代表上、下、左、右。函数依照输入操作英雄移动。要是运动该方向会造成英雄出界,不会进行任何活动。

贯彻移动英雄角色方法,传入值0、1、2、3五个数字,分别代表上、下、左、右。函数依据输入操作英雄移动。假若运动该方向会造成英雄出界,不会举办其它活动。

概念newPosition方法,选用一个跟现有物体不争辩地方。itertools.product方法拿到多少个变量所有结成,创造环境size允许持有地方集合points,获取目前拥有物体地方集合currentPositions,从points去掉currentPositions,剩下可用位置。np.random.choice随机抽取一个可用地点重临。

概念newPosition方法,拔取一个跟现有物体不顶牛位置。itertools.product方法赢得几个变量所有组成,创设环境size允许持有职位集合points,获取近日颇具物体地点集合currentPositions,从points去掉currentPositions,剩下可用位置。np.random.choice随机抽取一个可用地点再次来到。

定义checkGoal函数。检查hero是否触碰goal、fire。从objects获取hero,其他物体对象放置others列表。编历others列表,假如物体和坐标与hero完全一致,判定触碰。依据触碰物体销毁,self.newPosition()方法在任意地方再次生成物体,再次来到物体reward值(goal
1,fire -1)。

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

创设长宛size+2、颜色通道数 3
图片。起始值全1,代表全白色。最外面内部像素颜色值全体赋0,代表肉色。遍历物体对象列表self.objects,设置物体亮度值。scipy.misc.imresize将图像从原有大小resize
84x84x3尺寸,正常游玩图像尺寸。

创制长宛size+2、颜色通道数 3
图片。先河值全1,代表全白色。最外侧内部像素颜色值全体赋0,代表灰色。遍历物体对象列表self.objects,设置物体亮度值。scipy.misc.imresize将图像从原始大小resize
84x84x3尺寸,正常游玩图像尺寸。

概念GridWorld环境举办一步Action方法。输入参数Action,self.moveChart(action)移动hero地方,self.checkGoal()检测hero是否触碰物体,获得reward、done标记。self.renderEnv获取环境图像state,重临state、reward、done。

概念GridWorld环境举行一步Action方法。输入参数Action,self.moveChart(action)移动hero地方,self.checkGoal()检测hero是否触碰物体,得到reward、done标记。self.renderEnv获取环境图像state,再次来到state、reward、done。

调用gameEnv类开端化方法,设置size
5,创建5×5大小GridWorld环境,每一次创设GridWorld环境随机变化。小尺寸环境相对容易学习,大尺寸较难,磨炼时间更长。

调用gameEnv类起首化方法,设置size
5,创制5×5大小GridWorld环境,每回创造GridWorld环境随机生成。小尺寸环境相对容易学习,大尺寸较难,磨炼时间更长。

规划DQN(Deep
Q-Network)网络。使用卷积层,能够间接从环境原始像素学习策略。输入scalarInput,扁平化长为84x84x3=21168向量,苏醒成[-1,84,84,3]尺寸图片ImageIn。tf.contrib.layers.convolution2d成立第1个卷积层,卷积核尺寸8×8,步长4×4,输出通道数(filter数量)32,padding模型VALID,bias先河化器空。用4×4涨幅和VALID模型padding,第1层卷积输出维度20x20x32。第2层卷积尺寸4×4,步长2×2,输出通道数64,输出维度9x9x64。第3层卷积尺寸3×3,步长1×1,输出通道数64,输出维度7x7x64。第4层卷积尺寸7×7,步长1×1,输出通道数512,空间尺寸只同意在一个地点卷积,,输出维度1x1x512。

规划DQN(Deep
Q-Network)网络。使用卷积层,可以直接从环境原始像素学习策略。输入scalarInput,扁平化长为84x84x3=21168向量,復苏成[-1,84,84,3]尺寸图片ImageIn。tf.contrib.layers.convolution2d创设第1个卷积层,卷积核尺寸8×8,步长4×4,输出通道数(filter数量)32,padding模型VALID,bias先导化器空。用4×4升幅和VALID模型padding,第1层卷积输出维度20x20x32。第2层卷积尺寸4×4,步长2×2,输出通道数64,输出维度9x9x64。第3层卷积尺寸3×3,步长1×1,输出通道数64,输出维度7x7x64。第4层卷积尺寸7×7,步长1×1,输出通道数512,空间尺寸只同目的在于一个岗位卷积,,输出维度1x1x512。

tf.split(),第4个卷积层输出conv4平均拆分两段,streamAC、streamVC,Dueling
DQN Advantage Function(Action带来的价值)和Value
Function(环境本身价值)。tf.split函数第2参数代表要拆分成几段。第3参数代表要拆分多少个维度。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针对环境统一的,输出数量
1。Q值由Value、advantage复合成,Value加上缩小均值Advantage。Advantage减去均值操作
tf.subtract,均值统计tf.reduce_mean函数(reduce_indices
1,代表Action数量维度)。最后输出Action,Q值最大Action,tf.argmax。

tf.split(),第4个卷积层输出conv4平均拆分两段,streamAC、streamVC,Dueling
DQN Advantage Function(Action带来的市值)和Value
Function(环境本身价值)。tf.split函数第2参数代表要拆分成几段。第3参数代表要拆分多少个维度。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针对环境统一的,输出数量
1。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)。

概念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-4
Adam优化器优化预测Q值和目的Q值偏差。

定义loss,tf.square、tf.reduce_mean总括targetQ和Q均方误差,学习速率1e-4
艾达(Ada)m优化器优化预测Q值和对象Q值偏差。

实现Experience Replay策略。定义experience_buffer
class。伊始化定义buffer_size存储样本最大容量,创设buffer列表。定义向经buffer添加元素方法。假设超越buffer最大容量,清空最早样本,列表末尾添加新元素。定义样本抽样格局,用random.sample()函数随机抽取一定数量样本。

实现Experience Replay策略。定义experience_buffer
class。开头化定义buffer_size存储样本最大容量,创立buffer列表。定义向经buffer添日币素方法。假使超越buffer最大容量,清空最早样本,列表末尾添加新元素。定义样本抽样格局,用random.sample()函数随机抽取一定数额样本。

概念84x84x3 states扁平化 1维向量函数processState,方便后边堆叠样本。

概念84x84x3 states扁平化 1维向量函数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值不能够在三回迭代间波动太大,锻练非常不安定、失控,陷入目标Q值和预测Q值反馈循环。需要安静目的Q值练习网络,缓慢学习target
DQN网络出口目的Q值,主网络优化目标Q值和展望Q值间loss,target
DQN跟随主DQN缓慢学习。函数updateTargetGraph创设改进target
DQN模型参数操作,函数updateTarget执行操作。

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值不能够在五次迭代间波动太大,操练分外不安宁、失控,陷入目标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执行三遍模型参数更新,4。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学习速率。

DQN网络操练过程参数。batch_size,每一次从experience
buffer获取样本数,32。更新频率update_freq,每隔多少step执行两遍模型参数更新,4。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模型参数操作。

Qnetwork类先导化mainQN和匡助targetQN。发轫化所有模型参数。trainables获取具有可磨练参数。updateTargetGraph创设立异target
DQN模型参数操作。

experience_buffer创制experience replay
class,设置当前随机Action概率e,总计e每一步衰减值stepDrop。起头化储存每个episode的reward列表rList,总步数total_steps。创设模型训练保存器(Saver)检查保存目录是否留存。

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。

始建默认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,获得接下来事态s1、reward、done标记。processState对s1扁平化处理,s、a、r、s1、d传入episodeBuffer存储。

开创内层循环,每趟迭代执行Action。总步数紧跟于pre_train_steps,强制用随机Action,只从随机Action学习,不深化过程。达到pre_train_steps,保留较小概率随机选拔Action。不随机选用Action,传入当前状态s给主DQN,预测得到相应执行Action。env.step()执行一步Action,得到接下来事态s1、reward、done标记。processState对s1扁平化处理,s、a、r、s1、d传入episodeBuffer存储。

总步数超越pre_train_steps,持续下跌随机拔取Action概率e,直到最低值endE。每当总步数达到update_freq整数部,举行一遍磨炼,模型参数更新。从myBuffer中sample出一个batch_size样本。磨炼样本第3列消息,下一景观s1,传入mainQN,执行main.predict,得到主模型采取Action。s1传来协助targetQN,得到s1状态下具有Action的Q值。mainQN输出Action
,接纳targetQN输出Q,得到doubleQ。五个DQN网络把选取Action和输出Q值六个操作分隔开,Double
DQN。磨炼样本第2列音讯,当前reward,加doubleQ乘以衰减全面γ,得到学习目的targetQ。传入当前状态s,学习目的targetQ和事实上采纳Action,执行updateTarget函数,执行targetQN模型参数更新(缓慢向mainQN学习)。完整完成一遍锻炼过程。每个step截止,累计当前这步获取reward,更新当前情形为下一步试验做准备。假若done标记为True,直接中断episode试验。

总步数超越pre_train_steps,持续下跌随机选用Action概率e,直到最低值endE。每当总步数达到update_freq整数部,举办一回磨炼,模型参数更新。从myBuffer中sample出一个batch_size样本。磨练样本第3列新闻,下一情状s1,传入mainQN,执行main.predict,拿到主模型采取Action。s1传到协助targetQN,得到s1状态下有所Action的Q值。mainQN输出Action
,拔取targetQN输出Q,得到doubleQ。六个DQN网络把选用Action和出口Q值四个操作分隔开,Double
DQN。训练样本第2列信息,当前reward,加doubleQ乘以衰减系数γ,得到读书目的targetQ。传入当前状态s,学习目的targetQ和实在采取Action,执行updateTarget函数,执行targetQN模型参数更新(缓慢向mainQN学习)。完整完成三回锻练过程。每个step截至,累计当前这步获取reward,更新当前状态为下一步试验做准备。假设done标记为True,直接中断episode试验。

episode内部episodeBuffer添加到myBuffer,作未来操练抽样数据集。当前episode
reward添加到rList。每25个episode显示平均reward值。每1000个episode或任何训练完成,保存当前模型。

episode内部episodeBuffer添加到myBuffer,作未来操练抽样数据集。当前episode
reward添加到rList。每25个episode展示平均reward值。每1000个episode或任何磨练完成,保存当前模型。

始于200个episode内,完全随机Action的前10000步内,平均可以赢得reward在2附近,基础baseline。

千帆竞发200个episode内,完全随机Action的前10000步内,平均可以取得reward在2邻近,基础baseline。

教练最终episode输出,平均reward 22,非凡大提高。

操练最后episode输出,平均reward 22,异常大提升。

测算每100个episode平均reward,plt.plot体现reward变化趋势。从第1000个episode起头,reward迅速进步,到第4000个episode基本达到顶峰,后面进去平台期,提高不大。

总计每100个episode平均reward,plt.plot呈现reward变化趋势。从第1000个episode开端,reward飞快进步,到第4000个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)
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实战》

参考资料:
《TensorFlow实战》

迎接付费咨询(150元每时辰),我的微信:qingxingfengzi

迎接付费咨询(150元每时辰),我的微信:qingxingfengzi

相关文章