围棋的棋盘是 19 × 19 的网格,可以在两条线交叉的地方放置棋子,一共有 361 个可以放置棋子的位置,因此动作空间是 A = {1, · · , 361}。比如动作 a = 123 的意思是在第 123 号位置上放棋子。
于是我们便有了类似的策略网络和价值网络
和人类下棋类似,AlphaGo在做决策前,需要在“大脑里”做预判,确保几步以后很可能会占优势。如果只根据当前格局做判断,不往前看,是很难获胜的。
以上只是 MCTS 的基本想法,实际做起来有很多难点需要解决。
观测棋盘上当前的格局,找出所有空位,然后判断其中哪些位置符合围棋规则;每个符合规则的位置对应一个可行的动作。
每一步至少有几十、甚至上百个可行的动作;假如挨个搜索和评估所有可行动作,计算量会大到无法承受。
虽然有几十、上百个可行动作,好在只有少数几个动作有较高的胜算。第一步—— 选择——的目的就是找出胜算较高的动作,只搜索这些好的动作,忽略掉其他的动作。
那么,如何判断动作 a 的好坏呢?
η 是个需要调的超参数 N ( a ) 是动作 a 已经被访问过的次数。
- 初始的时候,对于所有的 a,令 N(a) ← 0。
- 动作 a 每被选中一次,我们就把 N(a) 加一:N(a) ← N(a) + 1。
Q ( a ) 是之前 N ( a ) 次模拟算出来的动作价值,主要由胜率和价值函数决定。
Q ( a ) 的初始值是 0 ; 动作 a 每被选中一次,就会更新一次 Q ( a ) ;如何更新会在第四步说明。
可以这样理解公式 ( 18.1 ) :
把第一步选中的动作记作 a t ,它只是个假想的动作, 只在“模拟器”中执行,而不是 AlphaGo 真正执行的动作。AlphaGo 需要考虑这样一个问题:假如它执行动作 a t ,那么对手会执行什么动作呢?AlphaGo 可以“推己及人”:如果 AlphaGo 认为几个动作很好,对手也会这么认为。此处的状态 s′ 是站在对手的角度观测到的棋盘上的格局,动作 a′t 是(假想)对手选择的动作。
图 18.5 的例子中对手有四种可行动作, AlphaGo 用策略网络算出每个动作的概率值,然后根据概率值随机抽样一个对手的动作,记作 a ′ t 。假设根据概率值 0 . 1 , 0 . 3 , 0 . 2 , 0. 4 做随机抽样,选中第二种动作从 AlphaGo 的角度来看,对手的动作就是 AlphaGo 新的状态。
AlphaGo 需要在模拟中跟对 手将一局游戏进行下去,所以需要一个模拟器(即环境)。在模拟器中,AlphaGo 每执行一个动作,模拟器就会返回一个新的状态。
想要搭建一个好的模 拟器,关键在于使用正确的状态 转移函数 ;如果状态转移函数与事实偏离太远,那么用模拟器做 MCTS 是毫无意义的。
从状态开始,双方都用策略网络 π 做决策,在 模拟器中交替落子,直到分出胜负。当这局游戏结束时,可以观测到奖励 r 。如果 AlphaGo 胜利,则 r = +1 ,否则 r = 1 。
回顾一下,棋盘上真实的状态是,AlphaGo 在模拟器中执行动作 ,然后模拟器中的对手执行动作,带来新的状态。状态 越好,则这局游戏胜算越大。
第三 步——求值——算出了第 t + 1 步某一个状态的价值,记作 V () ;每一次 模拟都会得出这样一个价值,并且记录下来。模拟会重复很多次,于是第 t + 1 步每一种状态下面可以有多条记 录;如图 18.8 所示。
第 t 步的动作 at 下面有多个可能的状态(子节点),每个状态下面有若干条记录。把 a t 下面所有的记录取平均,记作价值 Q( a t),它可以反映出动作 a t 的好坏。在图 18.8 中, a t 下面一共有 12 条记录, Q( a t) 是 12 条记录的均值。
为什么要依据 N ( a ) 来做决策呢?在每一次模拟中,MCTS 找出所有可行的动作{a}, 计算它们的分数 score( a ) ,然后选择其中分数最高的动作,然后在模拟器里执行。如果某 个动作 a 在模拟中胜率很大,那么它的价值 Q ( a ) 就会很大,它的分数 score( a ) 会很高,于是它被选中的几率就大。也就是说如果某个动作 a 很好,它被选中的次数 N ( a ) 就会 大。
当观测到棋盘上当前状态 st,MCTS 做成千上万次模拟,记录每个动作 a 被选中的次数 N(a),最终做出决策 at = argmaxa N(a)。
到了下一时刻,状态变成了。MCTS 把所有动作 a 的 Q(a)、N(a) 全都初始化为零,然后从头开始做模拟,而不能利用上一次的结果。
【个人推测,是很难有和St中模拟的一模一样state的了,因为哪怕你当前棋谱是一样的,过去几个片段的棋谱也不可能一样】
AlphaGo 下棋非常“暴力”:每走一步棋之前,它先在“脑海里”模拟几千、几万局, 它可以预知它每一种动作带来的后果,对手最有可能做出的反应都在 AlphaGo 的算计之内。
!!AlphaGo 没有使用MCTS!!
一开始的时候,策略网络的参数都是随机初始化的。假如此时直接让两个策略网络自我博弈,它们会做出纯随机的动作。它们得随机摸索很多很多次,才能做出合理的动作。假如一上来就用 REINFORCE 学习策略网络,最初随机摸索的过 程要花很久。
AlphaGo 用行为克隆训练策略网络 π(a|s; θ)模仿学习笔记:行为克隆_UQI-LIUWJ的博客-CSDN博客_行为克隆
是策略网络的输出
设是对动作 的 One-Hot 编码。
函数是交叉熵,衡量和fk的差别。
这可以想象成分类问题,用梯度下降实现
- AlphaGo 让策略网络 做自我博弈,用胜负作为奖励,更新策略网络。
- 博弈的双方是两个策略网络,一个叫做 “玩家”,用最新的参数,记作 θnow;
- 另一个叫做“对手”,它的参数是从过时的参数中随机选出来的,记作 θold。
- “对手”的作用相当于模拟器(环境)的状态转移函数,只是陪玩。
- 训练的过程中,只更新“玩家”的参数,不更新“对手”的参数。
让“玩家”和“对手”博弈,将一局游戏进行到底,假设走了 n 步。游戏没结束的时候,奖励全都是零:游戏结束的时候,如果“玩家”赢了,奖励是 = +1 ,于是所有的回报都是 +1:
回顾一下REINFORCE的参数更新公式
价值网络 v(s; w) 是对状态价值函数的近似,用于评估状态 s 的好坏。
在完成第二步——训练策略网络 π——之后,用 π 辅助训练 v。
虽然 此处有一个策略网络 π 和一个价值网络 v,但这不属于 Actor-Critic 方法:此处先训练 π,再训练 v,用 π 辅助训练 v;而 Actor-Critic 则是同时训练 π 和 v,用 v 辅助训练 π。
让训练好的策略网络做自我博弈,记录状态—回报二元组,存到一个数组里。自我博弈需要重复非常多次,把最终得到的数据集记作而 价值网络 v(s; w) 是对状态价值函数的近似,所以我们希望用v(s;w)来拟合uk
于是我们定义回归问题
这也可以用梯度下降实现
把 MCTS 的决策作为目标,让 π 去模仿。这是行为克隆,被模仿的对象是MCTS。
尽量接近pt,也就是希望交叉熵尽量小