翻译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框架内有效地实现策略梯度学习,然后使用交叉熵损失进行训练。
  • 策略梯度训练可能需要手动调整优化器。对于策略梯度学习,您可能需要比用于监督学习的更小的学习率和更大的小训练集。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章