# 十、OpenAI Gym
OpenAI Gym 是一個開源 Python 框架,由非營利性 AI 研究公司 OpenAI 開發,作為開發和評估 RL 算法的工具包。它給我們提供了一組測試問題,稱為環境,我們可以編寫 RL 算法來解決。這使我們能夠將更多的時間用于實現和改進學習算法,而不是花費大量時間來模擬環境。此外,它為人們提供了一種比較和審查其他算法的媒介。
## OpenAI 環境
OpenAI Gym 擁有一系列環境。在編寫本書時,可以使用以下環境:
* 經典控制和玩具文本:來自 RL 文獻的小規模任務。
* 算法:執行計算,例如添加多位數和反轉序列。這些任務中的大多數都需要記憶,并且可以通過改變序列長度來改變它們的難度。
* Atari:經典 Atari 游戲,使用街機學習環境,屏幕圖像或 RAM 作為輸入。
* 棋盤游戲:目前,我們已經將圍棋游戲包括在`9x9`和`19x19`板上,而 Pachi 引擎則作為對手。
* 2D 和 3D 機器人:允許在模擬中控制機器人。這些任務使用 MuJoCo 物理引擎,該引擎專為快速準確的機器人仿真而設計。一些任務改編自 RLLab。
## `env`類
OpenAI Gym 允許使用`env`類,它封裝了環境和任何內部動態。此類具有不同的方法和屬性,使您可以實現創建新環境。最重要的方法名為`reset`,`step`和`render`:
* `reset`方法的任務是通過將環境初始化為初始狀態來重置環境。在重置方法中,必須包含構成環境的元素的定義(在這種情況下,機械臂的定義,要抓取的對象及其支持)。
* `step`方法是用于在時間上推進環境的 。它需要輸入操作并將新觀察結果返回給智能體。在該方法中,必須定義運動動態管理,狀態和獎勵計算以及劇集完成控制。
* 最后一種方法是`render`, 用于顯示當前狀態。
使用框架提出的`env`類作為新環境的基礎,它采用工具包提供的通用接口。
這樣,構建的環境可以集成到工具包的庫中,并且可以從 OpenAI Gym 社區的用戶所做的算法中學習它們的動態。
## 安裝并運行 OpenAI Gym
有關如何使用和運行 OpenAI Gym 的更多詳細說明,請參閱([此鏈接](https://gym.openai.com/docs/))的官方文檔頁面。使用以下命令可以實現 OpenApp Gym 的最小安裝:
```py
git clone https://github.com/openai/gym
cd gym
pip install -e
```
安裝 OpenAI Gym 之后,您可以在 Python 代碼中實例化并運行環境:
```py
import gym
env = gym.make('CartPole-v0')
obs = env.reset()
for step_idx in range(500):
env.render()
obs, reward, done, _ = env.step(env.action_space.sample())
```
此代碼段將首先導入`gym`庫。然后它創建了 [Cart-Pole](https://gym.openai.com/envs/CartPole-v0/) 環境的實例 ,這是 RL 中的經典問題。 Cart-Pole 環境模擬安裝在推車上的倒立擺。鐘擺最初是垂直的,你的目標是保持其垂直平衡。控制擺錘的唯一方法是選擇水平方向讓推車移動(向左或向右)。
上面的代碼運行`500`時間步的環境,并選擇隨機操作在每一步執行。因此,您在下面的視頻中看到,桿不能長時間保持穩定。獎勵是通過在桿距垂直方向超過 15 度之前經過的時間步數來衡量的。您保持在此范圍內的時間越長,您的總獎勵就越高。
# Q-Learning 算法
解決 RL 問題需要在學習過程中估計評估函數。該函數必須能夠通過獎勵的總和來評估策略的成功。
Q-Learning 的基本思想是算法學習整個狀態和動作空間的最優評估函數(`S×A`)。這種所謂的`Q`函數以`Q: S×A -> R`的形式提供匹配,其中`R`是在狀態`s ∈ S`中執行的動作`a ∈ A`的未來獎勵的期望值。一旦智能體學會了最佳函數`Q`,它就能夠識別哪種行為將導致某種狀態下最高的未來獎勵。
實現 Q-Learning 算法的最常用示例之一涉及使用表。該表的每個單元格是值`Q(s; a) = R`并且它被初始化為 0.由智能體執行的動作`a ∈ A`是使用相對于`Qε`的貪婪策略來選擇的。
Q-Learning 算法的基本思想是訓練規則,它更新表格元素`Q(s; a) = R`。
該算法遵循以下基本步驟:
1. 任意初始化`Q(s; a) = R`。
2. 對每個劇集重復以下:
1. 初始化`s`。
2. 重復(對于劇集的每一步):
3. 使用從`Q`派生的策略從`s ∈ S`中選擇一個動作`a ∈ A`。
4. 選取動作`a`,觀察`r`,`s'`:
```
Q(s; a) <= Q(s; a) + a · (r + γ · max Q(s'; a) - Q(s; a))
s': s <- s'
```
5. 繼續直到`s`的終點。
我們在下圖中描述了算法:

圖 2:Q-Learning 算法
讓我們總結一下 Q 值更新過程中使用的參數:
* `α`是學習率,設置在 0 和 1 之間。將其設置為 0 意味著 Q 值永遠不會更新,因此不會學習任何內容。設置較高的值(如 0.9)意味著可以快速進行學習。
* `γ`是折扣因子,設置在 0 和 1 之間。這模擬了未來獎勵的值低于直接獎勵的事實。在數學上,需要將折扣因子設置為小于 1 以使算法收斂。
* `max Q(s'; a)`是在當前狀態之后的狀態下可獲得的最大獎勵,即之后采取最佳行動的獎勵。
## FrozenLake 環境
智能體控制角色在`4×4`網格世界中的移動。網格的一些瓷磚是可行走的,而其他瓷磚則導致落入水中。另外,智能體的移動方向是不確定的,并且僅部分地取決于所選擇的方向。智能體因找到目標圖塊的可行走路徑而獲得獎勵:

圖 3:Frozen-Lake v0 網格字的表示
使用如下網格描述上面所示的表面:
```py
SFFF (S: starting point, safe)
FHFH (F: frozensurface, safe)
FFFH (H: hole, fall to yourdoom)
HFFG (G: goal, where the frisbee islocated)
```
當我們到達目標或陷入一個洞時,這一集結束。如果達到目標,我們會收到`1`的獎勵,否則會收到`0`。
針對 FrozenLake 問題的 Q-Learning
在為高度結構化數據提供良好功能方面,神經網絡非常強大。
為了解決 FrozenLake 問題,我們將構建一個單層網絡,該網絡采用`1×16`向量中編碼的狀態并學習最佳移動(動作),在向量中映射可能的動作長度為四。
以下實現基于 TensorFlow:
首先,我們需要導入所有庫:
```py
import gym
import numpy as np
import random
import tensorflow as tf
import matplotlib.pyplot as plt
```
然后我們加載并設置環境以進行測試:
```py
env = gym.make('FrozenLake-v0')
```
輸入網絡是一種狀態,以張量形狀[1,16]編碼。因此,我們定義了`input1`占位符:
```py
inputs1 = tf.placeholder(shape=[1,16],dtype=tf.float32)
```
網絡權重最初由`tf.random_uniform`函數隨機選擇:
```py
W = tf.Variable(tf.random_uniform([16,4],0,0.01))
```
網絡輸出由`inputs1`占位符和權重的乘積給出:
```py
Qout = tf.matmul(inputs1,W)
```
在`Qout`上計算的`argmax`將給出預測值:
```py
predict = tf.argmax(Qout,1)
```
最佳動作(`nextQ`)以張量形狀編碼[1,4]:
```py
nextQ = tf.placeholder(shape=[1,4],dtype=tf.float32)
```
接下來,我們定義一個損失函數來實現反向傳播過程。
損失函數是`loss = ∑(Q - target - Q)`,其中計算當前預測的 Q 值和目標值之間的差異,并且梯度通過網絡傳遞:
```py
loss = tf.reduce_sum(tf.square(nextQ - Qout))
```
優化函數是眾所周知的`GradientDescentOptimizer`:
```py
trainer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
updateModel = trainer.minimize(loss)
```
重置并初始化計算圖:
```py
tf.reset_default_graph()
init = tf.global_variables_initializer()
```
然后我們設置 Q-Learning 訓練過程的參數:
```py
y = .99
e = 0.1
num_episodes = 6000
jList = []
rList = []
```
我們定義會話`sess`,其中網絡必須學習最佳的移動順序:
```py
with tf.Session() as sess:
sess.run(init)
for i in range(num_episodes):
s = env.reset()
rAll = 0
d = False
j = 0
while j < 99:
j+=1
```
輸入狀態用于為網絡提供信息:
```py
a,allQ = sess.run([predict,Qout],\
feed_dict=\
{inputs1:np.identity(16)[s:s+1]})
```
從輸出張量`a`中選擇一個隨機狀態:
```py
if np.random.rand(1) < e:
a[0] = env.action_space.sample()
```
使用`env.step()`函數執行`a[0]`動作,獲得獎勵,`r`和狀態,`s1`:
```py
s1,r,d,_ = env.step(a[0])
```
新狀態`s1`用于更新`Q`張量:
```py
Q1 = sess.run(Qout,feed_dict=\
{inputs1:np.identity(16)[s1:s1+1]})
maxQ1 = np.max(Q1)
targetQ = allQ
targetQ[0,a[0]] = r + y*maxQ1
```
當然,必須為反向傳播過程更新權重:
```py
_,W1 = sess.run([updateModel,W],\
feed_dict=\
{inputs1:np.identity(16)[s:s+1],nextQ:targetQ})
```
`rAll`這里定義了會話期間獲得的總獎勵。讓我們回想一下,RL 智能體的目標是最大化它從長遠來看所獲得的總獎勵:
```py
rAll += r
```
更新下一步的環境狀態:
```py
s = s1
if d == True:
e = 1./((i/50) + 10)
break
jList.append(j)
rList.append(rAll)
```
計算結束時,將顯示成功劇集的百分比:
```py
print ("Percent of successfulepisodes: " +\
str(sum(rList)/num_episodes) + "%")
```
如果我們運行模型,我們應該得到這樣的結果,可以通過調整網絡參數來改進:
```py
>>>[2017-01-15 16:56:01,048] Making new env: FrozenLake-v0
Percentage of successful episodes: 0.558%
```
# 深度 Q 學習
多虧了 DeepMind 在 2013 年和 2016 年取得的近期成就,它成功地在 Atari 游戲中達到了所謂的超人級別,并擊敗了圍棋世界冠軍,RL 在機器學習社區中變得非常有趣。這種新的興趣也是由于深度神經網絡(DNN)表現為近似函數,使這種算法的潛在價值達到了更高的水平。最近獲得最多興趣的算法肯定是深度 Q-Learning。以下部分介紹深度 Q-Learning 算法,并討論一些優化技術以最大化其表現。
## 深度 Q 神經網絡
當狀態數和可能的動作增加并且從矩陣的角度來看變得難以管理時,Q 學習基礎算法會引起巨大的問題。想想谷歌使用的結構輸入配置,以達到 Atari 游戲的表現水平。狀態空間是離散的,但國家的數量是巨大的。這就是深度學習的步驟。神經網絡非常擅長為高度結構化的數據提供良好的功能。事實上,我們可以用神經網絡識別 Q 函數,它將狀態和動作作為輸入并輸出相應的 Q 值:
```py
Q(state; action) = value
```
深度神經網絡最常見的實現如下圖所示:

圖 4:深度 Q 神經網絡的通用實現
或者, 可以將狀態作為輸入,并為每個可能的動作生成相應的值:
```py
Q(state) = 每個可能的操作值
```
這個優化的實現可以在下圖中看到:

圖 5:深度 Q 神經網絡的優化實現
最后的方法在計算上是有利的,因為要更新 Q 值(或選擇最高的 Q 值),我們只需要通過網絡向前邁出一步,我們將立即獲得所有可用操作的所有 Q 值。
## Cart-Pole 問題
我們將建立一個深度神經網絡,可以學習通過 RL 玩游戲。更具體地說,我們將使用深度 Q 學習訓練智能體玩 Cart-Pole 游戲。
在這個游戲中, 自由擺動桿連接到推車。推車可以向左和向右移動,目標是盡可能長時間保持桿直立:

圖 6:Cart-Pole
我們使用 OpenAI Gym 模擬這個游戲。我們需要導入所需的庫:
```py
import gym
import tensorflow as tf
import numpy as np
import time
```
讓我們創建 Cart-Pole 游戲環境:
```py
env = gym.make('CartPole-v0')
```
初始化環境,獎勵列表和開始時間:
```py
env.reset()
rewards = []
tic = time.time()
```
這里使用`env.render()`語句來顯示運行模擬的窗口:
```py
for _ in range(1000):
env.render()
```
`env.action_space.sample()`被傳遞給`env.step()`語句以構建模擬的下一步:
```py
state, reward, done, info = \
env.step\
(env.action_space.sample())
```
在 Cart-Pole 游戲中,有兩種可能的動作:向左或向右移動。因此,我們可以采取兩種操作,編碼為 0 和 1。
在這里,我們采取隨機行動:
```py
rewards.append(reward)
if done:
rewards = []
env.reset()
toc = time.time()
```
10 秒后,模擬結束:
```py
if toc-tic > 10:
env.close()
```
要關閉顯示模擬的窗口,請使用`env.close()`。
當我們運行模擬時,我們有一個獎勵列表,如下所示:
```py
[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
```
在極點超過一定角度后,游戲重置。對于正在運行的每個幀,模擬返回 1.0 的獎勵。游戲運行的時間越長,獲得的獎勵就越多。因此,我們的網絡的目標是通過保持桿垂直來最大化獎勵。它將通過向左和向右移動推車來完成此操作。
### 針對 Cart-Pole 問題的深度 Q 網絡
我們使用 Bellman 方程再次訓練我們的 Q 學習智能體:

這里,`s`是狀態,`a`是動作,`s'`是狀態`s`和動作`a`的下一個狀態。
之前,我們使用這個等式來學習 Q 表的值。但是,這個游戲有很多狀態可供使用。狀態有四個值:推車的位置和速度,以及桿的位置和速度。這些都是實數值,所以如果我們忽略浮點精度,我們實際上有無限狀態。然后,我們將用一個近似于 Q 表查找功能的神經網絡替換它,而不是使用表格。
通過將狀態傳遞到網絡來計算 Q 值,而輸出將是每個可用動作的 Q 值,具有完全連接的隱藏層:

圖 7:深度 Q-Learning
在這個 Cart-Pole 游戲中,我們有四個輸入,一個用于狀態中的每個值;和兩個輸出,每個動作一個。網絡權重更新將通過選擇動作并使用所選動作模擬游戲來進行。這將把我們帶到下一個狀態然后再到獎勵。
以下是用于解決 Cart-Pole 問題的神經網絡的簡短代碼片段:
```py
import tensorflow as tf
class DQNetwork:
def __init__(self,\
learning_rate=0.01, \
state_size=4,\
action_size=2, \
hidden_size=10,\
name='DQNetwork'):
```
隱藏層由兩個完全連接的層組成,具有 ReLU 激活:
```py
self.fc1 =tf.contrib.layers.fully_connected\
(self.inputs_,\
hidden_size)
self.fc2 = tf.contrib.layers.fully_connected\
(self.fc1,\
hidden_size)
```
輸出層是線性輸出層:
```py
self.output = tf.contrib.layers.fully_connected\
(self.fc2,\
action_size,activation_fn=None)
```
### 經驗重放方法
近似函數可能會受到非獨立且相同分布和非平穩數據(狀態之間的相關性)的影響。
使用經驗重放方法可以克服這種問題。
在智能體和環境之間的交互過程中,所有經驗(`state`,`action`,`reward`和`next_state`)都保存在重放內存中,這是固定大小的內存并以先進先出(FIFO)的方式運行。
這是重放內存類的實現:
```py
from collections import deque
import numpy as np
class replayMemory():
def __init__(self, max_size = 1000):
self.buffer = \
deque(maxlen=max_size)
def build(self, experience):
self.buffer.append(experience)
def sample(self, batch_size):
idx = np.random.choice\
(np.arange(len(self.buffer)),
size=batch_size,
replace=False)
return [self.buffer[ii] for ii in idx]
```
這將允許在網絡訓練期間使用在重放存儲器中隨機獲取的小批量經驗,而不是一個接一個地使用最近的經驗。
使用經驗重放方法有助于緩解順序訓練數據的問題,這可能導致算法保持在局部最小值,從而使其無法獲得最佳解決方案。
### 利用和探索
每當智能體必須選擇要采取的行動時,它基本上有兩種方式可以執行其策略。第一種模式稱為利用,包括根據目前獲得的信息,即過去和存儲的經驗,做出最佳決策。此信息始終作為值函數提供,該函數表示哪個操作為每個狀態 - 操作對提供最大的最終累積回報。
第二種模式稱為探索,它是一種決策策略,不同于目前認為最優的策略。
探索階段非常重要,因為它用于收集未探測狀態的信息。實際上,只有執行最佳操作的智能體才有可能始終遵循相同的操作順序,而沒有機會探索并發現可能存在從長遠來看可能導致的策略更好的結果,即使這意味著立即獲得的收益更低。
最常用于在利用和探索之間達成正確妥協的策略是貪婪的策略。它代表了一種選擇動作的方法,基于使用均勻概率分布來選擇隨機動作的可能性。
### 深度 Q-Learning 訓練算法
讓我們看看如何構建一個深度 Q-Learning 算法來解決 Cart-Pole 問題。
該項目相當復雜。為此原因。它已被細分為幾個文件模塊:
* `DQNetwork.py`:實現深度神經網絡
* `memory.py`:實現經驗重放方法
* `start_simulation.py`:創建我們想要解決的 Cart-Pole 環境
* `solve_cart_pole.py`:用經過訓練的神經網絡解決 Cart-Pole 環境
* `plot_result_DQN.py`:繪制最后的獎勵與劇集
* `deepQlearning.py`:主程序
以下命令提供了`deepQlearning.py`文件實現的簡要說明:
```py
import tensorflow as tf
import gym
import numpy as np
import time
import os
from create_cart_pole_env import *
from DQNetwork import *
from memory import *
from solve_cart_pole import *
from plot_result_DQN import *
```
接下來要做的是定義用于此實現的超參數,因此我們需要定義要學習的最大劇集數,一集中的最大步數以及未來的獎勵折扣:
```py
train_episodes = 1000
max_steps = 200
gamma = 0.99
```
探索參數是探索開始時的探索概率,最小探索概率和探索概率的指數衰減率:
```py
explore_start = 1.0
explore_stop = 0.01
decay_rate = 0.0001
```
網絡參數是每個隱藏 Q 網絡層中的單元數和 Q 網絡學習率:
```py
hidden_size = 64
learning_rate = 0.0001
```
定義以下內存參數:
```py
memory_size = 10000
batch_size = 20
```
然后我們有大量的經驗來預先記錄內存:
```py
pretrain_length = batch_size
```
現在我們可以創建環境并啟動 Cart-Pole 模擬:
```py
env = gym.make('CartPole-v0')
start_simulation(env)
```
接下來,我們使用`hidden_size`和`learning_rate`超參數實例化 DNN:
```py
tf.reset_default_graph()
deepQN = DQNetwork(name='main', hidden_size=64, \
learning_rate=0.0001)
```
最后,我們重新初始化模擬:
```py
env.reset()
```
讓我們采取隨機步驟,從中我們可以獲得狀態和獎勵:
```py
state, rew, done, _ = env.step(env.action_space.sample())
```
實例化`replayMemory`對象以實現經驗重放方法:
```py
memory = replayMemory(max_size=10000)
```
使用`memory.build`方法獲取隨機動作的塊,來存儲相對經驗,狀態和動作:
```py
pretrain_length= 20
for j in range(pretrain_length):
action = env.action_space.sample()
next_state, rew, done, _ = \
env.step(env.action_space.sample())
if done:
env.reset()
memory.build((state,\
action,\
rew,\
np.zeros(state.shape)))
state, rew, done, _ = \
env.step(env.action_space.sample())
else:
memory.build((state, action, rew, next_state))
state = next_state
```
通過獲得的新經驗,我們可以進行神??經網絡的訓練:
```py
rew_list = []
train_episodes = 100
max_steps=200
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
step = 0
for ep in range(1, train_episodes):
tot_rew = 0
t = 0
while t < max_steps:
step += 1
explore_p = stop_exp + (start_exp - stop_exp)*\
np.exp(-decay_rate*step)
if explore_p > np.random.rand():
action = env.action_space.sample()
else:
```
然后我們計算 Q 狀態:
```py
Qs = sess.run(deepQN.output, \
feed_dict={deepQN.inputs_: \
state.reshape\
((1, *state.shape))})
```
我們現在可以獲得動作:
```py
action = np.argmax(Qs)
next_state, rew, done, _ = env.step(action)
tot_rew += rew
if done:
next_state = np.zeros(state.shape)
t = max_steps
print('Episode: {}'.format(ep),
'Total rew: {}'.format(tot_rew),
'Training loss: {:.4f}'.format(loss),
'Explore P: {:.4f}'.format(explore_p))
rew_list.append((ep, tot_rew))
memory.build((state, action, rew, next_state))
env.reset()
state, rew, done, _ = env.step\
(env.action_space.sample())
else:
memory.build((state, action, rew, next_state))
state = next_state
t += 1
batch_size = pretrain_length
states = np.array([item[0] for item \
in memory.sample(batch_size)])
actions = np.array([item[1] for item \
in memory.sample(batch_size)])
rews = np.array([item[2] for item in \
memory.sample(batch_size)])
next_states = np.array([item[3] for item\
in memory.sample(batch_size)])
```
最后,我們開始訓練智能體。訓練很慢,因為它渲染的幀比網絡可以訓練的慢:
```py
target_Qs = sess.run(deepQN.output, \
feed_dict=\
{deepQN.inputs_: next_states})
target_Qs[(next_states == \
np.zeros(states[0].shape))\
.all(axis=1)] = (0, 0)
targets = rews + 0.99 * np.max(target_Qs, axis=1)
loss, _ = sess.run([deepQN.loss, deepQN.opt],
feed_dict={deepQN.inputs_: states,
deepQN.targetQs_: targets,
deepQN.actions_: actions})
env = gym.make('CartPole-v0')
```
要測試模型,我們調用以下函數:
```py
solve_cart_pole(env,deepQN,state,sess)
plot_result(rew_list)
```
這里是用于測試購物車桿問題的神經網絡實現:
```py
import numpy as np
def solve_cart_pole(env,dQN,state,sess):
test_episodes = 10
test_max_steps = 400
env.reset()
for ep in range(1, test_episodes):
t = 0
while t < test_max_steps:
env.render()
Qs = sess.run(dQN.output, \
feed_dict={dQN.inputs_: state.reshape\
((1, *state.shape))})
action = np.argmax(Qs)
next_state, reward, done, _ = env.step(action)
if done:
t = test_max_steps
env.reset()
state, reward, done, _ =
env.step(env.action_space.sample())
else:
state = next_state
t += 1
```
最后,如果我們運行`deepQlearning.py`腳本,我們應該得到這樣的結果:
```py
[2017-12-03 10:20:43,915] Making new env: CartPole-v0
[]
Episode: 1 Total reward: 7.0 Training loss: 1.1949 Explore P: 0.9993
Episode: 2 Total reward: 21.0 Training loss: 1.1786 Explore P: 0.9972
Episode: 3 Total reward: 38.0 Training loss: 1.1868 Explore P: 0.9935
Episode: 4 Total reward: 8.0 Training loss: 1.3752 Explore P: 0.9927
Episode: 5 Total reward: 9.0 Training loss: 1.6286 Explore P: 0.9918
Episode: 6 Total reward: 32.0 Training loss: 1.4313 Explore P: 0.9887
Episode: 7 Total reward: 19.0 Training loss: 1.2806 Explore P: 0.9868
……
Episode: 581 Total reward: 47.0 Training loss: 0.9959 Explore P: 0.1844
Episode: 582 Total reward: 133.0 Training loss: 21.3187 Explore P: 0.1821
Episode: 583 Total reward: 54.0 Training loss: 42.5041 Explore P: 0.1812
Episode: 584 Total reward: 95.0 Training loss: 1.5211 Explore P: 0.1795
Episode: 585 Total reward: 52.0 Training loss: 1.3615 Explore P: 0.1787
Episode: 586 Total reward: 78.0 Training loss: 1.1606 Explore P: 0.1774
…….
Episode: 984 Total reward: 199.0 Training loss: 0.2630 Explore P: 0.0103
Episode: 985 Total reward: 199.0 Training loss: 0.3037 Explore P: 0.0103
Episode: 986 Total reward: 199.0 Training loss: 256.8498 Explore P: 0.0103
Episode: 987 Total reward: 199.0 Training loss: 0.2177 Explore P: 0.0103
Episode: 988 Total reward: 199.0 Training loss: 0.3051 Explore P: 0.0103
Episode: 989 Total reward: 199.0 Training loss: 218.1568 Explore P: 0.0103
Episode: 990 Total reward: 199.0 Training loss: 0.1679 Explore P: 0.0103
Episode: 991 Total reward: 199.0 Training loss: 0.2048 Explore P: 0.0103
Episode: 992 Total reward: 199.0 Training loss: 0.4215 Explore P: 0.0102
Episode: 993 Total reward: 199.0 Training loss: 0.2133 Explore P: 0.0102
Episode: 994 Total reward: 199.0 Training loss: 0.1836 Explore P: 0.0102
Episode: 995 Total reward: 199.0 Training loss: 0.1656 Explore P: 0.0102
Episode: 996 Total reward: 199.0 Training loss: 0.2620 Explore P: 0.0102
Episode: 997 Total reward: 199.0 Training loss: 0.2358 Explore P: 0.0102
Episode: 998 Total reward: 199.0 Training loss: 0.4601 Explore P: 0.0102
Episode: 999 Total reward: 199.0 Training loss: 0.2845 Explore P: 0.0102
[2017-12-03 10:23:43,770] Making new env: CartPole-v0
>>>
```
隨著訓練損失減少,總獎勵增加。
在測試期間,推車桿完美平衡:

圖 8:解決了 Cart-Pole 問題
為了可視化訓練,我們使用了`plot_result()`函數(它在`plot_result_DQN.py`函數中定義)。
`plot_result()`函數繪制每集的總獎勵:
```py
def plot_result(rew_list):
eps, rews = np.array(rew_list).T
smoothed_rews = running_mean(rews, 10)
smoothed_rews = running_mean(rews, 10)
plt.plot(eps[-len(smoothed_rews):], smoothed_rews)
plt.plot(eps, rews, color='grey', alpha=0.3)
plt.xlabel('Episode')
plt.ylabel('Total Reward')
plt.show()
```
以下繪圖顯示,每個事件的總獎勵隨著智能體改進其對值函數的估計而增加:

# 總結
許多研究人員認為,RL 是我們創造人工智能的最好方法。這是一個令人興奮的領域,有許多未解決的挑戰和巨大的潛力。雖然一開始看起來很有挑戰性,但開始使用 RL 并不是那么困難。在本章中,我們描述了 RL 的一些基本原理。
我們討論的主要內容是 Q-Learning 算法。它的顯著特點是能夠在即時獎勵和延遲獎勵之間做出選擇。最簡單的 Q-learning 使用表來存儲數據。當監視/控制的系統的狀態/動作空間的大小增加時,這很快就失去了可行性。
我們可以使用神經網絡作為函數逼近器來克服這個問題,該函數逼近器將狀態和動作作為輸入并輸出相應的 Q 值。
按照這個想法,我們使用 TensorFlow 框架和 OpenAI Gym 工具包實現了一個 Q 學習神經網絡,以贏得 FrozenLake 游戲。
在本章的最后一部分,我們介紹了深度強化學習。在傳統的 RL 中,問題空間非常有限,并且環境中只有少數可能的狀態。這是傳統方法的主要局限之一。多年來,已經有一些相對成功的方法能夠通過近似狀態來處理更大的狀態空間。
深度學習算法的進步已經在 RL 中引入了新的成功應用浪潮,因為它提供了有效處理高維輸入數據(例如圖像)的機會。在這種情況下,訓練有素的 DNN 可以被視為一種端到端的 RL 方法,其中智能體可以直接從其輸入數據中學習狀態抽象和策略近似。按照這種方法,我們實現了 DNN 來解決 Cart-Pole 問題。
我們的 TensorFlow 深度學習之旅將在此結束。深度學習是一個非常有成效的研究領域;有許多書籍,課程和在線資源可以幫助讀者深入理論和編程。此外,TensorFlow 還提供了豐富的工具來處理深度學習模型。我希望本書的讀者成為 TensorFlow 社區的一部分,該社區非常活躍,并希望熱心人士盡快加入。
- TensorFlow 1.x 深度學習秘籍
- 零、前言
- 一、TensorFlow 簡介
- 二、回歸
- 三、神經網絡:感知器
- 四、卷積神經網絡
- 五、高級卷積神經網絡
- 六、循環神經網絡
- 七、無監督學習
- 八、自編碼器
- 九、強化學習
- 十、移動計算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度學習
- 十三、AutoML 和學習如何學習(元學習)
- 十四、TensorFlow 處理單元
- 使用 TensorFlow 構建機器學習項目中文版
- 一、探索和轉換數據
- 二、聚類
- 三、線性回歸
- 四、邏輯回歸
- 五、簡單的前饋神經網絡
- 六、卷積神經網絡
- 七、循環神經網絡和 LSTM
- 八、深度神經網絡
- 九、大規模運行模型 -- GPU 和服務
- 十、庫安裝和其他提示
- TensorFlow 深度學習中文第二版
- 一、人工神經網絡
- 二、TensorFlow v1.6 的新功能是什么?
- 三、實現前饋神經網絡
- 四、CNN 實戰
- 五、使用 TensorFlow 實現自編碼器
- 六、RNN 和梯度消失或爆炸問題
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用協同過濾的電影推薦
- 十、OpenAI Gym
- TensorFlow 深度學習實戰指南中文版
- 一、入門
- 二、深度神經網絡
- 三、卷積神經網絡
- 四、循環神經網絡介紹
- 五、總結
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高級庫
- 三、Keras 101
- 四、TensorFlow 中的經典機器學習
- 五、TensorFlow 和 Keras 中的神經網絡和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于時間序列數據的 RNN
- 八、TensorFlow 和 Keras 中的用于文本數據的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自編碼器
- 十一、TF 服務:生產中的 TensorFlow 模型
- 十二、遷移學習和預訓練模型
- 十三、深度強化學習
- 十四、生成對抗網絡
- 十五、TensorFlow 集群的分布式模型
- 十六、移動和嵌入式平臺上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、調試 TensorFlow 模型
- 十九、張量處理單元
- TensorFlow 機器學習秘籍中文第二版
- 一、TensorFlow 入門
- 二、TensorFlow 的方式
- 三、線性回歸
- 四、支持向量機
- 五、最近鄰方法
- 六、神經網絡
- 七、自然語言處理
- 八、卷積神經網絡
- 九、循環神經網絡
- 十、將 TensorFlow 投入生產
- 十一、更多 TensorFlow
- 與 TensorFlow 的初次接觸
- 前言
- 1.?TensorFlow 基礎知識
- 2. TensorFlow 中的線性回歸
- 3. TensorFlow 中的聚類
- 4. TensorFlow 中的單層神經網絡
- 5. TensorFlow 中的多層神經網絡
- 6. 并行
- 后記
- TensorFlow 學習指南
- 一、基礎
- 二、線性模型
- 三、學習
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 構建簡單的神經網絡
- 二、在 Eager 模式中使用指標
- 三、如何保存和恢復訓練模型
- 四、文本序列到 TFRecords
- 五、如何將原始圖片數據轉換為 TFRecords
- 六、如何使用 TensorFlow Eager 從 TFRecords 批量讀取數據
- 七、使用 TensorFlow Eager 構建用于情感識別的卷積神經網絡(CNN)
- 八、用于 TensorFlow Eager 序列分類的動態循壞神經網絡
- 九、用于 TensorFlow Eager 時間序列回歸的遞歸神經網絡
- TensorFlow 高效編程
- 圖嵌入綜述:問題,技術與應用
- 一、引言
- 三、圖嵌入的問題設定
- 四、圖嵌入技術
- 基于邊重構的優化問題
- 應用
- 基于深度學習的推薦系統:綜述和新視角
- 引言
- 基于深度學習的推薦:最先進的技術
- 基于卷積神經網絡的推薦
- 關于卷積神經網絡我們理解了什么
- 第1章概論
- 第2章多層網絡
- 2.1.4生成對抗網絡
- 2.2.1最近ConvNets演變中的關鍵架構
- 2.2.2走向ConvNet不變性
- 2.3時空卷積網絡
- 第3章了解ConvNets構建塊
- 3.2整改
- 3.3規范化
- 3.4匯集
- 第四章現狀
- 4.2打開問題
- 參考
- 機器學習超級復習筆記
- Python 遷移學習實用指南
- 零、前言
- 一、機器學習基礎
- 二、深度學習基礎
- 三、了解深度學習架構
- 四、遷移學習基礎
- 五、釋放遷移學習的力量
- 六、圖像識別與分類
- 七、文本文件分類
- 八、音頻事件識別與分類
- 九、DeepDream
- 十、自動圖像字幕生成器
- 十一、圖像著色
- 面向計算機視覺的深度學習
- 零、前言
- 一、入門
- 二、圖像分類
- 三、圖像檢索
- 四、對象檢測
- 五、語義分割
- 六、相似性學習
- 七、圖像字幕
- 八、生成模型
- 九、視頻分類
- 十、部署
- 深度學習快速參考
- 零、前言
- 一、深度學習的基礎
- 二、使用深度學習解決回歸問題
- 三、使用 TensorBoard 監控網絡訓練
- 四、使用深度學習解決二分類問題
- 五、使用 Keras 解決多分類問題
- 六、超參數優化
- 七、從頭開始訓練 CNN
- 八、將預訓練的 CNN 用于遷移學習
- 九、從頭開始訓練 RNN
- 十、使用詞嵌入從頭開始訓練 LSTM
- 十一、訓練 Seq2Seq 模型
- 十二、深度強化學習
- 十三、生成對抗網絡
- TensorFlow 2.0 快速入門指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 簡介
- 一、TensorFlow 2 簡介
- 二、Keras:TensorFlow 2 的高級 API
- 三、TensorFlow 2 和 ANN 技術
- 第 2 部分:TensorFlow 2.00 Alpha 中的監督和無監督學習
- 四、TensorFlow 2 和監督機器學習
- 五、TensorFlow 2 和無監督學習
- 第 3 部分:TensorFlow 2.00 Alpha 的神經網絡應用
- 六、使用 TensorFlow 2 識別圖像
- 七、TensorFlow 2 和神經風格遷移
- 八、TensorFlow 2 和循環神經網絡
- 九、TensorFlow 估計器和 TensorFlow HUB
- 十、從 tf1.12 轉換為 tf2
- TensorFlow 入門
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 數學運算
- 三、機器學習入門
- 四、神經網絡簡介
- 五、深度學習
- 六、TensorFlow GPU 編程和服務
- TensorFlow 卷積神經網絡實用指南
- 零、前言
- 一、TensorFlow 的設置和介紹
- 二、深度學習和卷積神經網絡
- 三、TensorFlow 中的圖像分類
- 四、目標檢測與分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻