lutein / RL-with-gym

tensorflow, gym, RL, Deep deterministic policy gradient

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

deep deterministic policy gradient

gym

  • constant set:
    RENDER_ENV = True
    # Use Gym Monitor
    GYM_MONITOR_EN = True
    # Gym environment
    ENV_NAME = 'Pendulum-v0'
    # Directory for storing gym results
    MONITOR_DIR = './results/gym_ddpg'
    # File for saving reward and qmax
    RESULTS_FILE = './results/rewards.npz'
    RANDOM_SEED = 1234
    # Size of replay buffer
    BUFFER_SIZE = 10000
    MINIBATCH_SIZE = 128
  • functions:

这里的动作和状态维数应该是常数。

初始动作的产生带有exploration噪声(使用随机的动作):

    a = actor.predict(np.reshape(s, (1, s_dim))) + (1. / (1. + i))
    #reshape(a, newshape, order='C')

而在定义actor.predict时为:

    def predict(self, state):
        return self.sess.run(self.out, feed_dict={self.inputs: state})
    #self.out = network.get_actor_out(is_target=False)=self.actor_target_y = self._create_actors(self.state_feature_target)

然后执行动作,获得下一步的状态和奖励:

    s2, r, terminal, info = env.step(a[0])

具体代码:

    #1. 打开模拟环境
    env = gym.make(ENV_NAME)#ENV_NAME指的是例如:"Pendulum-v0","CartPole-v0"之类的给定环境名称
    #2. 初始化
    s = env.reset() #initialize, before every episode begin, state needs initialize
    env.render()
    action_dim = env.action_space.shape[0]
    state_dim = env.observation_space.shape[0]
    action_bound = env.action_space.high#env.action_space.high = -env.action_space.low
    #3. 产生动作,并根据动作产生下一步状态和奖励
    next_state,reward,done,_ = env.step(action)
    #随机
    np.random.seed(RANDOM_SEED)
    tf.set_random_seed(RANDOM_SEED)
    env.seed(RANDOM_SEED)
    #Monitor
    if GYM_MONITOR_EN:
       if not RENDER_ENV:
          env = wrappers.Monitor(env, MONITOR_DIR, video_callable=False, force=True)
       else:
          env = wrappers.Monitor(env, MONITOR_DIR, force=True)
    if GYM_MONITOR_EN:
       env.monitor.close()

experience replay

  • 伪代码

preview

  • 理解:

在每次训练时,先初始化状态,然后在训练的每次迭代时,要么随机选取一个动作(exploration),要么选择使得Q值最大的动作。在模拟器中执行动作并观察奖励和状态,将状态转移矩阵存储在经验池中。

如果迭代结束,那么最后y_j就是反馈值,如果没有结束,那么equation2就是 equation1,接着用梯度下降来最小化equation3

相当于课程PPT中讲的那个图:这里的Q可以理解为轨迹?目的是产生使得轨迹尽可能接近的动作。

所以说就是存储轨迹?

  • 代码

一共四个子函数:

add:输入当前s,a,r,t和下一步s2,写成矩阵(s,a,r,t,s2),如果此时计数小于缓冲区大小,就将经验矩阵加到缓冲区右侧,并且计数加一;如果计数已经超过缓冲区大小,左出栈,缓冲区附加经验矩阵。

size:返回计数值(初始为0)

sample_batch:输入batch_size,如果计数值小于批尺寸,batch就随机选择一组缓冲区和计数值;如果大于批尺寸,就随机选缓冲区和批尺寸。其中的第0,1,2,3,4列分别代表s_batch,a_batch,r_batch,t_batch,s2_batch,最终返回的也是这些值。

关于批尺寸:batch的选择决定的是下降方向。大概指的就是每次训练的数据集大小。

如果数据集较小,可以采用全数据集(Full Batch Learning),有两个好处:由全数据集确定的方向能更好地代表样本总体,准确地朝向极值所在方向;不同权重梯度值差别大导致的选取全局学习率困难,如果用全数据集的话就可以使用Rprop,只基于梯度符号,针对性单独更新权值。

全数据集的对立面是在线学习(Online Learning),每次只训练一个样本,batch_size=1

clear: 队列和计数值均清零

调用:

    from replay_buffer import ReplayBuffer
    #in function train(), inputs are constant defined in part 1, 10000, 1234
    replay_buffer = ReplayBuffer(BUFFER_SIZE, RANDOM_SEED)
    replay_buffer.add(np.reshape(s, (s_dim,)), np.reshape(a, (a_dim,)), r,
                                  terminal, np.reshape(s2, (s_dim,)))
    # Keep adding experience to the memory until
    # there are at least minibatch size samples
    if replay_buffer.size() > MINIBATCH_SIZE:
        s_batch, a_batch, r_batch, t_batch, s2_batch = \
            replay_buffer.sample_batch(MINIBATCH_SIZE)
        #经验池满了之后,可以计算目标Q值了

计算reward, equation2

如何获得q:其中函数critic_target.predict的输入是下一状态,和以此为输入的下一目标动作,输出目标value

    target_q = critic_target.predict(s2_batch, actor_target.predict(s2_batch))

然后计算equation2,按照2中的公式:

    y_i = []
    for k in range(MINIBATCH_SIZE):
         if t_batch[k]:
             y_i.append(r_batch[k])
         else:
             y_i.append(r_batch[k] + GAMMA * target_q[k])#GAMMA=0.99, dicsount factor

为了得到最大Q,需要将其放入网络中训练

    predicted_q_value, _ = critic.train(s_batch, a_batch, np.reshape(y_i, (MINIBATCH_SIZE, 1)))

每个episode中最大Q值的平均值:

    #ep_ave_max_q += np.amax(predicted_q_value)
    ep_ave_max_q += np.mean(predicted_q_value)

用随机梯度法更新四个网络

    # Update the actor policy using the sampled gradient
    a_outs = actor.predict(s_batch)
     grads = critic.action_gradients(s_batch, a_outs)
    actor.train(s_batch, grads[0])
    
    # Update target networks
    actor_target.train()
    critic_target.train()

策略梯度

  • 理论

注意:critic给出的分数是从当前到游戏结束的总reward,而系统返回的是当前获得的reward

反向传播:调整actor网络参数使得critic的打分尽量高

  • equation1是actor函数。此处s是输入的state,equation1是网络自己的参数。
  • Q (s, a ; w)是critic函数。此处s和a是输入的state、action,w是网络自己的参数。
  • 优化目标是让Q (s , a ; w) 尽量高
  • 梯度(被称为policy gradient)是 ![equation](http://latex.codecogs.com/svg.latex?\frac{\partial\mu}{\partial\theta}\frac{\partial Q}{\partial a}) ,其实很像是反向传播的chain rule:你可以把equation1看作是a,因为equation1的输出是action。(这个是deterministic policy gradient,跟传统的不太一样。)
  • 然后用梯度上升更新equation1。(不是梯度下降,因为我们想让Q尽量大)。

理解:先随机产生一个状态,并选取一个动作,然后系统返回下一个状态的动作,状态,reward

训练整体流程:

  • 算出actor网络输出关于所有参数的gradient
  • 算出critic网络输出关于a的梯度
  • 把两个梯度相乘得到policy gradient
  • 最后把policy gradient加到actor网络所有参数上

About

tensorflow, gym, RL, Deep deterministic policy gradient


Languages

Language:Python 94.4%Language:C++ 5.6%