日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【强化学习】Policy Gradient(策略梯度)算法详解

發布時間:2023/12/16 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【强化学习】Policy Gradient(策略梯度)算法详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 Policy Gradient簡介

1.1 基于策略和基于值的強化學習方法不同

強化學習是一個通過獎懲來學習正確行為的機制。家族中有很多種不一樣的成員,有學習獎懲值,根據自己認為的高價值選行為,比如Q-Learning,Deep-Q-network,也有不通過分析獎懲值,直接輸出行為的方法,這就是今天要說的Policy Gradient加上一個神經網絡來輸出預測的動作。對比起以值為基礎的方法,Policy Gradient直接輸出動作的最大好處就是,他能在一個連續區間內挑選動作,而基于值的,比如Q-Learning,它如果在無窮多得動作種計算價值,從而選擇行為,這他可吃不消。

1.2 算法更新

有了神經網絡當然方便,但是,我們怎么進行神經網絡的誤差反向傳遞呢?Policy Gradient的誤差又是什么呢?答案是沒有誤差。但是他的確是在進行某一種的反向傳遞。這種反向傳遞的目的是讓這次被選中的行為更有可能在下次發生。但是我們要怎么確定這個行為是不是應當被增加被選的概率呢?這時候,reward獎懲正可以在這個時候排上用場。

1.3 具體更新步驟

現在演示一遍,觀測的信息通過神經網絡分析,選出了左邊的行為,我們直接進行反向傳遞,使之下次被選的可能性增加,但是獎懲信息卻告訴我們,這次的行為是不好的,那我們的動作可能性增加的幅度隨之被減低。這樣就能靠獎勵來左右我們的神經網絡反向傳遞。我們再舉一個例子,假如這次的觀測信息讓神經網絡選擇了右邊的行為,右邊的行為隨之想要進行反向傳遞,使右邊的行為下次被多選一點,這時,獎懲信息也來了,告訴我們這是好行為,那我們就在這次反向傳遞的時候加大力度,讓他下次被多選的幅度更猛烈。這就是Policy Gradient的核心思想。

2 Policy Gradient算法更新

全部代碼免費下載地址如下:
https://download.csdn.net/download/shoppingend/85194070

2.1 要點

Policy Gradient是RL中一個大家族,他不像Value-based方法(Q-Learning,Sarsa),但他也要接收環境信息(observation),不同的是他要輸出不是action的value,而是具體的那一個action,這樣Policy Gradient就跳過了value這個階段。而且Policy Gradient最大的一個優勢是:輸出的這個action可以是一個連續的值,之前我們說到的value-based方法輸出的都是不連續的值,然后再選擇值最大的action。而Policy Gradient可以在一個連續分布上選取action。

2.2 算法

我們介紹最簡單的Policy Gradient算法是一種基于整條回合數據的更新,也叫REINFORCE方法。這種方法是Policy Gradient的最基本方法,有了這個的基礎,我們再來做更高級的。

Δ(log(Policy(s,a))*V表示在狀態s對所選動作a的吃驚度,如果Policy(s,a)概率越小,反向的log(Policy(s,a))(即-log§)反而越大。如果在Policy(s,a)很小的情況下,拿到了一個大的R,也就是大的V,那-Δ(log(Policy(s,a))*V就更大,表示更吃驚,(我選了一個不常選的動作,卻發現原來它能得到了一個好的reward,那我就得對我這次的參數進行一個大幅修改)。這就是吃驚度的物理意義了。

2.3 算法代碼形成

先定義主更新的循環:

import gym from RL_brain import PolicyGradient import matplotlib.pyplot as pltRENDER = False # 在屏幕上顯示模擬窗口會拖慢運行速度, 我們等計算機學得差不多了再顯示模擬 DISPLAY_REWARD_THRESHOLD = 400 # 當 回合總 reward 大于 400 時顯示模擬窗口env = gym.make('CartPole-v0') # CartPole 這個模擬 env = env.unwrapped # 取消限制 env.seed(1) # 普通的 Policy gradient 方法, 使得回合的 variance 比較大, 所以我們選了一個好點的隨機種子print(env.action_space) # 顯示可用 action print(env.observation_space) # 顯示可用 state 的 observation print(env.observation_space.high) # 顯示 observation 最高值 print(env.observation_space.low) # 顯示 observation 最低值# 定義 RL = PolicyGradient(n_actions=env.action_space.n,n_features=env.observation_space.shape[0],learning_rate=0.02,reward_decay=0.99, # gamma# output_graph=True, # 輸出 tensorboard 文件 )

主循環:

for i_episode in range(3000):observation = env.reset()while True:if RENDER: env.render()action = RL.choose_action(observation)observation_, reward, done, info = env.step(action)RL.store_transition(observation, action, reward) # 存儲這一回合的 transitionif done:ep_rs_sum = sum(RL.ep_rs)if 'running_reward' not in globals():running_reward = ep_rs_sumelse:running_reward = running_reward * 0.99 + ep_rs_sum * 0.01if running_reward > DISPLAY_REWARD_THRESHOLD: RENDER = True # 判斷是否顯示模擬print("episode:", i_episode, " reward:", int(running_reward))vt = RL.learn() # 學習, 輸出 vt, 我們下節課講這個 vt 的作用if i_episode == 0:plt.plot(vt) # plot 這個回合的 vtplt.xlabel('episode steps')plt.ylabel('normalized state-action value')plt.show()breakobservation = observation_

3 Policy Gradient思維決策

3.1 代碼主結構

用基本的 Policy gradient 算法,和之前的 value-based 算法看上去很類似。

class PolicyGradient:# 初始化 (有改變)def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):# 建立 policy gradient 神經網絡 (有改變)def _build_net(self):# 選行為 (有改變)def choose_action(self, observation):# 存儲回合 transition (有改變)def store_transition(self, s, a, r):# 學習更新參數 (有改變)def learn(self, s, a, r, s_):# 衰減回合的 reward (新內容)def _discount_and_norm_rewards(self):

初始化:

class PolicyGradient:def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):self.n_actions = n_actionsself.n_features = n_featuresself.lr = learning_rate # 學習率self.gamma = reward_decay # reward 遞減率self.ep_obs, self.ep_as, self.ep_rs = [], [], [] # 這是我們存儲 回合信息的 listself._build_net() # 建立 policy 神經網絡self.sess = tf.Session()if output_graph: # 是否輸出 tensorboard 文件# $ tensorboard --logdir=logs# http://0.0.0.0:6006/# tf.train.SummaryWriter soon be deprecated, use followingtf.summary.FileWriter("logs/", self.sess.graph)self.sess.run(tf.global_variables_initializer())

3.2 建立Policy神經網絡

這次我們要建立的神經網絡是這樣的:

因為這是強化學習,所以神經網絡中沒有監督學習中的y label。取而代之的是我們選的action。

class PolicyGradient:def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):...def _build_net(self):with tf.name_scope('inputs'):self.tf_obs = tf.placeholder(tf.float32, [None, self.n_features], name="observations") # 接收 observationself.tf_acts = tf.placeholder(tf.int32, [None, ], name="actions_num") # 接收我們在這個回合中選過的 actionsself.tf_vt = tf.placeholder(tf.float32, [None, ], name="actions_value") # 接收每個 state-action 所對應的 value (通過 reward 計算)# fc1layer = tf.layers.dense(inputs=self.tf_obs,units=10, # 輸出個數activation=tf.nn.tanh, # 激勵函數kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),bias_initializer=tf.constant_initializer(0.1),name='fc1')# fc2all_act = tf.layers.dense(inputs=layer,units=self.n_actions, # 輸出個數activation=None, # 之后再加 Softmaxkernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),bias_initializer=tf.constant_initializer(0.1),name='fc2')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 的功能里只有最小化 lossneg_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) 引導參數的梯度下降with tf.name_scope('train'):self.train_op = tf.train.AdamOptimizer(self.lr).minimize(loss)

為什么使用loss=-log(prob)*Vt當作loss。簡單來說,上面提到了兩種行式來計算neg_log_prob,這兩種行式是一摸一樣的,只是第二個是第一個的展開行式。如果仔細看第一個行式,就是在神經網絡分類問題中的cross-entropy。使用softmax和神經網絡的參數按照這個真實標簽改進。這顯然和一個分類問題沒有太多的區別,我們能將這個neg_log_prob理解成cross-entropy的分類誤差。分類問題中的標簽是真實x對應的y,而我們Policy Gradient中,x是state,y就是它按照這個x所做的動作號碼。所以也可以理解成,它按照x做的動作永遠是對的(出來的動作永遠是正確標簽,他也永遠會按照這個正確標簽修改自己的參數。可是事實并不是這樣,他的動作不一定都是正確標簽,這就是強化學習(Policy Gradient)和監督學習(classification)的區別。
為了確保這個動作是正確標簽,我們的loss在原本的cross-entropy行式上乘以Vt,用Vt來告訴這個cross-entropy算出來的梯度是不是一個值得信賴的梯度。如果Vt小,或者是負的,就說明這個梯度下降是一個錯誤的方向,我們應該向著另一個方向更新參數,如果這個Vt是正的,或很大,Vt就會稱贊cross-entropy出來的梯度,并朝著這個方向梯度下降。下面有一張圖,也正是闡述的這個思想。

而為什么是loss=-log(prob)Vt而不是loss=-probVt。原因是這里的prob是從softmax出來的,而計算神經網絡里的所有參數梯度,使用到的就是cross-entropy,然后將這個梯度乘以Vt來控制梯度下降的方向和力度。

3.3 選行為

這個行為不再是用Q-value來選定的,而是用概率來決定。即使不用epsilon-greedy,也具有一定的隨機性。

class PolicyGradient:def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):...def _build_net(self):...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()) # 根據概率來選 actionreturn action

3.4 存儲回合

這一部分就是將這一步的observation,action,reward加到列表中去。因為本回合完畢之后要清空列表,然后存儲下一回合的數據,所以我們會在learn()當中進行清空列表的動作

class PolicyGradient:def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):...def _build_net(self):...def choose_action(self, observation):...def store_transition(self, s, a, r):self.ep_obs.append(s)self.ep_as.append(a)self.ep_rs.append(r)

3.5 學習

本節的learn()很簡單首先我們要對這回合的所有的reawrd動動手腳,使得它變得更適合被學習。第一就是隨著時間推進,用γ衰減未來的reward,然后為了一定程度上減小Policy Gradient回合variance。

class PolicyGradient:def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):...def _build_net(self):...def choose_action(self, observation):...def store_transition(self, s, a, r):...def learn(self):# 衰減, 并標準化這回合的 rewarddiscounted_ep_rs_norm = self._discount_and_norm_rewards() # 功能再面# train on episodeself.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 = [], [], [] # 清空回合 datareturn discounted_ep_rs_norm # 返回這一回合的 state-action value

再看discounted_ep_rs_norm

vt = RL.learn() # 學習, 輸出 vt, 我們下節課講這個 vt 的作用if i_episode == 0:plt.plot(vt) # plot 這個回合的 vtplt.xlabel('episode steps')plt.ylabel('normalized state-action value')plt.show()

最后使如何用算法實現對未來reward的衰減

class PolicyGradient:def __init__(self, n_actions, n_features, learning_rate=0.01, reward_decay=0.95, output_graph=False):...def _build_net(self):...def choose_action(self, observation):...def store_transition(self, s, a, r):...def learn(self):...def _discount_and_norm_rewards(self):# discount episode rewardsdiscounted_ep_rs = np.zeros_like(self.ep_rs)running_add = 0for t in reversed(range(0, len(self.ep_rs))):running_add = running_add * self.gamma + self.ep_rs[t]discounted_ep_rs[t] = running_add# normalize episode rewardsdiscounted_ep_rs -= np.mean(discounted_ep_rs)discounted_ep_rs /= np.std(discounted_ep_rs)return discounted_ep_rs

總結

以上是生活随笔為你收集整理的【强化学习】Policy Gradient(策略梯度)算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。