翻譯Deep Learning and the Game of Go(12)第十章:利用策略梯度進行強化學習

本章介紹

  • 利用策略梯度學習來提升遊戲對弈水平
  •  使用Keras實現策略梯度學習
  • 爲策略梯度學習改變優化器

第9章向您展示瞭如何讓一個下圍棋的程序和自己對弈,並把結果保存在經驗數據中這是強化學習的前半部分;下一步是運用經驗數據來提升代理水平,以便讓它可以更經常地獲勝。來自上一章的代理使用神經網絡來選擇落子。作爲一個思維實驗,想象一下你隨機改變神經網絡的每個權重,然後代理將選擇不同的落子。只要運氣好,這些新落子中的一些會比舊落子更好;而另一些則會更糟。最終平衡下來,最新的代理可能會比以前的版本稍微強一點或弱一點。它走哪條路都是隨機的。

你能改進一下嗎?本章涵蓋策略梯度學習的一種形式。爲了使AI能更好地做任務,策略梯度方法提供了一組往哪個方向改變權重的方案。與隨機改變權重不同,你可以分析經驗數據來猜測是增加還是減少一個特定的權重。隨機性仍然在起作用,但策略梯度學習會提高了你的希望。

回想第九章,你做決定依靠的是一個隨機梯度----一個指定代理所能做的每一個可能的落子概率的函數。本章所涉及的策略學習方法工作方式就像這樣:

  • 1 當代理人獲勝時,就增加它選擇的每一個落子的概率。
  • 2.當代理人輸掉時,就減少它選擇的每一個落子的概率。

首先,您將通過一個簡化的示例來說明如何使用這種技術來改進策略,從而可以贏得更多的對局。接下來,您將看到如何使用梯度來做你想要的改變----提升或減少一個特定落子的概率----在一個神經網絡中。在管理訓練過程中,我們會總結一些實用的小技巧。

10.1 隨機的遊戲怎麼一個決定是否是好的

爲了引入策略學習,我們將從一個比圍棋簡單得多的遊戲開始。讓我們把這個遊戲叫加起來。以下是規則:

  • 在每個回合中,每個玩家選擇一個介於1到5之間的數字。
  • 一百回合以後,每個玩家把他們所選擇的所有數字加起來。
  • 總數較高的選手獲勝。

是的,這意味着最佳策略是在每個回合中都選擇5。不,這可能不是一個好遊戲。但我們會使用這個遊戲來說明策略學習,在這裏,您可以根據遊戲結果逐步改進隨機策略。因爲你知道這個遊戲的正確策略,所以你可以看到策略是怎樣學習從而可以完美地發揮。

加起來是一個簡單的遊戲,但我們可以用它來類比一個更嚴肅的遊戲,比如圍棋。就像在圍棋中一樣,加起來的遊戲也可以玩很長,同一遊戲中玩家有很多機會做出好的或錯誤的選擇。爲了根據遊戲結果更新策略,您需要確定哪些落子應該爲贏棋或輸棋而受到表揚或指責。這是稱爲信度分配問題(credit assignment problem),這是強化學習的核心問題之一。本節就演示瞭如何平均許多遊戲結果來分配信度給單個決定。在第12章中,您將在此技術的基礎上創建一個更復雜和健壯的信度分配算法。

讓我們從一個純隨機策略開始,在該策略中您在相同概率下從五個選項中選擇(這樣的政策叫做統一隨機)。在一場完整的遊戲中,你會期望政策選擇1大約20次,2大約20次,3大約20次,等等。但你不會期望1正好出現20次;它將因遊戲而異。下面的列表顯示了一個Python函數,它模擬了一個代理將在遊戲中所做的所有選擇。圖10.1顯示了一些示例運行的結果;您可以嘗試自己的代碼片段幾次,然後查看。

import numpy as np

count = {1:0,2:0,3:0,4:0,5:0}

for i in range(100):
    choice = np.random.choice([1,2,3,4,5])
    count[choice]+=1

print(count)

即使代理在每個遊戲中都遵循完全相同的策略,策略的隨機性也會導致遊戲間的差異,而你可以利用這種差異來改進策略。

下面就顯示了一個函數,它模擬了一個完整的加起來遊戲,跟蹤每個玩家做出的決定,並計算出贏家。

import numpy as np


class GameResult:
    def __init__(self,winner_choice,losing_choice):
        self.winner_choice = winner_choice;
        self.losing_choice = losing_choice;
    def show(self):
        return (self.winner_choice,self.losing_choice)

def simulate_game(policy):
    print("policy:"+str(policy))
    player1_count = {1:0,2:0,3:0,4:0,5:0}
    player1_total = 0
    player2_count = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
    player2_total = 0
    for i in range(100):
        player1_choice = np.random.choice([1,2,3,4,5],p=policy)
        player1_count[player1_choice]+=1
        player1_total+=player1_choice
        player2_choice = np.random.choice([1, 2, 3, 4, 5], p=policy)
        player2_count[player2_choice] += 1
        player2_total += player2_choice
    print("player1:"+str(player1_total))
    print("player2:"+str(player2_total))
    if player1_total>player2_total:
        return GameResult(player1_count,player2_count)
    else:
        return GameResult(player2_count,player1_count)


print(stimulate_game([0.2,0.2,0.2,0.2,0.2]).show())

 運行幾次並查看結果;列表10.3顯示了一些示例運行。通常情況下,獲勝者會少選1,但並不總是這樣。有時獲勝者會多選5,但同樣不能保證

如果你看清單10.3中的四個例子游戲中的平均值,你會看到勝利者選擇1,平均是18.75次,而失敗者選擇1平均是22.5次。這就造成了一種感覺,因爲1是個壞動作。雖然所有這些遊戲都是根據同一個策略進行取樣的,但贏家和輸家之間的分佈是不同的,因爲選擇更多的1經常會導致代理人輸掉比賽。

代理人選擇的數字獲勝和代理人選擇的數字輸掉比賽之間的區別可以告訴你選擇哪些數字更好。爲了改進策略,您可以利用這些差異去更新政策。在這種情況下,您可以爲每次在獲勝中出現一個操作添加一個小的固定數目,併爲每次在失敗中出現一個操作時減去一個小的固定數目。然後概率的分佈就會將慢慢地轉向更經常出現在勝利中的操作----即你認爲這是好的移動。對於加起來這個遊戲,該算法工作良好。但對於學習一個像圍棋這樣複雜的遊戲時,你將需要使用一個更復雜的方案來更新概率;我們在10.2節中就涵蓋了這一點。


num_games= 50
choices = [1, 2, 3, 4, 5]
policy = np.array([0.2, 0.2, 0.2, 0.2, 0.2])
learning_rate = 0.005
for i in range(num_games):
    win_counts, lose_counts = simulate_game(policy).show()
    # 將列表變成可索引的序列
    for i, choice in enumerate(choices):
        # 如果選擇在贏中出現的頻率更高,那麼net_wins將是積極的;如果選擇在輸中出現的頻率更高,那麼選擇就會是消極的。
        net_wins = win_counts[choice] - lose_counts[choice]
        policy[i] += learning_rate * net_wins
    policy = normalize(policy)
    print('%d: %s' % (i, policy))

圖10.2顯示了策略在整個演示過程中的演變過程。在大約一千場遊戲之後,算法學會了停止選擇最差的操作。再來一千場遊戲中,它幾乎達成了完美的策略:在每個回合中都選擇5。曲線並不完全平滑。有時後AI會在一場比賽中選擇很多的1,無論是否在贏的對局中;然後策略會(錯誤地)轉向1,而這些錯誤會在很多對局中被消除

圖10.2這個圖表顯示了在簡化的策略學習下策略是如何發展的。在數百場遊戲中,經紀人逐漸不太可能選擇最差操作1。同樣,代理人逐漸變得很大可能去選擇最佳操作5。這兩條曲線都是搖擺不定的,因爲政策有時會逐漸邁出錯誤的一小步

10.2.使用梯度下降修改神經網絡

學習玩加起來遊戲和學習圍棋有一個明顯的區別。您在加起來示例中使用的策略在任何方面都不依賴於遊戲狀態。選擇5是一直以來是一個好的舉動,而選擇1一直以來是一個不好的舉動。在圍棋中,當我們說我們想增加某一特定落子的概率時,我們真的想在類似的情況下增加該落子的概率。但是這種類似情況的定義是不可能模糊的。在這裏,我們依靠神經網絡的力量來得出類似情況的真正含義。

當你在第9章創建一個神經網絡策略時,您構建了一個函數,它把棋盤局面作爲輸入,並將概率分佈作爲輸出。對於你的經驗數據中的每一個棋盤局面,如果一個落子導致勝利,你就想要去增加選擇該落子的概率,而如果一個落子導致失敗,你就想要去減少選擇落子的概率,但是你不能像你在10.1節中所做的那樣強行修改策略。相反,你必須要去修改神經網絡的權重,以使你想要的結果發生。梯度下降是使這成爲可能的工具。使用梯度下降去修改策略被稱爲策略梯度學習。這種想法有一些不同,我們在本章中描述的特定學習算法有時被稱爲蒙特卡羅策略梯度(Monte Carlo policy gradient),或REINFORCE方法。圖10.3顯示了這一過程如何應用於遊戲的高級流程。 

這個強化方法代表回報增量=非負因子*強化偏移*特性合格性,這是梯度更新的公式

讓我們回顧一下梯度下降的監督學習是如何工作的,如第5章所述。你選擇了一個損失函數,該函數表示您的函數離訓練數據有多遠,並計算它的梯度。目標是使損失函數的值更小,這樣就意味着學習函數將更好地匹配訓練數據。梯度下降-逐步更新損失函數中的梯度的方向-提供了降低損失函數的機制。梯度告訴你改變每個權重的方向,以減少損失函數。 

對於策略學習,您希望找到改變每個權重的方向,以便將策略偏向(或遠離)特定的落子。您可以繪製一個損失函數,使其梯度具有有自己的特性。當您有了這些,您可以利用Keras提供的快速和靈活的基礎設施來修改策略網絡的權重。

回想起你第7章的監督學習,對於每個遊戲狀態,您也知道在遊戲中發生的人類落子。你創建了一個目標向量,其中包含每個棋盤局面的0,其中1表示人類落子。損失函數測量了預測概率分佈之間的差距,其梯度指示了縮小差距的方向。在完成一批梯度下降後,預測人類落子的概率略有增加。

這正是你想要達到的效果:增加特定落子的概率。如果你的代理贏了對局,你可以爲代理的落子構造完全相同的目標向量,就好像它是一個來自真實遊戲記錄的人類落子一樣。然後Keras fit函數使AI在正確的方向上更新策略。

關於輸掉棋局的例子?在這種情況下,您希望降低該選擇落子的概率,但您不知道實際的最佳落子。理想情況下,與贏棋比賽有相反的效果。

事實證明,如果你用交叉熵損失函數進行訓練,你可以只在目標向量中插入一個-1,而不是一個1。這將逆轉損失函數的梯度符號,這樣就意味着你的權重將朝着完全相反的方向移動,從而降低概率。

要做到這一點,你必須使用交叉熵損失函數;其他損失函數,如均方誤差,將不會以同樣的方式進行工作。在第七章中,您選擇了交叉熵損失函數,因爲這是訓練網絡來選擇固定選項最有效的方法。在這裏,你選擇它是爲了傳入不同的屬性:在目標向量中將-1交換爲1將逆轉梯度的方向。

再回想一下,您的經驗數據包括三個並行數組:

  • states[i]表示一個在自我對弈過程中,你的代理所面對的圍棋棋盤局面。
  • action[i]表示你的代理給定落子所選擇的落子。
  • rewards[i]表示如果贏得對局就回報1,如果輸掉對局就回報-1。

下面的列表就實現了一個prepare_experience_data函數,該函數將一個ExperienceBuffer打包成適合Keras的fit函數的目標數組,放在PolicyAgent文件裏,用於準備其訓練所需的經驗數據

# 準備經驗數據
def prepare_experience_buffer(experience,board_width,board_height):
    # 得到經驗數目
    experience_size = experience.actions.shape[0]
    target_vector = np.zeros((experience_size,board_width,board_height))
    for i in range(experience_size):
        action = experience.actions[i]
        reward = experience.rewards[i]
        target_vector[i][action] = reward
    return target_vector

 下面的列表顯示瞭如何在PolicyAgent類上實現訓練函數

    # 訓練AI
    # 在進行梯度下降算法過程中,梯度值可能會較大,通過控制clipnorm可以實現梯度的剪裁
    def train(self,experience,learning_rate,clipnorm,batch_size):
        self.model.compile(
            loss = 'categorical_crossentropy',
            optimizer = SGD(learning_rate = learning_rate,clipnorm=clipnorm)
        )

        # 目標向量
        target_vector = prepare_experience_buffer(experience,self.encoder.board_height,self.encoder.board_width)

        #states作爲特徵,target_vector作爲標籤
        self.model.fit(experience.states,target_vector,batch_size=batch_size,epochs=1)

 除了一個ExperienceBUffer之外,這個訓練函數還需要三個參數來修改優化器的行爲:

  • learning_rate是學習速率,它控制每步後權重變化的範圍。
  • clipnorm提供了一個在任何單獨步驟下變化權重的最大值。
  • batch_size控制結合經驗數據和單獨更新權重的落子數目。

你可能需要微調這些參數,以使策略梯度學習獲得一個良好的結果。在10.3節中,我們提供了幫助您找到正確設置的一些小技巧。

在第七章中,你使用了Adadelta和Adagrad優化器,它在整個訓練過程中自動調整學習速率。不幸的是,他們都做出了假設,因而並不總是適用於策略梯度學習。相反,您應該使用基本的隨機梯度下降優化器,並手動設置學習速率。我們要強調的是,在95%的時間裏,像Adadelta或Adagrad這樣的適應性優化器是最好的選擇;你會看到更快的訓練,帶有更少的錯誤。但是在一些罕見的情況下,你需要回到普通的SGD,並且對如何手工設置學習率要有一些瞭解。

注意你只用經驗數據訓練一輪,這與第七章使用同一個訓練集上訓練幾輪不同。這關鍵的區別在於已知第7章中的訓練數據是好的。在這個數據集中的每個遊戲落子都是一個熟練的人類玩家在一個真正的對局中選擇的落子。而在你的自我對弈數據中,遊戲結果是部分隨機的,你不知道哪個落子應爲最終獲勝而受到表揚。你希望通過大量的遊戲來消除錯誤,因此你不想重複使用任何一個遊戲記錄:否則將會導致雙倍誤導。

幸運的是,有了強化學習,你就有了無限的訓練數據供應。不依靠同一個訓練集上運行多次,您應該運行另一批自我對弈並生成一個新的訓練集。

現在你已經準備好了一個訓練函數,下面的列表顯示了一個腳本來做訓練。你能找到在train_pg.py中找到。它將使用第9章的self_play腳本生成經驗數據文件。

import h5py
from keras.models import Sequential
from dlgo.network.LargeLayer import layers
from dlgo.Encoder.ElevenPlaneEncoder import ElevenPlaneEncoder
from keras.layers import Dense
from keras.layers import Activation
from dlgo.agent.ReinforcementLearning.PolicyAgent import PolicyAgent
from dlgo.agent.ReinforcementLearning.ExperienceCollector import load_experience
from dlgo.agent.ReinforcementLearning.PolicyAgent import load_policy_agent



def main():
    experiences = []
    agent = load_policy_agent("initial_pgAgent")
    k=1
    # 加載經驗數據
    # updated_agent_filename = "../updated_pgAgent.h5"
    learning_rate = 0.0001
    batch_size = 10
    clipnorm =1.

    for i in range(100):
        k = i+1
        experiences.append("experienceData/experience_"+str(k)+".h5")
    i = 0
    for experience_file in experiences:
        i += 1
        exp_buffer = load_experience(h5py.File(experience_file))
        agent.train(
            exp_buffer,
            learning_rate=learning_rate,
            clipnorm=clipnorm,
            batch_size=batch_size)
        if i % 10 == 0:
            updated_agent_filename = "updated_pgAgent_" + str(i) + ".h5"
            with h5py.File(updated_agent_filename, 'w') as updated_agent_outf:
                agent.serialize(updated_agent_outf)

10.3 自我對弈訓練的小技巧

調整訓練過程可能是困難的,並且訓練一個大的網絡是緩慢的,這意味着你可能需要等待很長時間來檢查你的結果。你應該爲一些嘗試和錯誤還有一些錯誤的開始做好準備。本節提供了管理長期訓練過程的小技巧。首先,我們提供了關於如何測試和驗證您的機器人的進度的詳細信息,然後我們挖掘和調整影響訓練過程的參數。

強化學習是緩慢的:如果你正在訓練圍棋AI,你可能需要10000局或更多的自我對弈遊戲,然後才能看到明顯的進步。我們建議先在一個較小的板上進行實驗,如9×9,甚至5×5。在小棋盤上,遊戲更短,所以你可以更快地生成自我對弈遊戲;遊戲不是那麼複雜,所以你可以需要更少的訓練數據才能取得進展。這樣,您就可以測試您的代碼,並更快地調整訓練過程。一旦你對你的代碼有信心,你就可以改到一個更大的圍棋棋盤大小。

10.3.1. 評估你的AI進展 

在像圍棋這樣複雜的遊戲中,強化學習可能需要很長時間,特別當你沒有機會去使用專門的硬件,因此沒有什麼比花幾天時間訓練卻發現很多小時前就出了問題更令人沮喪了,因此我們建議定期檢查你的學習代理的進度。你通過模擬更多的遊戲來做到這一點。eval_pg_bot.py腳本使得兩個版本的機器人相互對抗;下面的列表顯示了它是如何工作的。 

from dlgo.gotypes import Player
from dlgo.agent.ReinforcementLearning.PolicyAgent import load_policy_agent
import h5py
from dlgo.agent.ReinforcementLearning.self_play import simulate_game
import sys

def main():
    # 得到30輪經驗數據訓練的AI
    agent1 = load_policy_agent(h5py.File("updated_pgAgent_30.h5"))
    agent2 = load_policy_agent(h5py.File("initial_pgAgent.h5"))
    num_games = 10
    wins = 0
    losses = 0
    color1 = Player.black
    board_size = 19
    for i in range(num_games):
        print('Simulating game %d/%d...' % (i + 1, num_games))
        if color1 == Player.black:
            black_player, white_player = agent1, agent2
        else:
            white_player, black_player = agent1, agent2
        # 進行模擬對局
        game_record = simulate_game(black_player, white_player,board_size)
        if game_record.winner == color1:
            wins += 1
        else:
            losses += 1
        #每下完一局就對調棋子
        color1 = color1.other
    print('Agent 1 record: %d/%d' % (wins, wins + losses))


if __name__=='__main__':
    main()

每輪訓練結束後,您可以將更新的代理與原始代理進行比較,並確認更新的代理正在改進,或者至少沒有惡化。 

 10.3.2. 衡量實力的細小差距

在進行了數以千計的自我對弈遊戲訓練後,你的機器人可能只會比它的前一版本提高几個百分點。衡量一個小的差異是相當困難的。假設你完成了一輪訓練。對於評估,您運行您的更新機器人與以前版本對弈100遊戲。更新後的機器人贏得了53。新機器人真的就強了3%嗎?或者它只是運氣好嗎?你需要一種方法來決定你是否有足夠的數據來準確地評估你的機器人水平。

想象一下,你的訓練毫無效果,你更新的機器人與以前的版本沒有兩樣。那同樣的機器人贏得至少53場比賽的機會是多少?統計學家使用一個叫做二項式檢驗的公式來計算這個機會。Python包scipy 提供了一種方便地實現二項式檢驗的方法: 

from scipy.stats import binom_test

print(binom_test(53,100,0.5))
在該片段中:
  • 53表示您觀察到的獲勝次數。
  • 100表示你模擬的遊戲數量。
  • 0.5如果你的機器人與對方水平相當時,你的機器人贏得一場比賽的概率

二項式檢驗給出了61.7%的值,這意味着如果你的機器人和對手真的完全一樣,它仍然有61.7%的機會贏得53場或更多的比賽。這個概率有時被稱爲p-value,但並不意味着你的機器人沒有學到任何東西的機率是61.7%,這只是意味着你沒有足夠的證據來判斷你的AI取得進步了。如果你想證明你的機器人已經進步了,你需要做更多的試驗。

事實證明,你需要相當多的試驗來可靠地測量如此小的實力差異。如果你跑了1000場比賽,獲得530場勝利,二項式檢驗得出的p值約爲6%。一個常用的指導方針是在作出決定之前尋找p-value5%以下的值,不過5%的門檻並沒有什麼神奇之處。相反,把p-value看作是一個光譜,表明你有多懷疑機器人的獲勝記錄,並使用你的判斷。 

10.3.3.調整隨機梯度下降(SGD)優化器

該SGD優化器有幾個參數可以影響其性能。一般來說,它們在速度和準確性之間有一個權衡。策略梯度學習相對於監督學習通常會對準確性更敏感,所以你需要適當地設置參數。

你必須設置的第一個參數是學習率。要正確地設定學習率,你應該瞭解一個錯誤設置的學習率可能導致的問題。在本節中,您將參考圖10.4。它顯示了你想要最小化的一個假想的目標函數。從概念上講,這個數據就展示了與你在5.4節中研究的東西相同;但是在這裏,我們將它限制在一個維度上來說明幾個特定的點。實際上,你通常是在超過數千個維度去優化一個函數

 圖10.4  這個圖表顯示了一個假設的目標函數如何隨着可學習模型權重而變化。您希望將θ的值從當前位置移動到最小。你可以認爲梯度下降造成權重下滑。

在第5章中,您試圖優化一個損失函數,該函數測量您的預測和已知的正確示例之間的誤差。在這種情況下,其目標是你的機器人的獲勝率。不像損失函數,你不能計算直接計算獲勝率,但您可以從自我對弈數據中估計其梯度。在圖10.4中,x軸表示網絡中的某種權重,y軸表示objective的值有效性隨權重的變化而變化。標記點表示網絡當前狀態..在理想的情況下,你可以想象梯度下降使標記點滾下山坡並定居在山谷裏。如果學習率太小,如圖10.5所示,優化器雖然將向正確的方向移動權重,但需要進行多輪的訓練才能達到最低水平,因此爲了提高效率,你希望學習率儘可能大,而不會造成問題。

                                     圖10.5  在這個例子中,學習率太小,在權重達到最小之前需要進行多次更新。 

如果你學習率調得超過一點,目標可能不會有多大的改善。但是下一個梯度將指向正確的方向,所以它可以在一段時間內來回反彈,如圖10.6所示。

圖10.6這裏,學習率太大,權重超過了目標。在下一輪學習中,梯度將指向相反的方向,但它很可能在下一輪會超調。這可能會導致權重在真正的最小值附近來回反彈。 

在示例目標中,如果你學習率過大,那麼權重就會在右邊的平坦區域結束。圖10.7顯示了這是如何發生的。在那個區域梯度接近於零,我梯度下降不再給你一個關於改變權重的方向的線索。在這種情況下,目標可能會被永久地卡住。這不僅僅是一個理論問題:這些平面區域在具有校正線性單元的網絡中,是常見的,我們在第6章中介紹了這一點。深度學習工程師有時把這個問題稱爲“死的”ReLU:他們被認爲是“死的”,因爲他們返回0的值,並停止對整個學習過程的貢獻。 

這些就是當你向正確的方向過渡時可能會發生的問題。在策略梯度學習中,問題更嚴重,因爲你不知道你要嘗試的真正梯度。在有時候有一個理論函數,它將你的AI實力與其策略網絡的權重聯繫起來,但是你沒有辦法記下這個函數,最好的辦法是從訓練數據中估計梯度。這種估計是嘈雜的,而且有時會指向錯誤的方向。(回顧10.1節中的圖10.2;概率最高的落子經常朝着錯誤的方向邁出一小步。圍棋或相似的複雜遊戲自我對弈數據要比這還嘈雜

如果你向錯誤的方向邁步太遠,權重可能會在左邊的另一個山谷中下降。圖10.8顯示了這個例子是如何發生的。這叫遺忘(forgetting):網絡學會了處理數據集的特定屬性,然後突然取消。

圖10.8 在策略梯度學習中,您試圖從非常嘈雜的信號中估計真實的梯度,有時一個單一的估計會指向錯誤的方向。如果你在錯誤方向改變權重太遠,它可以從中間的真正最小值跳到左邊的局部最小值,它可能會在那裏停留一段時間。 

您還可以採取步驟改進梯度估計。回想一下,隨機梯度下降在小批量上起作用:優化器接受訓練集的一小部分,從這些點計算梯度,然後更新所有的權重。較大的小訓練集大小傾向於平滑錯誤。在Keras中默認的小訓練集大小爲32,這對於許多有監督的學習問題是很好的。對於策略學習,我們建議讓它更大:嘗試1024,甚至2048。 

最後,策略梯度學習很容易陷入局部最大值--一種對策略的任何增量更改都會使機器人變得更弱的情況。有時你可以通過在自我對弈中引入一點額外的隨機性來避免一個局部最大值。在一小部分時間內(比如每輪1%或0.5%),AI可以退出策略並選擇完全隨機落子。 

實際上,策略梯度訓練過程如下:

  1. 生成一大批自我對弈數據
  2. 訓練。
  3. 讓更新版本的AI與以前版本AI進行對弈來測試實力。
  4. 如果新的機器人更強大,就使用這個版本。
  5. 如果機器人的實力大約相同,則需要生成更多的對弈數據並再次訓練。
  6. 如果新的機器人較弱,則需要調整優化器設置並重新進行訓練。調整優化器可能感覺就像穿針引線,但是通過一些實踐和實驗,您可以有一種感覺。表10.1就總結了我們在本節中涵蓋的小技巧。

 

10.4總結 

  • 策略學習是一種強化學習技術,它從經驗數據中更新策略。在玩遊戲的情況下,這意味着AI會根據遊戲結果去選擇更好的落子。
  • 策略學習的一種形式是增加每次贏棋選點的概率,並降低每次輸棋選點的概率。超過千次的對局,使得這個算法將慢慢地更新策略,從而使它更經常地獲勝,這個該算法就被成爲策略梯度學習。
  • 交叉熵損失是爲這樣一種情況設計的:你必須要從固定選項中選出一個。在第七章中,你使用了交叉熵損失來預測一個人在給定的棋盤局面下會選擇哪個落子。你也可以使用交叉熵損失進行策略梯度學習。
  • 您可以通過正確編碼經驗,從而在Keras框架內有效地實現策略梯度學習,然後使用交叉熵損失進行訓練。
  • 策略梯度訓練可能需要手動調整優化器。對於策略梯度學習,您可能需要比用於監督學習的更小的學習率和更大的小訓練集。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章