PPO強化學習

一、什麼是PPO

PPO(Proximal Policy Optimization)是一種強化學習演算法,它使用了一個新的優化目標,可以大大提高演算法的穩定性和效果。PPO演算法是由OpenAI的研究人員Schulman等人於2017年提出的,是一種基於策略梯度的強化學習演算法。

PPO演算法的目標是最大化累積獎勵,即最大化智能體與環境互動過程中所獲得的獎勵的總和。為了達到這個目標,PPO演算法同時優化策略函數和價值函數。在策略函數優化的過程中,PPO演算法使用一種叫做「重要性採樣比率裁剪」的技術,來防止策略函數更新過於劇烈而導致性能下降。

二、PPO演算法的框架

在PPO演算法中,智能體會和環境互動,從環境中收集經驗,然後使用這些經驗來更新策略函數和價值函數。整個演算法的流程可以用下面這個框架來表示:

Initialize policy network πθ(a|s)
Initialize value function Vϕ(s)

for iteration = 1, 2, ..., N do:
   Collect set of M trajectories {τi} using current policy πθ
   Compute rewards and advantages for each time step in each trajectory
   Update the policy by maximizing the PPO-clip objective:
         Lclip(θ) = E[min(ratio * A, clip(ratio, 1-e, 1+e) * A)]
   Update the value function by minimizing the mean-squared error:
         LV(ϕ) = E[(Vϕ(s) − Vtarget(s))^2]
end for

其中,πθ表示策略函數,Vϕ表示價值函數,|s表示狀態變數,|a表示動作變數。在每個迭代中,我們會從環境中收集一些軌跡,然後使用重要性採樣比率裁剪的方法更新策略函數和價值函數。

三、PPO演算法的優缺點

優點

與之前的策略梯度方法相比,PPO演算法的穩定性得到了非常大的提升。在Dota 2遊戲中,PPO演算法被用來實現了一個AI玩家,在人類職業選手中表現良好。

此外,PPO演算法還沒有其他演算法那麼敏感,對於不同的超參數和網路結構變化,其效果並不會發生很大的變化。

缺點

PPO演算法的主要缺點是計算複雜度比較高,同時也需要大量的經驗。在一些簡單的環境中,PPO演算法可能會比其他演算法表現的更差。此外,PPO演算法的訓練速度也比較慢,需要較長的訓練時間。

四、PPO演算法的應用

PPO演算法已經被廣泛應用於機器人控制、遊戲AI、自然語言處理等領域。在AlphaGo Zero中,PPO演算法被用來實現強化學習部分,這也是讓AlphaGo Zero在圍棋比賽中贏得勝利的關鍵之一。

五、PPO演算法的代碼示例

以下是使用Python和TensorFlow實現的PPO演算法的代碼示例:

import tensorflow as tf
import numpy as np

class PPO(object):
    def __init__(self, sess, state_dim, action_dim):

        self.sess = sess
        self.state_dim = state_dim
        self.action_dim = action_dim

        self.gamma = 0.99 
        self.lamda = 0.95 
        self.epochs = 10
        self.batch_size = 64
        self.clip_range = 0.2 

        self.actor_lr = 0.001
        self.critic_lr = 0.01

        self._build_graph()

        self.sess.run(tf.global_variables_initializer())
    
    # Build TensorFlow graph
    def _build_graph(self):
        self.states = tf.placeholder(tf.float32, [None, self.state_dim], 'states')
        self.actions = tf.placeholder(tf.int32, [None, ], 'actions')
        self.returns = tf.placeholder(tf.float32, [None, ], 'returns')
        self.advs = tf.placeholder(tf.float32, [None, ], 'advantages')

        actor_inputs = self.states
        hidden1 = tf.layers.dense(actor_inputs, 64, tf.nn.tanh, name='actor_fc1')
        hidden2 = tf.layers.dense(hidden1, 64, tf.nn.tanh, name='actor_fc2')
        hidden3 = tf.layers.dense(hidden2, 32, tf.nn.tanh, name='actor_fc3')
        self.logits = tf.layers.dense(hidden3, self.action_dim, name='actor_fc4')
        self.probs = tf.nn.softmax(self.logits)

        self.values = tf.squeeze(tf.layers.dense(self.states, 1))

        action_one_hot = tf.one_hot(self.actions, self.action_dim)
        selected_log_probs = tf.reduce_sum(action_one_hot * tf.log(self.probs), axis=1)

        with tf.variable_scope('actor_loss'):
            unclipped_ratios = tf.exp(selected_log_probs - tf.stop_gradient(tf.log(tf.reduce_sum(tf.exp(self.logits), axis=1))))
            clipped_ratios = tf.clip_by_value(unclipped_ratios, 1-self.clip_range, 1+self.clip_range)
            surrogate1 = unclipped_ratios * self.advs
            surrogate2 = clipped_ratios * self.advs
            self.actor_loss = -tf.reduce_mean(tf.minimum(surrogate1, surrogate2))

        with tf.variable_scope('critic_loss'):
            self.critic_loss = tf.reduce_mean(tf.square(self.values - self.returns))

        with tf.variable_scope('train'):
            self.actor_train_op = tf.train.AdamOptimizer(self.actor_lr).minimize(self.actor_loss)
            self.critic_train_op = tf.train.AdamOptimizer(self.critic_lr).minimize(self.critic_loss)
    
    # Given observation, return action and value
    def get_action_value(self, state):
        probs = self.sess.run(self.probs, {self.states: state})[0]
        action = np.random.choice(self.action_dim, p=probs)
        value = self.sess.run(self.values, {self.states: state})[0]
        return action, value

    # Update policy using PPO
    def update(self, states, actions, returns, advs):
        for epoch in range(self.epochs):
            # Shuffle data
            sample_indices = np.arange(len(states))
            np.random.shuffle(sample_indices)

            # Split data into batches
            for i in range(len(states) // self.batch_size):

                # Get batch of data
                indices = sample_indices[self.batch_size*i : self.batch_size*i+self.batch_size]
                batch_states = states[indices]
                batch_actions = actions[indices]
                batch_returns = returns[indices]
                batch_advs = advs[indices]

                # Training step
                actor_loss, _, critic_loss, _ = self.sess.run([self.actor_loss, self.actor_train_op, self.critic_loss, self.critic_train_op], feed_dict={self.states: batch_states,
                                self.actions: batch_actions,
                                self.returns: batch_returns,
                                self.advs: batch_advs})

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/289298.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-24 03:02
下一篇 2024-12-24 03:02

相關推薦

  • 深入理解PPO演算法

    一、什麼是PPO演算法 PPO(Proximal Policy Optimization)演算法是一種基於策略梯度的強化學習演算法,通過限制新策略與舊策略之間的差異大小,來訓練一個更加穩…

    編程 2025-02-15

發表回復

登錄後才能評論