《Scikit-Learn與TensorFlow機(jī)器學(xué)習(xí)實(shí)用指南》 第16章 強(qiáng)化學(xué)習(xí)(下)


(第一部分 機(jī)器學(xué)習(xí)基礎(chǔ))
第01章 機(jī)器學(xué)習(xí)概覽
第02章 一個(gè)完整的機(jī)器學(xué)習(xí)項(xiàng)目(上)
第02章 一個(gè)完整的機(jī)器學(xué)習(xí)項(xiàng)目(下)
第03章 分類(lèi)
第04章 訓(xùn)練模型
第05章 支持向量機(jī)
第06章 決策樹(shù)
第07章 集成學(xué)習(xí)和隨機(jī)森林
第08章 降維
(第二部分 神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí))
第9章 啟動(dòng)和運(yùn)行TensorFlow
第10章 人工神經(jīng)網(wǎng)絡(luò)
第11章 訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)(上)
第11章 訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)(下)
第12章 設(shè)備和服務(wù)器上的分布式 TensorFlow
第13章 卷積神經(jīng)網(wǎng)絡(luò)
第14章 循環(huán)神經(jīng)網(wǎng)絡(luò)
第15章 自編碼器
第16章 強(qiáng)化學(xué)習(xí)(上)
第16章 強(qiáng)化學(xué)習(xí)(下)


馬爾可夫決策過(guò)程

在二十世紀(jì)初军拟,數(shù)學(xué)家 Andrey Markov 研究了沒(méi)有記憶的隨機(jī)過(guò)程胳徽,稱(chēng)為馬爾可夫鏈贞间。這樣的過(guò)程具有固定數(shù)量的狀態(tài)雏门,并且在每個(gè)步驟中隨機(jī)地從一個(gè)狀態(tài)演化到另一個(gè)狀態(tài)。它從狀態(tài)S演變?yōu)闋顟B(tài)S'的概率是固定的梯啤,它只依賴(lài)于(S, S')對(duì)卿吐,而不是依賴(lài)于過(guò)去的狀態(tài)(系統(tǒng)沒(méi)有記憶)。

圖 16-7 展示了一個(gè)具有四個(gè)狀態(tài)的馬爾可夫鏈的例子沟娱。假設(shè)該過(guò)程從狀態(tài)S0開(kāi)始,并且在下一步驟中有 70% 的概率保持在該狀態(tài)不變中腕柜。最終济似,它必然離開(kāi)那個(gè)狀態(tài),并且永遠(yuǎn)不會(huì)回來(lái)盏缤,因?yàn)闆](méi)有其他狀態(tài)回到S0砰蠢。如果它進(jìn)入狀態(tài)S1,那么它很可能會(huì)進(jìn)入狀態(tài)S2(90% 的概率)唉铜,然后立即回到狀態(tài)S1(以 100% 的概率)台舱。它可以在這兩個(gè)狀態(tài)之間交替多次,但最終它會(huì)落入狀態(tài)S3并永遠(yuǎn)留在那里(這是一個(gè)終端狀態(tài))潭流。馬爾可夫鏈可以有非常不同的應(yīng)用竞惋,它們?cè)跓崃W(xué)、化學(xué)灰嫉、統(tǒng)計(jì)學(xué)等方面有著廣泛的應(yīng)用拆宛。

圖16-7 馬爾科夫鏈案例

馬爾可夫決策過(guò)程最初是在 20 世紀(jì) 50 年代由 Richard Bellman 描述的。它們類(lèi)似于馬爾可夫鏈讼撒,但有一個(gè)連結(jié):在狀態(tài)轉(zhuǎn)移的每一步中浑厚,一個(gè)智能體可以選擇幾種可能的動(dòng)作中的一個(gè),并且轉(zhuǎn)移概率取決于所選擇的動(dòng)作椿肩。此外瞻颂,一些狀態(tài)轉(zhuǎn)移返回一些獎(jiǎng)勵(lì)(正或負(fù)),智能體的目標(biāo)是找到一個(gè)策略郑象,隨著時(shí)間的推移將最大限度地提高獎(jiǎng)勵(lì)贡这。

例如,圖 16-8 中所示的 MDP 在每個(gè)步驟中具有三個(gè)狀態(tài)和三個(gè)可能的離散動(dòng)作厂榛。如果從狀態(tài)S0開(kāi)始盖矫,隨著時(shí)間的推移可以在動(dòng)作A0A1A2之間進(jìn)行選擇击奶。如果它選擇動(dòng)作A1辈双,它就保持在狀態(tài)S0中,并且沒(méi)有任何獎(jiǎng)勵(lì)柜砾。因此湃望,如果愿意的話(huà),它可以決定永遠(yuǎn)呆在那里。但是证芭,如果它選擇動(dòng)作A0瞳浦,它有 70% 的概率獲得 10 獎(jiǎng)勵(lì),并保持在狀態(tài)S0废士。然后叫潦,它可以一次又一次地嘗試獲得盡可能多的獎(jiǎng)勵(lì)。但它將在狀態(tài)S1中結(jié)束這樣的行為官硝。在狀態(tài)S1中矗蕊,它只有兩種可能的動(dòng)作:A0A1。它可以通過(guò)反復(fù)選擇動(dòng)作A1來(lái)選擇停留氢架,或者它可以選擇動(dòng)作A2移動(dòng)到狀態(tài)S2并得到 -50 獎(jiǎng)勵(lì)傻咖。在狀態(tài)S3中,除了采取行動(dòng)A1之外达箍,別無(wú)選擇没龙,這將最有可能引導(dǎo)它回到狀態(tài)S0,在途中獲得 40 的獎(jiǎng)勵(lì)缎玫。通過(guò)觀察這個(gè) MDP,你能猜出哪一個(gè)策略會(huì)隨著時(shí)間的推移而獲得最大的回報(bào)嗎解滓?在狀態(tài)S0中赃磨,清楚地知道A0是最好的選擇,在狀態(tài)S3中洼裤,智能體別無(wú)選擇邻辉,只能采取行動(dòng)A1,但是在狀態(tài)S1中腮鞍,智能體否應(yīng)該保持不動(dòng)(A0)或通過(guò)火(A2)值骇,這是不明確的。

圖16-8 馬爾科夫決策過(guò)程案例

Bellman 找到了一種估計(jì)任何狀態(tài)S的最佳狀態(tài)值的方法移国,他提出了V(s)吱瘩,它是智能體在其采取最佳行為達(dá)到狀態(tài)s后所有衰減未來(lái)獎(jiǎng)勵(lì)的總和的平均期望。他表明迹缀,如果智能體的行為最佳使碾,那么貝爾曼最優(yōu)性公式適用(見(jiàn)公式 16-1)。這個(gè)遞歸公式表示祝懂,如果智能體最優(yōu)地運(yùn)行票摇,那么當(dāng)前狀態(tài)的最優(yōu)值等于在采取一個(gè)最優(yōu)動(dòng)作之后平均得到的獎(jiǎng)勵(lì),加上該動(dòng)作可能導(dǎo)致的所有可能的下一個(gè)狀態(tài)的期望最優(yōu)值砚蓬。

公式16-1 貝爾曼最優(yōu)性公式

其中:

  • T為智能體選擇動(dòng)作a時(shí)從狀態(tài)s到狀態(tài)s'的概率

  • R為智能體選擇以動(dòng)作a從狀態(tài)s到狀態(tài)s'的過(guò)程中得到的獎(jiǎng)勵(lì)

  • γ為衰減率

這個(gè)等式直接引出了一種算法矢门,該算法可以精確估計(jì)每個(gè)可能狀態(tài)的最優(yōu)狀態(tài)值:首先將所有狀態(tài)值估計(jì)初始化為零,然后用數(shù)值迭代算法迭代更新它們(見(jiàn)公式 16-2)。一個(gè)顯著的結(jié)果是祟剔,給定足夠的時(shí)間傅事,這些估計(jì)保證收斂到最優(yōu)狀態(tài)值,對(duì)應(yīng)于最優(yōu)策略峡扩。

公式16-2 數(shù)值迭代算法

其中:

  • Vk(s)是在k次算法迭代對(duì)狀態(tài)s的估計(jì)

筆記:
該算法是動(dòng)態(tài)規(guī)劃的一個(gè)例子蹭越,它將了一個(gè)復(fù)雜的問(wèn)題(在這種情況下,估計(jì)潛在的未來(lái)衰減獎(jiǎng)勵(lì)的總和)變?yōu)榭商幚淼淖訂?wèn)題教届,可以迭代地處理(在這種情況下响鹃,找到最大化平均報(bào)酬與下一個(gè)衰減狀態(tài)值的和的動(dòng)作)

了解最佳狀態(tài)值可能是有用的,特別是評(píng)估策略案训,但它沒(méi)有明確地告訴智能體要做什么买置。幸運(yùn)的是,Bellman 發(fā)現(xiàn)了一種非常類(lèi)似的算法來(lái)估計(jì)最優(yōu)狀態(tài)-動(dòng)作值(state-action values)强霎,通常稱(chēng)為 Q 值忿项。狀態(tài)行動(dòng)(S, A)對(duì)的最優(yōu) Q 值,記為Q(s, a)城舞,是智能體在到達(dá)狀態(tài)S轩触,然后選擇動(dòng)作A之后平均衰減未來(lái)獎(jiǎng)勵(lì)的期望的總和。但是在它看到這個(gè)動(dòng)作的結(jié)果之前家夺,假設(shè)它在該動(dòng)作之后的動(dòng)作是最優(yōu)的脱柱。

下面是它的工作原理:再次,通過(guò)初始化所有的 Q 值估計(jì)為零拉馋,然后使用 Q 值迭代算法更新它們(參見(jiàn)公式 16-3)榨为。

公式16-3 Q值迭代算法

一旦你有了最佳的 Q 值,定義最優(yōu)的策略π*(s)煌茴,它是平凡的:當(dāng)智能體處于狀態(tài)S時(shí)随闺,它應(yīng)該選擇具有最高 Q 值的動(dòng)作,用于該狀態(tài):

讓我們把這個(gè)算法應(yīng)用到圖 16-8 所示的 MDP 中蔓腐。首先矩乐,我們需要定義 MDP:

nan=np.nan  # 代表不可能的動(dòng)作 
T = np.array([  # shape=[s, a, s']        
    [[0.7, 0.3, 0.0], [1.0, 0.0, 0.0], [0.8, 0.2, 0.0]],
    [[0.0, 1.0, 0.0], [nan, nan, nan], [0.0, 0.0, 1.0]],       
    [[nan, nan, nan], [0.8, 0.1, 0.1], [nan, nan, nan]],    ]) 
R = np.array([  # shape=[s, a, s']        
    [[10., 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]],        
    [[10., 0.0, 0.0], [nan, nan, nan], [0.0, 0.0, -50.]],        
    [[nan, nan, nan], [40., 0.0, 0.0], [nan, nan, nan]],    ]) 
possible_actions = [[0, 1, 2], [0, 2], [1]] 

讓我們運(yùn)行 Q 值迭代算法

Q = np.full((3, 3), -np.inf)  # -inf 對(duì)應(yīng)著不可能的動(dòng)作 
for state, actions in enumerate(possible_actions):    
    Q[state, actions] = 0.0  # 對(duì)所有可能的動(dòng)作初始化為0.0
learning_rate = 0.01 
discount_rate = 0.95 
n_iterations = 100
for iteration in range(n_iterations):   
    Q_prev = Q.copy()    
    for s in range(3):        
        for a in possible_actions[s]:            
            Q[s, a] = np.sum([T[s, a, sp] * (R[s, a, sp] + discount_rate * np.max(Q_prev[sp]))  
            for sp in range(3)]) 

結(jié)果的 Q 值類(lèi)似于如下:

>>> Q 
array([[ 21.89498982,  20.80024033,  16.86353093],       
        [  1.11669335,         -inf,   1.17573546],       
        [        -inf,  53.86946068,         -inf]]) 
>>> np.argmax(Q, axis=1)  # 每一狀態(tài)的最優(yōu)動(dòng)作
array([0, 2, 1]) 

這給我們這個(gè) MDP 的最佳策略,當(dāng)使用 0.95 的衰減率時(shí):在狀態(tài)S0選擇動(dòng)作A0合住,在狀態(tài)S1選擇動(dòng)作A2(通過(guò)火焰4戮)在狀態(tài)S2中選擇動(dòng)作A1(唯一可能的動(dòng)作)。有趣的是透葛,如果你把衰減率降低到 0.9笨使,最優(yōu)的策略改變:在狀態(tài)S1中,最好的動(dòng)作變成A0(保持不變僚害;不通過(guò)火)硫椰。這是有道理的繁调,因?yàn)槿绻阏J(rèn)為現(xiàn)在比未來(lái)更重要,那么未來(lái)獎(jiǎng)勵(lì)的前景是不值得立刻經(jīng)歷痛苦的靶草。

時(shí)間差分學(xué)習(xí)與 Q 學(xué)習(xí)

具有離散動(dòng)作的強(qiáng)化學(xué)習(xí)問(wèn)題通程阋龋可以被建模為馬爾可夫決策過(guò)程,但是智能體最初不知道轉(zhuǎn)移概率是什么(它不知道T)奕翔,并且它不知道獎(jiǎng)勵(lì)會(huì)是什么(它不知道R)裕寨。它必須經(jīng)歷每一個(gè)狀態(tài)和每一次轉(zhuǎn)變并且至少知道一次獎(jiǎng)勵(lì),并且如果要對(duì)轉(zhuǎn)移概率進(jìn)行合理的估計(jì)派继,就必須經(jīng)歷多次宾袜。

時(shí)間差分學(xué)習(xí)(TD 學(xué)習(xí))算法與數(shù)值迭代算法非常類(lèi)似,但考慮到智能體僅具有 MDP 的部分知識(shí)驾窟。一般來(lái)說(shuō)庆猫,我們假設(shè)智能體最初只知道可能的狀態(tài)和動(dòng)作,沒(méi)有更多了绅络。智能體使用探索策略月培,例如,純粹的隨機(jī)策略來(lái)探索 MDP恩急,并且隨著它的發(fā)展杉畜,TD 學(xué)習(xí)算法基于實(shí)際觀察到的轉(zhuǎn)換和獎(jiǎng)勵(lì)來(lái)更新?tīng)顟B(tài)值的估計(jì)(見(jiàn)公式 16-4)。

公式16-4 TD學(xué)習(xí)算法

其中:

a是學(xué)習(xí)率(例如 0.01)

TD 學(xué)習(xí)與隨機(jī)梯度下降有許多相似之處假栓,特別是它一次處理一個(gè)樣本的行為寻行。就像 SGD 一樣,只有當(dāng)你逐漸降低學(xué)習(xí)速率時(shí)匾荆,它才能真正收斂(否則它將在極值點(diǎn)震蕩)。

對(duì)于每個(gè)狀態(tài)S杆烁,該算法只跟蹤智能體離開(kāi)該狀態(tài)時(shí)立即獲得的獎(jiǎng)勵(lì)的平均值牙丽,再加上它期望稍后得到的獎(jiǎng)勵(lì)(假設(shè)它的行為最佳)。

類(lèi)似地兔魂,此時(shí)的Q 學(xué)習(xí)算法是 Q 值迭代算法的改編版本烤芦,其適應(yīng)轉(zhuǎn)移概率和回報(bào)在初始未知的情況(見(jiàn)公式16-5)。

公式16-5 Q學(xué)習(xí)算法

對(duì)于每一個(gè)狀態(tài)動(dòng)作對(duì)(s,a)析校,該算法跟蹤智能體在以動(dòng)作A離開(kāi)狀態(tài)S時(shí)獲得的即時(shí)獎(jiǎng)勵(lì)平均值R构罗,加上它期望稍后得到的獎(jiǎng)勵(lì)。由于目標(biāo)策略將最優(yōu)地運(yùn)行智玻,所以我們?nèi)∠乱粻顟B(tài)的 Q 值估計(jì)的最大值遂唧。

以下是如何實(shí)現(xiàn) Q 學(xué)習(xí):

import numpy.random as rnd
learning_rate0 = 0.05 
learning_rate_decay = 0.1 
n_iterations = 20000
s = 0 # 在狀態(tài) 0開(kāi)始
Q = np.full((3, 3), -np.inf)  # -inf 對(duì)應(yīng)著不可能的動(dòng)作 
for state, actions in enumerate(possible_actions):    
    Q[state, actions] = 0.0  # 對(duì)于所有可能的動(dòng)作初始化為 0.0
for iteration in range(n_iterations):    
    a = rnd.choice(possible_actions[s])  # 隨機(jī)選擇動(dòng)作   
    sp = rnd.choice(range(3), p=T[s, a]) # 使用 T[s, a] 挑選下一狀態(tài)   
    reward = R[s, a, sp]    
    learning_rate = learning_rate0 / (1 + iteration * learning_rate_decay)    
    Q[s, a] = learning_rate * Q[s, a] + (1 - learning_rate) * (reward + discount_rate * np.max(Q[sp]))    
    s = sp # 移動(dòng)至下一狀態(tài)

給定足夠的迭代,該算法將收斂到最優(yōu) Q 值吊奢。這被稱(chēng)為離線(xiàn)策略算法盖彭,因?yàn)檎谟?xùn)練的策略不是正在執(zhí)行的策略。令人驚訝的是,該算法能夠通過(guò)觀察智能體行為隨機(jī)學(xué)習(xí)(例如學(xué)習(xí)當(dāng)你的老師是一個(gè)醉猴子時(shí)打高爾夫球)最佳策略召边。我們能做得更好嗎铺呵?

探索策略

當(dāng)然,只有在探索策略充分探索 MDP 的情況下隧熙,Q 學(xué)習(xí)才能起作用片挂。盡管一個(gè)純粹的隨機(jī)策略保證最終訪(fǎng)問(wèn)每一個(gè)狀態(tài)和每個(gè)轉(zhuǎn)換多次,但可能需要很長(zhǎng)的時(shí)間這樣做贞盯。因此音念,一個(gè)更好的選擇是使用 ε 貪婪策略:在每個(gè)步驟中,它以概率ε隨機(jī)地或以概率為1-ε貪婪地(選擇具有最高 Q 值的動(dòng)作)邻悬。ε 貪婪策略的優(yōu)點(diǎn)(與完全隨機(jī)策略相比)是症昏,它將花費(fèi)越來(lái)越多的時(shí)間來(lái)探索環(huán)境中有趣的部分,因?yàn)?Q 值估計(jì)越來(lái)越好父丰,同時(shí)仍花費(fèi)一些時(shí)間訪(fǎng)問(wèn) MDP 的未知區(qū)域肝谭。以ε為很高的值(例如,1)開(kāi)始蛾扇,然后逐漸減小它(例如攘烛,下降到 0.05)是很常見(jiàn)的。

可選擇的镀首,相比于依賴(lài)于探索的可能性坟漱,另一種方法是鼓勵(lì)探索策略來(lái)嘗試它以前沒(méi)有嘗試過(guò)的行動(dòng)。這可以被實(shí)現(xiàn)為附加于 Q 值估計(jì)的獎(jiǎng)金更哄,如公式 16-6 所示芋齿。

公式16-6 使用探索函數(shù)的Q學(xué)習(xí)

其中:

  • N計(jì)算了在狀態(tài)s時(shí)選擇動(dòng)作a的次數(shù)

  • f是一個(gè)探索函數(shù),例如f=q+K/(1+n)成翩,其中K是一個(gè)好奇超參數(shù)觅捆,它測(cè)量智能體被吸引到未知狀態(tài)的程度。

近似 Q 學(xué)習(xí)

Q 學(xué)習(xí)的主要問(wèn)題是麻敌,它不能很好地?cái)U(kuò)展到具有許多狀態(tài)和動(dòng)作的大(甚至中等)的 MDP栅炒。試著用 Q 學(xué)習(xí)來(lái)訓(xùn)練一個(gè)智能體去玩 Ms. Pac-Man。Ms. Pac-Man 可以吃超過(guò) 250 粒粒子术羔,每一粒都可以存在或不存在(即已經(jīng)吃過(guò))赢赊。因此,可能狀態(tài)的數(shù)目大于 2 的 250 次冪级历,約等于 10 的 75 次冪(并且這是考慮顆粒的可能狀態(tài))释移。這比在可觀測(cè)的宇宙中的原子要多得多,所以你絕對(duì)無(wú)法追蹤每一個(gè) Q 值的估計(jì)值鱼喉。

解決方案是找到一個(gè)函數(shù)秀鞭,使用可管理數(shù)量的參數(shù)來(lái)近似 Q 值趋观。這被稱(chēng)為近似 Q 學(xué)習(xí)。多年來(lái)锋边,人們都是手工在狀態(tài)中提取并線(xiàn)性組合特征(例如皱坛,最近的鬼的距離,它們的方向等)來(lái)估計(jì) Q 值豆巨,但是 DeepMind 表明使用深度神經(jīng)網(wǎng)絡(luò)可以工作得更好剩辟,特別是對(duì)于復(fù)雜的問(wèn)題。它不需要任何特征工程往扔。用于估計(jì) Q 值的 DNN 被稱(chēng)為深度 Q 網(wǎng)絡(luò)(DQN)贩猎,并且使用近似 Q 學(xué)習(xí)的 DQN 被稱(chēng)為深度 Q 學(xué)習(xí)。

在本章的剩余部分萍膛,我們將使用深度 Q 學(xué)習(xí)來(lái)訓(xùn)練一個(gè)智能體去玩 Ms. Pac-Man吭服,就像 DeepMind 在 2013 所做的那樣。代碼可以很容易地調(diào)整蝗罗,調(diào)整后學(xué)習(xí)去玩大多數(shù) Atari 游戲的效果都相當(dāng)好艇棕。在大多數(shù)動(dòng)作游戲中,它可以達(dá)到超人的技能串塑,但它在長(zhǎng)時(shí)運(yùn)行的游戲中卻不太好沼琉。

學(xué)習(xí)去使用深度 Q 學(xué)習(xí)來(lái)玩 Ms.Pac-Man

由于我們將使用 Atari 環(huán)境,我們必須首先安裝 OpenAI gym 的 Atari 環(huán)境依賴(lài)項(xiàng)桩匪。當(dāng)需要玩其他的時(shí)候打瘪,我們也會(huì)為你想玩的其他 OpenAI gym 環(huán)境安裝依賴(lài)項(xiàng)。在 macOS 上傻昙,假設(shè)你已經(jīng)安裝了 Homebrew 程序闺骚,你需要運(yùn)行:

$ brew install cmake boost boost-python sdl2 swig wget

在 Ubuntu 上,輸入以下命令(如果使用 Python 2妆档,用 Python 替換 Python 3):

$ apt-get install -y python3-numpy python3-dev cmake zlib1g-dev libjpeg-dev\    xvfb libav-tools xorg-dev python3-opengl libboost-all-dev libsdl2-dev swig 

隨后安裝額外的 python 包:

$ pip3 install --upgrade 'gym[all]' 

如果一切順利葛碧,你應(yīng)該能夠創(chuàng)造一個(gè) Ms.Pac-Man 環(huán)境:

>>> env = gym.make("MsPacman-v0") 
>>> obs = env.reset() 
>>> obs.shape  # [長(zhǎng),寬过吻,通道] 
(210, 160, 3) 
>>> env.action_space 
Discrete(9) 

正如你所看到的,有九個(gè)離散動(dòng)作可用蔗衡,它對(duì)應(yīng)于操縱桿的九個(gè)可能位置(左纤虽、右、上绞惦、下逼纸、中、左上等)济蝉,觀察結(jié)果是 Atari 屏幕的截圖(見(jiàn)圖 16-9杰刽,左)菠发,表示為 3D Numpy 矩陣。這些圖像有點(diǎn)大贺嫂,所以我們將創(chuàng)建一個(gè)小的預(yù)處理函數(shù)滓鸠,將圖像裁剪并縮小到88×80像素,將其轉(zhuǎn)換成灰度第喳,并提高 Ms.Pac-Man 的對(duì)比度糜俗。這將減少 DQN 所需的計(jì)算量,并加快培訓(xùn)練曲饱。

mspacman_color = np.array([210, 164, 74]).mean()

def preprocess_observation(obs):    
    img = obs[1:176:2, ::2] # 裁剪    
    img = img.mean(axis=2) # 灰度化    
    img[img==mspacman_color] = 0 # 提升對(duì)比度    
    img = (img - 128) / 128 - 1 # 正則化為-1到1.   
    return img.reshape(88, 80, 1) 

過(guò)程的結(jié)果如圖 16-9 所示(右)悠抹。

圖16-9 原始的(左)和經(jīng)過(guò)預(yù)處理(右)的Ms. Pac-Man

接下來(lái),讓我們創(chuàng)建 DQN扩淀。它可以只取一個(gè)狀態(tài)動(dòng)作對(duì)(S,A)作為輸入楔敌,并輸出相應(yīng)的 Q 值Q(s,a)的估計(jì)值,但是由于動(dòng)作是離散的驻谆,所以使用只使用狀態(tài)S作為輸入并輸出每個(gè)動(dòng)作的一個(gè) Q 值估計(jì)的神經(jīng)網(wǎng)絡(luò)是更方便的卵凑。DQN 將由三個(gè)卷積層組成,接著是兩個(gè)全連接層旺韭,其中包括輸出層(如圖 16-10)氛谜。

圖16-10 用深度Q網(wǎng)絡(luò)玩Ms. Pac-Man

正如我們將看到的,我們將使用的訓(xùn)練算法需要兩個(gè)具有相同架構(gòu)(但不同參數(shù))的 DQN:一個(gè)將在訓(xùn)練期間用于驅(qū)動(dòng) Ms.Pac-Man(the actor区端,行動(dòng)者)值漫,另一個(gè)將觀看行動(dòng)者并從其試驗(yàn)和錯(cuò)誤中學(xué)習(xí)(the critic,評(píng)判者)织盼。每隔一定時(shí)間杨何,我們把評(píng)判者網(wǎng)絡(luò)復(fù)制給行動(dòng)者網(wǎng)絡(luò)。因?yàn)槲覀冃枰獌蓚€(gè)相同的 DQN沥邻,所以我們將創(chuàng)建一個(gè)q_network()函數(shù)來(lái)構(gòu)建它們:

from tensorflow.contrib.layers import convolution2d, fully_connected
input_height = 88 
input_width = 80 
input_channels = 1 
conv_n_maps = [32, 64, 64] 
conv_kernel_sizes = [(8,8), (4,4), (3,3)] 
conv_strides = [4, 2, 1] 
conv_paddings = ["SAME"]*3 
conv_activation = [tf.nn.relu]*3 
n_hidden_in = 64 * 11 * 10  # conv3 有 64 個(gè) 11x10 映射
each n_hidden = 512 
hidden_activation = tf.nn.relu 
n_outputs = env.action_space.n  # 9個(gè)離散動(dòng)作
initializer = tf.contrib.layers.variance_scaling_initializer()

def q_network(X_state, scope):    
    prev_layer = X_state    
    conv_layers = []    
    with tf.variable_scope(scope) as scope:        
        for n_maps, kernel_size, stride, padding, activation in zip(conv_n_maps,                                                                  conv_kernel_sizes, 
                                                                    conv_strides,
                                                                    conv_paddings,                                                                  conv_activation):           
            prev_layer = convolution2d(prev_layer, 
                                       num_outputs=n_maps, 
                                       kernel_size=kernel_size,
                                       stride=stride, padding=padding, 
                                       activation_fn=activation,
                                       weights_initializer=initializer)           
            conv_layers.append(prev_layer)       
        last_conv_layer_flat = tf.reshape(prev_layer, shape=[-1, n_hidden_in])     
        hidden = fully_connected(last_conv_layer_flat, n_hidden,
                                 activation_fn=hidden_activation,                                                  weights_initializer=initializer) 
        outputs = fully_connected(hidden, n_outputs, 
                                  activation_fn=None,
                                  weights_initializer=initializer)  
        
    trainable_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                                       scope=scope.name)                
    trainable_vars_by_name = {var.name[len(scope.name):]: var 
                              for var in trainable_vars}    
    return outputs, trainable_vars_by_name

該代碼的第一部分定義了DQN體系結(jié)構(gòu)的超參數(shù)危虱。然后q_network()函數(shù)創(chuàng)建 DQN,將環(huán)境的狀態(tài)X_state作為輸入唐全,以及變量范圍的名稱(chēng)埃跷。請(qǐng)注意,我們將只使用一個(gè)觀察來(lái)表示環(huán)境的狀態(tài)邮利,因?yàn)閹缀鯖](méi)有隱藏的狀態(tài)(除了閃爍的物體和鬼魂的方向)弥雹。

trainable_vars_by_name字典收集了所有 DQN 的可訓(xùn)練變量。當(dāng)我們創(chuàng)建操作以將評(píng)論家 DQN 復(fù)制到行動(dòng)者 DQN 時(shí)延届,這將是有用的剪勿。字典的鍵是變量的名稱(chēng),去掉與范圍名稱(chēng)相對(duì)應(yīng)的前綴的一部分方庭〔藜看起來(lái)像這樣:

>>> trainable_vars_by_name 
{'/Conv/biases:0': <tensorflow.python.ops.variables.Variable at 0x121cf7b50>, '/Conv/weights:0': <tensorflow.python.ops.variables.Variable...>, 
'/Conv_1/biases:0': <tensorflow.python.ops.variables.Variable...>, '/Conv_1/weights:0': <tensorflow.python.ops.variables.Variable...>, '/Conv_2/biases:0': <tensorflow.python.ops.variables.Variable...>, '/Conv_2/weights:0': <tensorflow.python.ops.variables.Variable...>, '/fully_connected/biases:0': <tensorflow.python.ops.variables.Variable...>, '/fully_connected/weights:0': <tensorflow.python.ops.variables.Variable...>, '/fully_connected_1/biases:0': <tensorflow.python.ops.variables.Variable...>, '/fully_connected_1/weights:0': <tensorflow.python.ops.variables.Variable...>}

現(xiàn)在讓我們?yōu)閮蓚€(gè) DQN 創(chuàng)建輸入占位符酱固,以及復(fù)制評(píng)論家 DQN 給行動(dòng)者 DQN 的操作:

X_state = tf.placeholder(tf.float32, 
                         shape=[None, input_height, input_width,input_channels])          
actor_q_values, actor_vars = q_network(X_state, scope="q_networks/actor") 
critic_q_values, critic_vars = q_network(X_state, scope="q_networks/critic")
copy_ops = [actor_var.assign(critic_vars[var_name])  
            for var_name, actor_var in actor_vars.items()] 
copy_critic_to_actor = tf.group(*copy_ops) 

讓我們后退一步:我們現(xiàn)在有兩個(gè) DQN,它們都能夠?qū)h(huán)境狀態(tài)(即預(yù)處理觀察)作為輸入头朱,并輸出在該狀態(tài)下的每一個(gè)可能的動(dòng)作的估計(jì) Q 值运悲。另外,我們有一個(gè)名為copy_critic_to_actor的操作髓窜,將評(píng)論家 DQN 的所有可訓(xùn)練變量復(fù)制到行動(dòng)者 DQN扇苞。我們使用 TensorFlow 的tf.group()函數(shù)將所有賦值操作分組到一個(gè)方便的操作中。

行動(dòng)者 DQN 可以用來(lái)扮演 Ms.Pac-Man(最初非常糟糕)寄纵。正如前面所討論的鳖敷,你希望它足夠深入地探究游戲,所以通常情況下你想將它用 ε 貪婪策略或另一種探索策略相結(jié)合程拭。

但是評(píng)論家 DQN 呢定踱?它如何去學(xué)習(xí)玩游戲?簡(jiǎn)而言之恃鞋,它將試圖使其預(yù)測(cè)的 Q 值去匹配行動(dòng)者通過(guò)其經(jīng)驗(yàn)的游戲估計(jì)的 Q 值崖媚。具體來(lái)說(shuō),我們將讓行動(dòng)者玩一段時(shí)間恤浪,把所有的經(jīng)驗(yàn)保存在回放記憶存儲(chǔ)器中畅哑。每個(gè)記憶將是一個(gè) 5 元組(狀態(tài)、動(dòng)作水由、下一狀態(tài)荠呐、獎(jiǎng)勵(lì)、繼續(xù))砂客,其中“繼續(xù)”項(xiàng)在游戲結(jié)束時(shí)等于 0泥张,否則為 1。接下來(lái)鞠值,我們定期地從回放存儲(chǔ)器中采樣一批記憶媚创,并且我們將估計(jì)這些存儲(chǔ)器中的 Q 值。最后彤恶,我們將使用監(jiān)督學(xué)習(xí)技術(shù)訓(xùn)練評(píng)論家 DQN 去預(yù)測(cè)這些 Q 值钞钙。每隔幾個(gè)訓(xùn)練周期,我們會(huì)把評(píng)論家 DQN 復(fù)制到行動(dòng)者 DQN声离。就這樣歇竟!公式 16-7 示出了用于訓(xùn)練評(píng)論家 DQN 的損失函數(shù):

公式16-7 深度Q學(xué)習(xí)損失函數(shù)

其中:

  • s(i), a(i), r(i) and s′(i)分別為狀態(tài),行為抵恋,回報(bào),和下一狀態(tài)宝磨,均從存儲(chǔ)器中第i次采樣得到
  • m是記憶批處理的長(zhǎng)度
  • θcritic和θactor為評(píng)論者和行動(dòng)者的參數(shù)
  • Q(s'(i),a',θactor)是評(píng)論家 DQN 對(duì)第i記憶狀態(tài)行為 Q 值的預(yù)測(cè)
  • Q(s(i),a(i)critic)是演員 DQN 在選擇動(dòng)作A'時(shí)的下一狀態(tài)S'的期望 Q 值的預(yù)測(cè)
  • y(i)是第ith記憶的目標(biāo) Q 值弧关,注意盅安,它等同于行動(dòng)者實(shí)際觀察到的獎(jiǎng)勵(lì),再加上行動(dòng)者對(duì)如果它能發(fā)揮最佳效果(據(jù)它所知)世囊,未來(lái)的回報(bào)應(yīng)該是什么的預(yù)測(cè)别瞭。
  • J(θcritic)為訓(xùn)練評(píng)論家 DQN 的損失函數(shù)。正如你所看到的株憾,這只是由行動(dòng)者 DQN 估計(jì)的目標(biāo) Q 值y和評(píng)論家 DQN 對(duì)這些 Q 值的預(yù)測(cè)之間的均方誤差蝙寨。

回放記憶是可選的,但強(qiáng)烈推薦使它存在嗤瞎。沒(méi)有它墙歪,你會(huì)訓(xùn)練評(píng)論家 DQN 使用連續(xù)的經(jīng)驗(yàn),這可能是相關(guān)的贝奇。這將引入大量的偏差并且減慢訓(xùn)練算法的收斂性虹菲。通過(guò)使用回放記憶,我們確保饋送到訓(xùn)練算法的存儲(chǔ)器可以是不相關(guān)的掉瞳。

讓我們添加評(píng)論家 DQN 的訓(xùn)練操作毕源。首先,我們需要能夠計(jì)算其在存儲(chǔ)器批處理中的每個(gè)狀態(tài)動(dòng)作的預(yù)測(cè) Q 值陕习。由于 DQN 為每一個(gè)可能的動(dòng)作輸出一個(gè) Q 值霎褐,所以我們只需要保持與在該存儲(chǔ)器中實(shí)際選擇的動(dòng)作相對(duì)應(yīng)的 Q 值。為此该镣,我們將把動(dòng)作轉(zhuǎn)換成一個(gè)熱向量(記住這是一個(gè)滿(mǎn)是 0 的向量冻璃,除了第i個(gè)索引中的1),并乘以 Q 值:這將刪除所有與記憶動(dòng)作對(duì)應(yīng)的 Q 值外的 Q 值拌牲。然后只對(duì)第一軸求和俱饿,以獲得每個(gè)存儲(chǔ)器所需的 Q 值預(yù)測(cè)暇咆。

X_action = tf.placeholder(tf.int32, shape=[None]) 
q_value = tf.reduce_sum(critic_q_values * tf.one_hot(X_action, n_outputs), axis=1, keep_dims=True) 

接下來(lái)熏瞄,讓我們添加訓(xùn)練操作,假設(shè)目標(biāo)Q值將通過(guò)占位符饋入勺届。我們還創(chuàng)建了一個(gè)不可訓(xùn)練的變量global_step土居。優(yōu)化器的minimize()操作將負(fù)責(zé)增加它枣购。另外,我們創(chuàng)建了init操作和Saver擦耀。

y = tf.placeholder(tf.float32, shape=[None, 1]) 
cost = tf.reduce_mean(tf.square(y - q_value)) 
global_step = tf.Variable(0, trainable=False, name='global_step') 
optimizer = tf.train.AdamOptimizer(learning_rate) 
training_op = optimizer.minimize(cost, global_step=global_step)
init = tf.global_variables_initializer() 
saver = tf.train.Saver() 

這就是訓(xùn)練階段的情況棉圈。在我們查看執(zhí)行階段之前,我們需要一些工具眷蜓。首先分瘾,讓我們從回放記憶開(kāi)始。我們將使用一個(gè)deque列表吁系,因?yàn)樵趯?shù)據(jù)推送到隊(duì)列中并在達(dá)到最大內(nèi)存大小時(shí)從列表的末尾彈出它們使是非常有效的德召。我們還將編寫(xiě)一個(gè)小函數(shù)來(lái)隨機(jī)地從回放記憶中采樣一批處理:

from collections import deque

replay_memory_size = 10000 
replay_memory = deque([], maxlen=replay_memory_size)

def sample_memories(batch_size):    
    indices = rnd.permutation(len(replay_memory))[:batch_size]    
    cols = [[], [], [], [], []] # state, action, reward, next_state, continue    
    for idx in indices:        
        memory = replay_memory[idx]        
        for col, value in zip(cols, memory):            
            col.append(value)    
    cols = [np.array(col) for col in cols]    
    return (cols[0], cols[1], cols[2].reshape(-1, 1), cols[3],cols[4].reshape(-1, 1)) 

接下來(lái)白魂,我們需要行動(dòng)者來(lái)探索游戲。我們使用 ε 貪婪策略上岗,并在 50000 個(gè)訓(xùn)練步驟中逐步將ε從 1 降低到 0.05福荸。

eps_min = 0.05 
eps_max = 1.0 
eps_decay_steps = 50000
def epsilon_greedy(q_values, step):    
    epsilon = max(eps_min, eps_max - (eps_max-eps_min) * step/eps_decay_steps)   
     if rnd.rand() < epsilon:        
        return rnd.randint(n_outputs) # 隨機(jī)動(dòng)作   
    else:        
        return np.argmax(q_values) # 最優(yōu)動(dòng)作

就是這樣!我們準(zhǔn)備好開(kāi)始訓(xùn)練了肴掷。執(zhí)行階段不包含太復(fù)雜的東西敬锐,但它有點(diǎn)長(zhǎng),所以深呼吸呆瞻。準(zhǔn)備好了嗎台夺?來(lái)次夠!首先栋烤,讓我們初始化幾個(gè)變量:

n_steps = 100000  # 總的訓(xùn)練步長(zhǎng) 
training_start = 1000  # 在游戲1000次迭代后開(kāi)始訓(xùn)練
training_interval = 3  # 每3次迭代訓(xùn)練一次
save_steps = 50  # 每50訓(xùn)練步長(zhǎng)保存模型
copy_steps = 25  # 每25訓(xùn)練步長(zhǎng)后復(fù)制評(píng)論家Q值到行動(dòng)者
discount_rate = 0.95 
skip_start = 90  # 跳過(guò)游戲開(kāi)始(只是等待時(shí)間) 
batch_size = 50 
iteration = 0  # 游戲迭代
checkpoint_path = "./my_dqn.ckpt" 
done = True # env 需要被重置 

接下來(lái)谒养,讓我們打開(kāi)會(huì)話(huà)并開(kāi)始訓(xùn)練:

with tf.Session() as sess:    
    if os.path.isfile(checkpoint_path):        
        saver.restore(sess, checkpoint_path)    
    else:        
        init.run()    
    while True:        
        step = global_step.eval()        
        if step >= n_steps:            
            break        
        iteration += 1        
        if done: # 游戲結(jié)束,重來(lái)            
            obs = env.reset()            
            for skip in range(skip_start): # 跳過(guò)游戲開(kāi)頭              
                obs, reward, done, info = env.step(0)            
                state = preprocess_observation(obs)

        # 行動(dòng)者評(píng)估要干什么        
        q_values = actor_q_values.eval(feed_dict={X_state: [state]})        
        action = epsilon_greedy(q_values, step)

        # 行動(dòng)者開(kāi)始玩游戲       
        obs, reward, done, info = env.step(action)        
        next_state = preprocess_observation(obs)

        # 讓我們記下來(lái)剛才發(fā)生了啥        
        replay_memory.append((state, action, reward, next_state, 1.0 - done))        state = next_state

        if iteration < training_start or iteration % training_interval != 0:                continue

        # 評(píng)論家學(xué)習(xí)        
        X_state_val, X_action_val, rewards, X_next_state_val, continues = (            sample_memories(batch_size))        
        next_q_values = actor_q_values.eval( feed_dict={X_state: X_next_state_val})    
        max_next_q_values = np.max(next_q_values, axis=1, keepdims=True)        
        y_val = rewards + continues * discount_rate * max_next_q_values        
        training_op.run(feed_dict={X_state: X_state_val,X_action: X_action_val, y: y_val})

        # 復(fù)制評(píng)論家Q值到行動(dòng)者        
        if step % copy_steps == 0:            
            copy_critic_to_actor.run()

        # 保存模型        
        if step % save_steps == 0:            
            saver.save(sess, checkpoint_path)

如果檢查點(diǎn)文件存在明郭,我們就開(kāi)始恢復(fù)模型买窟,否則我們只需初始化變量。然后薯定,主循環(huán)開(kāi)始始绍,其中iteration計(jì)算從程序開(kāi)始以來(lái)游戲步驟的總數(shù),同時(shí)step計(jì)算從訓(xùn)練開(kāi)始的訓(xùn)練步驟的總數(shù)(如果恢復(fù)了檢查點(diǎn)话侄,也恢復(fù)全局步驟)亏推。然后代碼重置游戲(跳過(guò)第一個(gè)無(wú)聊的等待游戲的步驟,這步驟啥都沒(méi)有)年堆。接下來(lái)吞杭,行動(dòng)者評(píng)估該做什么,并且玩游戲变丧,并且它的經(jīng)驗(yàn)被存儲(chǔ)在回放記憶中芽狗。然后,每隔一段時(shí)間(熱身期后)痒蓬,評(píng)論家開(kāi)始一個(gè)訓(xùn)練步驟童擎。它采樣一批回放記憶,并要求行動(dòng)者估計(jì)下一狀態(tài)的所有動(dòng)作的Q值攻晒,并應(yīng)用公式 16-7 來(lái)計(jì)算目標(biāo) Q 值y_val.這里唯一棘手的部分是顾复,我們必須將下一個(gè)狀態(tài)的 Q 值乘以continues向量,以將對(duì)應(yīng)于游戲結(jié)束的記憶 Q 值清零鲁捏。接下來(lái)芯砸,我們進(jìn)行訓(xùn)練操作,以提高評(píng)論家預(yù)測(cè) Q 值的能力。最后乙嘀,我們定期將評(píng)論家的 Q 值復(fù)制給行動(dòng)者末购,然后保存模型。

不幸的是虎谢,訓(xùn)練過(guò)程是非常緩慢的:如果你使用你的破筆記本電腦進(jìn)行訓(xùn)練的話(huà),想讓 Ms. Pac-Man 變好一點(diǎn)點(diǎn)你得花好幾天曹质,如果你看看學(xué)習(xí)曲線(xiàn)婴噩,計(jì)算一下每次的平均獎(jiǎng)勵(lì),你會(huì)發(fā)現(xiàn)到它是非常嘈雜的羽德。在某些情況下几莽,很長(zhǎng)一段時(shí)間內(nèi)可能沒(méi)有明顯的進(jìn)展,直到智能體學(xué)會(huì)在合理的時(shí)間內(nèi)生存宅静。如前所述章蚣,一種解決方案是將盡可能多的先驗(yàn)知識(shí)注入到模型中(例如,通過(guò)預(yù)處理姨夹、獎(jiǎng)勵(lì)等)纤垂,也可以嘗試通過(guò)首先訓(xùn)練它來(lái)模仿基本策略來(lái)引導(dǎo)模型。在任何情況下磷账,RL仍然需要相當(dāng)多的耐心和調(diào)整峭沦,但最終結(jié)果是非常令人興奮的。

練習(xí)

  1. 你怎樣去定義強(qiáng)化學(xué)習(xí)逃糟?它與傳統(tǒng)的監(jiān)督以及非監(jiān)督學(xué)習(xí)有什么不同吼鱼?
  2. 你能想到什么本章沒(méi)有提到過(guò)的強(qiáng)化學(xué)習(xí)應(yīng)用?智能體是什么绰咽?什么是可能的動(dòng)作菇肃,什么是獎(jiǎng)勵(lì)?
  3. 什么是衰減率取募?如果你修改了衰減率那最優(yōu)策略會(huì)變化嗎琐谤?
  4. 你怎么去定義強(qiáng)化學(xué)習(xí)智能體的表現(xiàn)?
  5. 什么是信用評(píng)估問(wèn)題矛辕?它怎么出現(xiàn)的笑跛?你怎么解決?
  6. 使用回放記憶的目的是什么聊品?
  7. 什么是閉策略 RL 算法飞蹂?
  8. 使用深度 Q 學(xué)習(xí)來(lái)處理 OpenAI gym 的“BypedalWalker-v2” 。QNET 不需要對(duì)這個(gè)任務(wù)使用非常深的網(wǎng)絡(luò)翻屈。
  9. 使用策略梯度訓(xùn)練智能體扮演 Pong陈哑,一個(gè)著名的 Atari 游戲(PANV0 在 OpenAI gym 的 Pong-v0)。注意:個(gè)人的觀察不足以說(shuō)明球的方向和速度。一種解決方案是一次將兩次觀測(cè)傳遞給神經(jīng)網(wǎng)絡(luò)策略惊窖。為了減少維度和加速訓(xùn)練刽宪,你必須預(yù)先處理這些圖像(裁剪,調(diào)整大小界酒,并將它們轉(zhuǎn)換成黑白)圣拄,并可能將它們合并成單個(gè)圖像(例如去疊加它們)。
  10. 如果你有大約 100 美元備用毁欣,你可以購(gòu)買(mǎi) Raspberry Pi 3 再加上一些便宜的機(jī)器人組件庇谆,在 PI 上安裝 TensorFlow,然后讓我們嗨起來(lái)~凭疮!舉個(gè)例子饭耳,看看 Lukas Biewald 的這個(gè)有趣的帖子,或者看看 GoPiGo 或 BrickPi执解。為什么不嘗試通過(guò)使用策略梯度訓(xùn)練機(jī)器人來(lái)構(gòu)建真實(shí)的 cartpole 寞肖?或者造一個(gè)機(jī)器人蜘蛛,讓它學(xué)會(huì)走路衰腌;當(dāng)它接近某個(gè)目標(biāo)時(shí)新蟆,給予獎(jiǎng)勵(lì)(你需要傳感器來(lái)測(cè)量目標(biāo)的距離)。唯一的限制就是你的想象力桶唐。

練習(xí)答案均在附錄 A栅葡。

感謝

在我們結(jié)束這本書(shū)的最后一章之前,我想感謝你們讀到最后一段尤泽。我真心希望你能像我寫(xiě)這本書(shū)一樣愉快地閱讀這本書(shū)欣簇,這對(duì)你的項(xiàng)目,或多或少都是有用的坯约。

如果發(fā)現(xiàn)錯(cuò)誤熊咽,請(qǐng)發(fā)送反饋。更一般地說(shuō)闹丐,我很想知道你的想法横殴,所以請(qǐng)不要猶豫,通過(guò) O'Reilly 來(lái)與我聯(lián)系卿拴,或者通過(guò) ageron/handson-ml GITHUB 項(xiàng)目來(lái)練習(xí)衫仑。

對(duì)你來(lái)說(shuō),我最好的建議是練習(xí)和練習(xí):如果你還沒(méi)有做過(guò)這些練習(xí)堕花,試著使用 Juyter notebook 參加所有的練習(xí)文狱,加入 kaggle 網(wǎng)站或其他 ML 社區(qū),看 ML 課程缘挽,閱讀論文瞄崇,參加會(huì)議呻粹,會(huì)見(jiàn)專(zhuān)家。您可能還想研究我們?cè)诒緯?shū)中沒(méi)有涉及的一些主題苏研,包括推薦系統(tǒng)等浊、聚類(lèi)算法、異常檢測(cè)算法和遺傳算法摹蘑。

我最大的希望是筹燕,這本書(shū)將激勵(lì)你建立一個(gè)美妙的 ML 應(yīng)用程序,這將有利于我們所有人衅鹿!那會(huì)是什么呢庄萎?

2016 年 11 月 26 日,Aurélien Géron


(第一部分 機(jī)器學(xué)習(xí)基礎(chǔ))
第01章 機(jī)器學(xué)習(xí)概覽
第02章 一個(gè)完整的機(jī)器學(xué)習(xí)項(xiàng)目(上)
第02章 一個(gè)完整的機(jī)器學(xué)習(xí)項(xiàng)目(下)
第03章 分類(lèi)
第04章 訓(xùn)練模型
第05章 支持向量機(jī)
第06章 決策樹(shù)
第07章 集成學(xué)習(xí)和隨機(jī)森林
第08章 降維
(第二部分 神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí))
第9章 啟動(dòng)和運(yùn)行TensorFlow
第10章 人工神經(jīng)網(wǎng)絡(luò)
第11章 訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)(上)
第11章 訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)(下)
第12章 設(shè)備和服務(wù)器上的分布式 TensorFlow
第13章 卷積神經(jīng)網(wǎng)絡(luò)
第14章 循環(huán)神經(jīng)網(wǎng)絡(luò)
第15章 自編碼器
第16章 強(qiáng)化學(xué)習(xí)(上)
第16章 強(qiáng)化學(xué)習(xí)(下)


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末塘安,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子援奢,更是在濱河造成了極大的恐慌兼犯,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件集漾,死亡現(xiàn)場(chǎng)離奇詭異切黔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)具篇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)纬霞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人驱显,你說(shuō)我怎么就攤上這事诗芜。” “怎么了埃疫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵伏恐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我栓霜,道長(zhǎng)翠桦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任胳蛮,我火速辦了婚禮销凑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仅炊。我一直安慰自己斗幼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布茂洒。 她就那樣靜靜地躺著孟岛,像睡著了一般瓶竭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渠羞,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天斤贰,我揣著相機(jī)與錄音,去河邊找鬼次询。 笑死荧恍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屯吊。 我是一名探鬼主播送巡,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼盒卸!你這毒婦竟也來(lái)了骗爆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蔽介,失蹤者是張志新(化名)和其女友劉穎摘投,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體虹蓄,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡犀呼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了薇组。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片外臂。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖律胀,靈堂內(nèi)的尸體忽然破棺而出宋光,到底是詐尸還是另有隱情,我是刑警寧澤累铅,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布跃须,位于F島的核電站,受9級(jí)特大地震影響娃兽,放射性物質(zhì)發(fā)生泄漏菇民。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一投储、第九天 我趴在偏房一處隱蔽的房頂上張望第练。 院中可真熱鬧,春花似錦玛荞、人聲如沸娇掏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)婴梧。三九已至下梢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塞蹭,已是汗流浹背孽江。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留番电,地道東北人岗屏。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像漱办,于是被迫代替她去往敵國(guó)和親这刷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容