【强化学习】Policy Gradients代码注释版本
生活随笔
收集整理的這篇文章主要介紹了
【强化学习】Policy Gradients代码注释版本
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
import gym #
import tensorflow as tf
import numpy as np# Hyper Parameters
GAMMA = 0.95 # discount factor 折扣因子
LEARNING_RATE = 0.01 # 學習率class Policy_Gradient():# 咱們來搞一下大頭!def __init__(self, env): # 初始化# 先初始化一些參量self.time_step = 0 # 某個地方需要用的步數(shù)self.state_dim = env.observation_space.shape[0] # 狀態(tài)維度self.action_dim = env.action_space.n # 動作維度 TODO 這個.n是什么意思self.ep_obs, self.ep_as, self.ep_rs = [], [], [] # 初始化了一個三狀態(tài),為了后面用store_transition存到智能體中self.create_softmax_network()# Init session 初始化tensorflow參數(shù)self.session = tf.InteractiveSession()self.session.run(tf.global_variables_initializer()) # 初始化 tensorflow 參數(shù)。def create_softmax_network(self):# network weights"""當在time-step-i時刻,策略網(wǎng)絡輸出概率向量若與采樣到的time-step-i時刻的動作越相似,那么交叉熵會越小。最小化這個交叉熵誤差也就能夠使策略網(wǎng)絡的決策越接近我們采樣的動作。最后用交叉熵乘上對應time-step的reward,就將reward的大小引入損失函數(shù),entropy*reward越大,神經(jīng)網(wǎng)絡調(diào)整參數(shù)時計算得到的梯度就會越偏向該方向。:return:"""W1 = self.weight_variable([self.state_dim, 20]) # w1 權重,4*20的網(wǎng)絡b1 = self.bias_variable([20]) # b1權重,y = w1*x + b1W2 = self.weight_variable([20, self.action_dim])b2 = self.bias_variable([self.action_dim])# input layerself.state_input = tf.placeholder("float", [None, self.state_dim]) # 狀態(tài)輸入層占位,多少組不知道,每組有4個狀態(tài)self.tf_acts = tf.placeholder(tf.int32, [None, ],name="actions_num") # 動作數(shù) TODO 這里我其實沒太看出來是干啥的,很想輸出一下這些參量長什么樣,晚上學一下self.tf_vt = tf.placeholder(tf.float32, [None, ], name="actions_value") # 這是我們的狀態(tài)價值函數(shù)# hidden layersh_layer = tf.nn.relu(tf.matmul(self.state_input, W1) + b1) # 進行 y = w1*x + b1 的運算 ,并激活成可輸出的狀態(tài)# softmax layer# matmul返回兩個數(shù)組的矩陣乘積,結果還是一個矩陣self.softmax_input = tf.matmul(h_layer, W2) + b2 # 進行 y = w2*x + b2 的運算,輸出是兩個是數(shù)(不確定)TODO# softmax outputself.all_act_prob = tf.nn.softmax(self.softmax_input, name='act_prob') # softmax輸出層,輸出每個動作的概率# 計算logits 和 labels 之間的稀疏softmax 交叉熵# 函數(shù)先對 logits 進行 softmax 處理得到歸一化的概率,將lables向量進行one-hot處理,然后求logits和labels的交叉熵:# TODO https://blog.csdn.net/qq_22194315/article/details/77991283 一會兒研究一下這個鏈接self.neg_log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.softmax_input,labels=self.tf_acts)# tf.reduce_mean :計算張量tensor沿著指定的數(shù)軸(tensor的某一維度)上的的平均值# 損失函數(shù)計算,定義為softmax交叉熵損失函數(shù)和狀態(tài)價值函數(shù)的乘積self.loss = tf.reduce_mean(self.neg_log_prob * self.tf_vt) # reward guided loss# 我的理解是,利用tensorflow中的Adam優(yōu)化算法最小化loss函數(shù)# Adam優(yōu)化算法:是一個尋找全局最優(yōu)點的優(yōu)化算法,引入了二次方梯度校正。self.train_op = tf.train.AdamOptimizer(LEARNING_RATE).minimize(self.loss)def weight_variable(self, shape): # 權重變量initial = tf.truncated_normal(shape)return tf.Variable(initial)def bias_variable(self, shape): # 偏執(zhí)變量,生成常量矩陣,是tensorflow中固定的機制initial = tf.constant(0.01, shape=shape)return tf.Variable(initial)def choose_action(self, observation):"""選擇動作 :這里的observation其實就是狀態(tài),當前的狀態(tài)先傳入state_input(也就相當于softmax網(wǎng)絡的入口),softmax網(wǎng)絡的輸出是針對當前狀態(tài)每個動作的概率,第一句就是運行了一個會話進行這個過程。#TODO prob_weights 應該是一個動作對應概率的矩陣,怎么查看數(shù)據(jù)類型來著忘了下一句就是依據(jù)概率選擇動作了,選擇概率最大的動作"""prob_weights = self.session.run(self.all_act_prob, feed_dict={self.state_input: observation[np.newaxis, :]})action = np.random.choice(range(prob_weights.shape[1]),p=prob_weights.ravel()) # select action w.r.t the actions probreturn actiondef store_transition(self, s, a, r): # 序列采樣,差不多是將三狀態(tài)整合在一起self.ep_obs.append(s)self.ep_as.append(a)self.ep_rs.append(r)def learn(self): #"""模型學習:通過蒙特卡洛完整序列采樣,對神經(jīng)網(wǎng)絡進行調(diào)整。:return:"""discounted_ep_rs = np.zeros_like(self.ep_rs) # 下面所有的這些過程就是在一步步實現(xiàn)那個復雜的計算狀態(tài)價值函數(shù)的公式running_add = 0for t in reversed(range(0, len(self.ep_rs))):running_add = running_add * GAMMA + self.ep_rs[t] #discounted_ep_rs[t] = running_adddiscounted_ep_rs -= np.mean(discounted_ep_rs)discounted_ep_rs /= np.std(discounted_ep_rs) # 到這一步就實現(xiàn)了# train on episodeself.session.run(self.train_op, feed_dict={self.state_input: np.vstack(self.ep_obs),self.tf_acts: np.array(self.ep_as),self.tf_vt: discounted_ep_rs,}) # 到這一步就計算完成了,給她傳進會話讓他進行下面的計算吧self.ep_obs, self.ep_as, self.ep_rs = [], [], [] # 每步結束之后清空這三個值# main函數(shù)里面會用到的一些超級參量
ENV_NAME = 'CartPole-v0' # 定義一個超級參量,小車桿子的游戲環(huán)境名稱
EPISODE = 3000 # 3000個回合
STEP = 3000 # 每個回合里面最多執(zhí)行3000步
TEST = 20 # 每一百個回合做一次測試,每次10次測試取一次平均def main():env = gym.make(ENV_NAME)agent = Policy_Gradient(env) # 定義了一個智能體for episode in range(EPISODE): # 開始回合更新state = env.reset() # 初始化狀態(tài)for step in range(STEP): # 開始單步更新action = agent.choose_action(state) # 根據(jù)當前的狀態(tài)隨機選擇動作next_state, reward, done, _ = env.step(action) # 得到執(zhí)行動作后的回報,以及下一個狀態(tài)agent.store_transition(state, action, reward) # 序列采樣state = next_state # 更新狀態(tài),準備下一步更新,下一個狀態(tài)即為下一步中的當前狀態(tài)if done:# 蒙特卡羅法里面價值函數(shù)的計算,一般是從后向前算,這樣前面的價值的計算可以利用后面的價值作為中間結果,簡化計算agent.learn() # 完成一個回合之后計算價值函數(shù)break # 達到終止條件的時候退出當前循環(huán),開啟下一回合# 完成100個回合下面開始測試if episode % 100 == 0:total_reward = 0 # 初始化回報for i in range(TEST):state = env.reset() # 初始化狀態(tài)for j in range(STEP):env.render() # env.render()函數(shù)用于渲染出當前的智能體以及環(huán)境的狀態(tài)action == agent.choose_action(state) # 根據(jù)狀態(tài)選擇動作state, reward, done, _ = env.step(action) # 根據(jù)action執(zhí)行step,得到三狀態(tài)total_reward += reward # 為了十次取一次平均,先加后除if done: # 如果達到了終止條件,則退出breakave_reward = total_reward / TEST # 求平均print('episode:', episode, 'Evaluation Average Reward:', ave_reward)if __name__ == '__main__':main()
總結
以上是生活随笔為你收集整理的【强化学习】Policy Gradients代码注释版本的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【强化学习】Policy Gradien
- 下一篇: 【强化学习】Actor Critic原理