Policy Gradients(Tensorflow)

Policy Gradients

  • Q learning学习奖惩值, 根据自己认为的高价值选行为, Policy Gradients不通过分析奖励值, 直接输出行为的方法
  • 最大好处就是, 它能在一个连续区间内挑选动作, 而基于值的, 如 Q-learning, 做不到

Policy Gradients的反向传递

  • 没有误差反向传递
  • 反向传递目的是让这次被选中的行为更有可能在下次发生. 通过reward 奖惩来决定被增加被选的概率

核心思想

  • 也是靠奖励来左右神经网络反向传递.

  • 观测的信息通过神经网络分析, 选出了①行为, 直接进行反向传递, 使之下次被选的可能性增加,根据奖惩信息,如果行为好增加动作可能性增加的幅度 ,不好则减低

算法

不像 Value-based 方法 (Q learning, Sarsa), 但他也要接受环境信息 (observation), 不同的是他要输出不是 action 的 value, 而是具体的那一个 action, policy gradient 跳过了 value 这个阶段

  • 第一个算法是一种基于 整条回合数据 的更新
    在这里插入图片描述
    更新神经网络参数时:
  • 更新参数依据先往这个方向更新,根据Vt判断方向是否正确,如果正确,则在这个方向幅度大一点;Vt不好幅度小一点,下次选中的概率略微少一点
  • log形式的概率是为了更好地收敛性
  • 以回合为基础,回合完了一次性更新(Qlearning单步更新)

代码结构

在这里插入图片描述

建立 policy 神经网络

  • 第一层建立全连接层
  • 第二层输出所有action
  • 将每个输出的值转换成概率
  • 计算误差(policy 是没有误差的)此处‘loss’是指反向传递后,使下一次选择这个动作的概率的增加一点乘以增加的幅度
   self.all_act_prob = tf.nn.softmax(all_act, name='act_prob')  # 激励函数 softmax 出概率

        with tf.name_scope('loss'):
            # 最大化 总体 reward (log_p * R) 就是在最小化 -(log_p * R), 而 tf 的功能里只有最小化 loss
            neg_log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=all_act, labels=self.tf_acts) # 所选 action 的概率 -log 值
            # 下面的方式是一样的:
            # neg_log_prob = tf.reduce_sum(-tf.log(self.all_act_prob)*tf.one_hot(self.tf_acts, self.n_actions), axis=1)
            loss = tf.reduce_mean(neg_log_prob * self.tf_vt)  # (vt = 本reward + 衰减的未来reward) 引导参数的梯度下降
  • 在这里插入图片描述tf.log(self.all_act_prob),all_act_prob所有action的概率
  • 放到记忆库中action是单个单个的值,如第0个action,放到记忆库中是0,第一个action放到记忆库中是1,。。。如果要进行如上的计算,最好变成矩阵的形式与概率tf.log(self.all_act_prob)相乘,one_hot(self.tf_acts, self.n_actions)采取action为1(没有采取为0)与相乘,筛选出采取了哪个对应action的概率
  • 负号 因为Tensorflow只能最小化loss。因为是想要得到奖励概率越来越大所以用负号将minimize换成max
  • 在这里插入图片描述
    self.tf_vt幅度

选行为

不通过 Q value 来选定的, 而是用概率来选定. 虽然不用epsilon-greedy, 也具有一定的随机性.

 def choose_action(self, observation):
        prob_weights = self.sess.run(self.all_act_prob, feed_dict={self.tf_obs: observation[np.newaxis, :]})    # 所有 action 的概率
        action = np.random.choice(range(prob_weights.shape[1]), p=prob_weights.ravel())  # 根据概率来选 action
        return action
  • np.random.choice()根据概率来产生随机数

存储回合

将这一步的 observation, action, reward 加到列表中去. 因为本回合完毕之后要清空列表, 然后存储下一回合的数据, 所以会在 learn() 当中进行清空列表的动作.

 def store_transition(self, s, a, r):
        self.ep_obs.append(s)
        self.ep_as.append(a)
        self.ep_rs.append(r)

学习

    def learn(self):
        # 衰减, 并标准化这回合的 reward
        discounted_ep_rs_norm = self._discount_and_norm_rewards()   # 功能再面

        # train on episode
        self.sess.run(self.train_op, feed_dict={
             self.tf_obs: np.vstack(self.ep_obs),  # shape=[None, n_obs]
             self.tf_acts: np.array(self.ep_as),  # shape=[None, ]
             self.tf_vt: discounted_ep_rs_norm,  # shape=[None, ]
        })

        self.ep_obs, self.ep_as, self.ep_rs = [], [], []    # 清空回合 data
        return discounted_ep_rs_norm    # 返回这一回合的 state-action value
  • 将reward处理过程放到train
  • 输入observation、action、vt到Tensorflow
  • 清空列表用于下一个回合
发布了23 篇原创文章 · 获赞 19 · 访问量 3007

猜你喜欢

转载自blog.csdn.net/komorebi6/article/details/105458905