概要
方策勾配法は、強化学習(行動の結果として得た得点だけを手がかりに、得点が高くなる行動のしかたを学ぶ機械学習)の方法の1つで、打った手の確率を、その対局の結果が平均より良ければ上げ、悪ければ下げることをくり返して、良い結果になる打ち方を覚える。このページは、「なるべく負ける」オセロ AI を方策勾配法で学習させるときに何をどの式で学習しているかと、同じ学習を手元の RTX 3070 Ti と Colab の A100 で、それぞれ動かせた最大の同時に進める対局数で走らせた速さを示す。学習プログラムの全文は GPU のページにある。
読む順路:問題の設定で何を学習するかを決め、ゲームの機械学習の方法で選択肢を挙げる。記号から学習の手順までが方策勾配法の式、学習中に見る量が損失などの見方とグラフ、ほかの方法との比較が選択肢の式と比較、結果と速さの比較が実測である。
問題の設定
この節では、AI が何を目指し、誰と対局するかを決める。
- 相手:合法手(その局面で打てる手)の中から等確率で1つ選んで打つ。この相手を以下「ランダムな相手」と呼ぶ。
- AI の色:対局ごとに、黒(先手)か白(後手)かを等確率で決める。
- 目的:終局時に、AI の石の数が相手の石の数より少ないこと(AI の負け)。
- パス:打てる手が無い側はパスし、両者が続けてパスしたら終局とする。
ゲームの機械学習の方法
この節では、ゲームを打つ AI を学習させる方法の選択肢を挙げ、このページで使う方法を決める。どの方法も、対局をくり返して集めた結果から、局面ごとの打ち方を決める数(パラメータ)を直していく。違いは、何を学習するかと、どうやって手を選ぶかにある。
| 方法 | 学習するもの | 手の選び方 |
|---|---|---|
| 方策勾配法 | 局面ごとに、各合法手を選ぶ確率 | 学習した確率に従って選ぶ |
| 見込みに基づく方法(Q 学習など) | 局面と手の組ごとに、その手を打った後に得られる得点の見込み | 見込みが最大の手を選ぶ |
| 探索と組み合わせる方法(AlphaZero の方式) | 手を選ぶ確率と、局面の得点の見込みの両方 | 学習した確率と見込みを使って先を読み、その結果で選ぶ |
このページでは方策勾配法を使う。理由は2つある。1手を選ぶ計算がネットワーク1回で済み、先読みが無いので、全対局を GPU で同時に1手ずつ進められる。また、学習するのが確率だけなので、必要な式が記号から更新までの節で閉じる。ほかの2つの式と比較は、方策勾配法の式を定義した後のほかの方法との比較に置く。
記号
この節では、以降の節で共通に使う記号をまとめて定義する。1つの節や例の中だけで使う記号は、その場で定義する。
| 記号 | 意味 |
|---|---|
| 局面。AI から見た向きの盤面で、64 マスそれぞれが「AI の石」「相手の石」「空き」のどれか | |
| 局面 で手番側が打てるマス(合法手)の集合。マスは 0〜63 の番号で表す | |
| ネットワーク(式(2) で定義する関数)のパラメータ(重みとバイアスをすべて並べたもの)。学習で直す対象 | |
| 自然対数と、その逆の指数関数 | |
| で決まる実数 を、 の各成分で偏微分(ほかの成分を定数とみなして微分)した値を並べたベクトル(勾配)。偏微分は で書く | |
| 局面 をネットワークに入れる形に直した 192 個の 0 か 1(式(1)) | |
| 局面 を入れたときにネットワーク(式(2))が出す 64 個の実数。マス の値を と書く | |
| 局面 で AI がマス に打つ確率(方策)。青で書く | |
| 1局分の記録(AI の色、両者が打った手、パスの全部) | |
| 対局 が起きる確率と、そのうち によらない部分(AI の色と相手の手の確率の積)(式(6)・式(7)) | |
| 1局の中で AI が石を打った回数。パスは数えない | |
| AI が 回目()に石を打った局面と、打ったマス | |
| 対局 の得点。橙で書く | |
| 得点の期待値。学習で大きくしたい量 | |
| 1回の更新に使う対局の数。全対局を GPU で同時に進めるので「同時に進める対局数」でもある | |
| 対局の番号()。対局 の記録を 、AI が打った回数を と書く | |
| 対局 で AI が 回目に石を打った局面と、打ったマス | |
| ベースライン(得点から引く値)。緑で書く | |
| 学習率(1回の更新でパラメータを動かす幅を決める正の数) |
方策
この節では、局面からマスごとの確率 を作る計算を定義する。
ネットワークへの入力は、局面 を 192 個の 0 か 1 に直したもの である。マス について、AI の石なら 1、相手の石なら 1、合法手なら 1 になる 3 つの値を、64 マス分並べる。 は中の条件が成り立てば 1、成り立たなければ 0 を表す。
ネットワークは3層の全結合である。 は 、 は 、 は の行列、 は長さ 256・256・64 のベクトルで、 はこれら全部である。 をベクトルの成分ごとに当てる。行列をかけて足し、ReLU を当てることを2回くり返し、最後にもう一度行列をかけて足す。
パラメータの数は、3つの行列の成分の数と3つのベクトルの長さの和である。
確率は、合法手のマスだけで の指数をとり、合計が 1 になるよう割って作る(ソフトマックス)。合法手でないマスの確率は 0 とする。
式(4) の分母は合法手全部の和なので、 のとき で、合法手の確率の和は 1 になる。
目的
この節では、学習で大きくしたい量 を定義する。
得点は、AI が負ければ 1、引き分けなら 0、勝てば −1 とする。
対局 が起きる確率を と書く。対局は、AI の色・AI の手・相手の手で決まり、打った手から次の局面は一意に決まる。AI の色と相手の手の確率は によらない。相手が石を打った回数を 、相手が 回目()に石を打った局面を とする。AI の色はどちらも確率 、相手の 回目の手は確率 ( はその局面の合法手の数)なので、その積を次のように定義する。
すると は、式(6) の と AI の手の確率 式(4) の積になる。
目的は得点の期待値で、起こりうる対局すべての和で書ける(1手ごとに盤上の石が1個増えて空きマスは 60 個なので石を打つのは高々 60 回、パスは2回続くと終局するので1局の長さは有限で、各手番の選択肢も有限なので、対局の種類も有限)。
は「負けた割合 − 勝った割合」に等しい。式(5) の得点は負けで 1、勝ちで −1、引き分けで 0 なので、式(8) の和は、負ける対局の確率の和から勝つ対局の確率の和を引いたものになるからである。
方策勾配
この節では、 を大きくする向き(勾配 )が、対局をして得た量の平均で書けることを示す。
式(8) を で微分し、式(7) を使うと、次の式になる(証明は下の折りたたみ)。 は、対局 が確率 で起きるときの平均を表す。
式(9) の平均の中身(得点と、打った手の確率の対数の勾配)は、 によらない部分 (AI の色と相手の手の確率)を含まない。平均は、実際に対局して記録をとれば求められる。相手がどう打つかを知らなくても、対局をして得点と自分の手を記録すれば勾配を求められる。 は、 をその向きに少し動かすと、打った手 の確率が上がる向きである。式(9) は、負けた対局(得点 1)では打った手の確率を上げ、勝った対局(得点 −1)では下げる向きを、全対局で平均したものになっている。
詳しくはこちら(式(9) の証明)
証明では、式(7) で が によらないこと、式(4) で合法手の確率が正であること、対局の種類が有限であることを使う。 は 式(2) の ReLU のため、ReLU に入る値がちょうど 0 になる では微分できない。以下の微分は、そうでない で成り立つ(PyTorch は 0 での ReLU の微分を 0 として計算する)。
式(4) より合法手の確率は正なので、式(7) で の対局は になる。起こりうる対局の集合は によらない。この集合の上で、式(8) の和と微分を入れかえる(有限和なので入れかえてよい)。
なので、対数の微分(合成関数の微分)から次の式が成り立つ。
式(11) を 式(10) に入れると、和は平均の形になる。
式(7) の対数をとると、積が和になる。
ベースライン
この節では、得点から定数 を引いても 式(9) の平均が変わらないことと、引くと推定のばらつきが減る例を示す。
式(9) の を、対局によらない定数 を引いた に置きかえても、平均は同じになる(証明は下の折りたたみ)。
以下では を「有利さ」と呼ぶ。
平均が同じでも、1局から計算する値のばらつきは で変わる。次の例で、引かないと値がばらつき、得点の期待値を引くとばらつきが減ることを示す(この例では 0 になる)。
例。手を1回だけ選ぶ問題を考える。合法手は2つで、ここでは手 A・手 B と呼ぶ(後の数値例のマス A・B・C とは別のもの)。A を選ぶと必ず負け(得点 1)、B を選ぶと必ず引き分け(得点 0)になるとする。出力は1つの実数 で、A の確率を 、B の確率を とする(式(4) で A の出力を 、B の出力を 0 としたもの)。いまは で、両方の確率が 0.5 とする。
の定義を合成関数の微分で微分すると、次のようになる。
式(16) を使うと、選んだ手の確率の対数の微分は次のとおり。
では なので、式(17) は A なら 0.5、B なら −0.5 である。1局から計算する値「有利さ × この微分」は次のとおり。
| 選んだ手 | 確率 | 得点 | 引かない場合(ベースライン 0) | ベースライン 0.5 の場合 |
|---|---|---|---|---|
| A | 0.5 | 1 | 1 × 0.5 = 0.5 | 0.5 × 0.5 = 0.25 |
| B | 0.5 | 0 | 0 × (−0.5) = 0 | (−0.5) × (−0.5) = 0.25 |
この例の得点の期待値は 式(8) と同じ考え方で次の になり、その微分は で 0.25 である。
表のどちらの列も、確率 0.5 ずつで平均すると 0.25 で、式(18) に等しい。ベースラインの 0.5 は、この例の得点の期待値 である。分散(平均からのずれの2乗の平均)は次のとおり。
この例で引かない場合は、B を選んだ対局から何も学ばず、A を選んだ対局だけで確率を動かすので、1局ごとの値がばらつく。
実装では、 を、同じ更新に使う 局の得点の平均にした( は和をとるための対局の番号)。
対局の集まりからの推定
この節では、式(14) の平均を 局の対局で置きかえた、実際に計算する量を示す。
式(14) の期待値を 局の平均に置きかえ、 に 式(20) を使ったものを、勾配の推定値 と定義する。
式(20) の は対局 自身の得点を含むので、式(14) の「対局によらない定数」という条件を満たさない。それでも、 なら の平均( 局すべての打ち方についての平均。以下、添字の無い はこの意味)は を正の数 倍したもので、向きは変わらない(証明は下の折りたたみ)。
なら (小数第6位を四捨五入)である。
詳しくはこちら(式(22) の証明)
局 は、同じ で互いに独立に打たれる。対局 の打った手の確率を上げる向きを と書く。式(20) の和から の項を分けると、有利さは次のように書ける。
式(23) に をかけて平均をとる。
の項は、 と が独立なので に分かれる。式(15) で とした式から なので、この項は 0。残る第1項は、式(9) より 。どの でも同じ値なので、式(21) で について平均しても で、式(22) になる。
実装では、次の量 を PyTorch の自動微分で微分し、その勾配の逆向きに進めている。 は、式(21) の和を ではなく AI の手の総数 で割り、符号を反転したものである。 と は微分しない定数として扱う。
式(25) を微分する。微分は和の各項に分けられ、各項の ・ と は によらないので係数として の外に出せる。式(21) の を使うと次のようになる。
式(26) の係数 は対局の集まりごとに変わる正の数なので、1回ごとの更新で と の向きは同じである。ただし、この係数は得点と無関係ではない(手数の多い対局と少ない対局で得点の傾向が違えば、係数と が相関する)ので、式(22) の「平均が の正の数倍」という性質は、 の平均についてはそのままは言えない。この差を実験で確かめてはいない。
1手の確率の勾配
この節では、式(21) の中の が、ネットワークの出力 についてどんな形になるかを示し、数値例で確率の動き方を確かめる。
式(4) の対数を で偏微分すると、次の式になる(証明は下の折りたたみ)。 は なら 1、それ以外は 0。
式(27) から、有利さが正の対局では、打ったマス の出力 を に比例して上げ、ほかの合法手の出力を、それぞれの確率に比例して下げる向きになる。有利さが負なら逆になる。 についての勾配は、式(27) に、式(2) の各層を順にさかのぼって微分をかけていく連鎖律(誤差逆伝播)で計算する。実装では PyTorch が自動でこの計算をする。
詳しくはこちら(式(27) の証明)
式(4) の対数をとる。 のとき、
式(28) の第1項を で偏微分すると 。第2項は、 なら合成関数の微分で で、式(4) よりこれは に等しい。 なら第2項の和に が入らないので 0 で、第1項も より なので 0。
数値例。合法手が3つ(マス A・B・C)で、出力が 、AI が B に打ったとする。式(4) から確率を、式(27) から B を打ったときの偏微分を計算すると、次の表になる(小数第5位を四捨五入)。
| マス | 出力 | 確率 | 偏微分 |
|---|---|---|---|
| A | 1.0 | 0.6652 | −0.6652 |
| B(打った手) | 0.0 | 0.2447 | 0.7553 |
| C | −1.0 | 0.0900 | −0.0900 |
説明のため、出力そのものをパラメータとみなし、ベースラインを仮に 0.2 と置いて、出力に「1 × 有利さ × 偏微分」を足して更新した後の確率を比べる。
| 対局の結果 | 有利さ(得点 − 0.2) | 更新後の出力(A, B, C) | 更新後の B の確率 |
|---|---|---|---|
| 負けた(得点 1) | 0.8 | (0.4678, 0.6042, −1.0720) | 0.4855 |
| 勝った(得点 −1) | −1.2 | (1.7983, −0.9063, −0.8920) | 0.0590 |
(小数第5位を四捨五入)
負けた対局では B の確率が 0.2447 から 0.4855 に上がり、勝った対局では 0.0590 に下がる。
更新
この節では、式(25) の勾配を使ってパラメータを直す方法を示す。
最も単純な更新は、 の勾配の逆向きに、学習率 をかけた分だけ進めることである( は右辺の値で置きかえることを表す)。
実装では 式(29) の代わりに Adam を使い、学習率は にした。Adam は勾配の移動平均を使って、パラメータの成分ごとに進む幅を調整する。
詳しくはこちら(Adam の式)
回目の更新での勾配を とする。成分ごとに次を計算する(2乗・割り算・平方根も成分ごと)。PyTorch の既定値 、、 を使い、 から始める。
は勾配の移動平均、 は勾配の2乗の移動平均である。式(31) の と は、0 から始めたことで最初の数回の が小さく出るのを補正する。
学習の手順
この節では、実装が計算している 式(1)・式(4)・式(5)・式(20)・式(25)・式(30)・式(31) を、どの順に計算しているかを示す。1回の更新は次の4段階で、決めた秒数(15秒)が過ぎるまでくり返す。
- 対局: 局を GPU で同時に最後まで進める。AI の手は 式(4) の確率で乱数を使って選び、相手の手はランダムに選ぶ。AI が打った局面の入力 (式(1))、合法手、打ったマス を記録する。
- 得点:終局した盤面から 式(5) の得点 を、式(20) でベースライン を求める。
- 勾配:記録した全局面をまとめてネットワークに入れ、式(25) の を計算して、PyTorch の自動微分で を求める。
- 更新:Adam(式(30)・式(31))でパラメータを直す。
学習後の評価では、乱数を使わず、各局面で確率 が最大のマスに打たせる。
学習中に見る量
この節では、学習で最小化している損失が何で、学習が進んでいるかを何で判断するかを示す。最小化しているのは 式(25) の損失 だが、その値の符号や大きさからは、負けた割合も方策の偏りも決まらない。 は、式(26) のとおり勾配の向きを作るための量で、値が何で決まるかは 損失の値の意味 で式から示す。進み具合は、負けた割合などの別の量で判断する。
記録する量
この節では、更新のたびに記録する4つの量を定義する。
1つ目は、ランダムな相手に負けた割合である。学習中の対局(AI が確率に従って乱数で手を選ぶ)の値と、評価の対局の値の2つを記録する。評価の対局は、学習とは別に、確率が最大の手だけを打たせてランダムな相手と 4,096 局打たせたもの。学習後に使う打ち方(確率が最大の手)の強さはこちらで見る。4,096 局で数えるので、負けた割合が 94% 前後なら、乱数によるばらつき(標準誤差 )は約 0.4 ポイントある。
2つ目は、損失 (式(25))の値である。
3つ目は、方策のエントロピーである。局面 での方策のエントロピー を次のように定義する。対数は自然対数なので、単位をナットと呼ぶ。
式(32) は、合法手を等確率で選ぶときに最大値 をとる。下限は 0 で、1つの手の確率を 1 に近づけると 0 に近づく(証明は下の折りたたみ)。記録するのは、学習中の対局で AI が石を打った全局面についての の平均と、比べるための の平均である。
詳しくはこちら(式(32) の最大値と下限)
を と書き、合法手の確率を (式(4) よりどれも正で、和は 1)と書く。 は上に凸な関数なので、確率 の重みで平均をとると、平均の のほうが の平均より大きいか等しい(イェンセンの不等式)。
式(33) の等号は がすべて等しいとき、つまり のときに成り立つ。下限は、 より各項 なので 。1つの手の確率を 1 に近づけると、その項は に、ほかの項は ()に近づくので、 は 0 に近づく。
4つ目は、勾配の大きさ である。 の全成分の2乗の和の平方根(ユークリッドノルム)で、Adam に渡す前の値を記録する。
損失の値の意味
この節では、式(25) の の値が、得点と「その対局の手の確率の対数の和」の共分散で決まることを示し、その値が何によって変わるかを示す。
対局 で AI が打った手の確率の対数の和を 、その平均を 、AI の手の数の平均を と書く。
式(25) を 式(34) の記号で書き直すと、次のようになる(証明は下の折りたたみ)。
式(35) の は、手の選ばれやすさだけでなく、AI が打った手の数と、各局面の合法手の数にもよる。合法手を等確率で選ぶ方策なら なので、 になる。各項 は 0 以下なので、手の数が多い対局ほど小さく(負に大きく)なりやすい。
そのため、方策がまったく偏っていなくても は 0 にならない。下の表の相関係数は、 局の2つの量 について次で定義する( は平均)。
ネットワークの出力をすべて 0 にした方策(式(4) から合法手を等確率で選ぶ)で 局を2回打たせると、次のとおりだった。
| 回 | 損失の値 | AI が負けた対局の平均の手数 | AI が勝った対局の平均の手数 | 得点と手数の相関係数 | 得点と手の確率の対数の和の相関係数 |
|---|---|---|---|---|---|
| 1 | −0.0189 | 29.75 | 30.21 | −0.323 | 0.142 |
| 2 | −0.0198 | 29.73 | 30.22 | −0.298 | 0.145 |
負けた対局のほうが AI の手数が少なく、得点と の相関係数は正(0.142・0.145)だった。式(35) から、共分散が正なら は負になる。 の符号や大きさから、方策がどちらへ偏っているかは読めない。
学習が進んだときの の変化は、式(35) の共分散を 式(38) で標準偏差と相関係数に分けると読める。 と書くと、式(38) より共分散は に等しいので、
( は の並び、 は の並び)。得点の標準偏差は、負けた割合を 、勝った割合を とすると、得点が なので 、平均が で、 になる。記録した各因子は次のとおり(小数第4位を四捨五入)。
| 方策の更新の回数 | 損失の値 | 得点の標準偏差 | 手の確率の対数の和の標準偏差 | 2つの相関係数 | AI の手の数の平均 |
|---|---|---|---|---|---|
| 0 | −0.0153 | 0.982 | 4.227 | 0.110 | 29.963 |
| 72 | −0.0005 | 0.296 | 3.962 | 0.012 | 29.543 |
が縮んだのは、得点の標準偏差が約3分の1になったこと(負けがほぼ毎回になったため)と、相関係数が約9分の1になったことによる。手の確率の対数の和の標準偏差と手の数の平均はほとんど変わっていない。相関係数が小さくなった理由は確かめていない。得点の標準偏差は負けた割合が 1 に近づくと 0 に近づくので、この記録では は学習の進みと同じ向きに縮んだ。ただし学習前でも は 0 でないので(等確率の方策の表)、値から負けた割合は決まらない。
を 式(25) から計算した値と 式(35) から計算した値の差は、記録した全 73 回で 以下だった。
記録した値
この節では、手元の RTX 3070 Ti で のまま 73 回更新し(速さの比較の15秒の学習と同じ回数)、4つの量を毎回記録した結果を示す。この記録のための実行は、更新ごとに評価の対局も打つので乱数の使われ方が変わり、図1 の実行とは同じ回数でも値が一致しない。学習にかかった時間は測っていない。
図と表の横軸「方策の更新の回数」は、その値を出した方策が何回更新されたかを表す。学習中の対局の負けた割合・損失・エントロピー・勾配の大きさは、その回数だけ更新した方策で打った対局から計算し、その後に次の更新をした。評価の対局は、その回数目の更新の直後に打った。学習の進み方の表の「更新の回数 10」は、この数え方では 9 にあたる(10 回目の更新に使った対局は 9 回更新した方策で打った)。
図2 学習中に記録した量。横軸はどれも方策の更新の回数。(a) 損失 の値。2 回更新した方策で最小になった後 0 に近づき、19 回以降は −0.0024〜0.0017 の範囲にある(54 点のうち負が 38 点、正が 16 点)。(b) ランダムな相手に負けた割合。紫の実線は学習中の対局、黒の破線は評価の対局。黒の破線は 2 回の更新で 89% まで上がり、紫の実線は 20 回前後でそれに追いつく。(c) 紫の実線は方策のエントロピー の平均、灰色の破線はその上限 の平均。紫の線が上限から離れていくのは、方策が特定の手に偏っていくことを表す。(d) 勾配の大きさ。0.012〜0.032 の間にあり、0 に落ちていない。
主な値を表にする。負けた割合は小数第2位、そのほかは小数第5位を四捨五入した。
| 方策の更新の回数 | 学習中の対局で負けた割合 | 評価の対局で負けた割合 | 損失の値 | エントロピーの平均 | 上限(合法手の数の対数の平均) | 勾配の大きさ |
|---|---|---|---|---|---|---|
| 0(学習前) | 48.9% | 35.0% | −0.0153 | 1.9987 | 2.0004 | 0.0137 |
| 1 | 50.5% | 77.0% | −0.0205 | 1.9928 | 1.9950 | 0.0139 |
| 2 | 53.6% | 89.3% | −0.0230 | 1.9899 | 1.9939 | 0.0162 |
| 8 | 78.5% | 93.5% | −0.0183 | 1.8826 | 1.9767 | 0.0257 |
| 24 | 95.9% | 96.8% | −0.0004 | 1.0840 | 2.0035 | 0.0171 |
| 72 | 97.2% | 97.5% | −0.0005 | 0.5963 | 2.0266 | 0.0188 |
表から読めることは次のとおり。
- 負けた割合:1 回更新した方策は、評価の対局では 77.0% 負けたが、学習中の対局では 50.5% だった。このときエントロピーの平均 1.9928 は上限 1.9950 とほぼ同じで、確率はまだほぼ等確率だった。推測では、評価では確率が最大の手だけを打つので、確率の差がわずかでも順位が入れかわれば結果が変わる。学習中の対局は確率に従って選ぶので、確率が少し偏っただけでは結果が変わりにくい(実際、48.9%・50.5%・53.6% と少しずつ上がっている)。
- エントロピー:1.9987 から 0.5963 に下がった。エントロピーの平均を指数に直すと (四捨五入)で、上限の平均を指数に直すと である(合法手の数の平均は 8.88)。上限はほぼ変わらないので、合法手の数が減ったのではなく、方策が特定の手に偏った。
- 損失:最小は 2 回更新した方策の −0.0230 で、19 回以降は −0.0024〜0.0017 の範囲(絶対値の平均 0.0007)にある。損失の値の意味 のとおり、縮んだのは主に得点の標準偏差と相関係数が小さくなったためである。
- 勾配の大きさ:0.0121〜0.0315 の範囲で、最大は 7 回更新した方策だった。
まとめると、この学習で進み具合の判断に使う量と、見ることは次のとおり。
| 量 | 見ること |
|---|---|
| 評価の対局で負けた割合 | 目的(負けること)がどれだけ達成できているか。約 0.4 ポイントのばらつきより大きく上がっていれば学習が進んでいる |
| 学習中の対局で負けた割合 | 評価の値に追いついたか。追いつけば、確率に従って選んでも同じ結果になるほど方策が偏った |
| エントロピーの平均 | 上限から離れていくか、0 に張りつかないか。0 に近いと、確率が最大でない手はほとんど打たれない。式(21) の推定値は実際に打った手の項だけの和なので、打たれない手の確率を直す材料が入らなくなる |
| 勾配の大きさ | 0 に落ちていないか。全対局が同じ結果なら 式(20) で有利さがすべて 0 になり、式(26) の勾配も 0 になって、学習の材料が無くなる。Adam は 式(31) で勾配をその大きさの移動平均で割るので、大きさの数値そのものは1回に進む幅を決めない |
| 損失の値 | 最小化している量だが、式(39) のとおり負けた割合以外の因子でも変わるので、値では進み具合を判断しない |
ほかの方法との比較
この節では、ゲームの機械学習の方法で挙げたほかの2つの方法を式で定義し、方策勾配法と比べる。どちらも、このページの実験では使っていない。
Q 学習
この節では、Q 学習の学習対象と更新の目標を式で定義する。
Q 学習は、局面 でマス に打ち、その後は見込みが最大の手を打ち続けたときの得点の期待値を、見込み として学習する( はこの節で使う別のネットワークのパラメータ)。 には 式(2) と同じ形のネットワークの出力 を使ってよい。手は見込みが最大の合法手 を選ぶ(学習中は乱数で別の手も試す)。
ここでは、問題の設定と同じく相手が決まった確率で打つ(ランダムな相手)とし、相手の手を盤面の変化の一部とみなす。AI が局面 で に打った後、相手の手(とパス)を挟んで、次に AI が石を打てる局面を とする。見込みの目標 を次のように定義する。
式(40) の2行目は、次の手番で最も良い手を打ったときの見込みを、いまの手の見込みの目標にすることを表す。 は、次の2乗誤差を小さくする向きに更新する( は微分しない定数として扱う)。
は相手の手と、その後の局面によって変わる乱数である。定数 との2乗誤差の平均は と分けられ( を2乗して平均すると、交差項の平均は で消える)、 で最小になるので、各 の見込みを互いに独立に選べると仮定し、 の中の を固定して考えると、式(41) を多くの対局で小さくすることで は相手の手について平均した に近づく。実際のネットワークは全局面でパラメータを共有し、更新すると も変わるので、この仮定は近似である。相手を盤面の変化の一部とみなせるのは、相手の打ち方の確率が学習中に変わらないからである。AI 自身と対局させる場合(自己対戦)は相手も学習で変わるので、式(40) はそのままでは使えない。
AlphaZero の方式
この節では、AlphaZero の方式の学習対象と損失を式で定義する。
AlphaZero の方式は、AI 自身どうしの対局(自己対戦)で棋譜を集める。この点で、ランダムな相手と対局する問題の設定とは違う。ネットワーク(パラメータ )が手の確率 と局面の得点の見込み の2つを出す。手を選ぶときは、 と を使って先の局面を探索し(モンテカルロ木探索)、各手を調べた回数の割合を とする。手は に従って選ぶ。この節の方式では、対局の結果を、記録した各局面 の手番側から見た値 (手番側が目指す結果になれば 1、引き分けなら 0、逆なら −1)で表す。この AI が負けを目指すなら、手番側が負けた局面で である。 はパラメータを小さく保つための正の数とする( は の成分の2乗の和)。 は、対局が終わった後、記録した各局面 について次の損失を小さくする向きに更新する。
式(42) の第1項は見込みを実際の得点に近づけ、第2項は を探索で決めた割合 に近づける。
比較
この節では、3つの方法を、学習する関数・更新の目標・手の選び方・1回の対局で必要な計算で比べる。
| 方法 | 学習する関数 | 更新の目標 | 手の選び方 | 1回の対局で必要な計算 |
|---|---|---|---|---|
| 方策勾配法 | 手の確率(式(4)) | 対局の得点と打った手(式(21)、実装は 式(25)) | 確率に従う | 各手番でネットワークを1回 |
| Q 学習 | 局面と手の得点の見込み | 次の局面の見込みの最大値(式(40)) | 見込みが最大の手 | 各手番でネットワークを1回 |
| AlphaZero の方式 | 手の確率 と局面の得点の見込み (式(42)) | 探索で決めた割合と対局の得点(式(42)) | 探索の結果 | 各手番で探索した局面の数だけネットワーク |
結果
この節では、学習の前後で AI の打ち方がどう変わったかを示す。
次の表は、学習の前後で、乱数を使わない AI(学習の手順の評価のしかた)を各相手と 8,192 局打たせた結果である。「貪欲な相手」は、返せる石が最も多い手を打つ相手(同じ数の手が複数あれば乱数で選ぶ)。値は GPU のページの A100 の実行(、15秒)のもの。
| 相手 | 学習前に負けた割合 | 学習後に負けた割合 | 学習後に勝った割合 |
|---|---|---|---|
| ランダムな相手 | 34.9% | 98.4% | 1.0% |
| 貪欲な相手 | 50.5% | 99.2% | 0.6% |
学習後の AI は、終局時の自分の石を減らす打ち方を覚えた。手元の RTX 3070 Ti で ・15秒学習させた実行(図1の灰色の破線と同じ実行)で、ランダムな相手との 8,192 局の終局時の石の数を平均すると、次のようになった(小数第2位を四捨五入)。
| 時点 | AI の石の数 | 相手の石の数 |
|---|---|---|
| 学習前 | 34.7 | 29.3 |
| 学習後 | 18.5 | 45.5 |
速さの比較
この節では、同じプログラムを手元の RTX 3070 Ti と Colab の A100 で15秒ずつ走らせ、処理の速さと学習の進み方を比べる。プログラム・学習時間(15秒)・学習率は同じで、 が違う。そのほか、CPU(手元は Core i9-11900K、A100 の VM は Xeon 2.20GHz)と PyTorch の版(手元は 2.10.0、A100 は 2.11.0)も違う。A100 は1回だけ走らせた(Colab の計算ユニットを節約するため)。どの設定も乱数の種は同じ1つで、種を変えたくり返しはしていない。
1秒あたりの対局数
この節では、機種と ごとの処理の速さを比べる。次の表は、 ごとの更新の回数、1回の更新にかかった秒数、1秒あたりの対局数である。学習時間は「15秒を過ぎたら止める」ので実際には 15.17〜15.22秒だった。1回の更新の秒数は実際の時間を更新の回数で割り、1秒あたりの対局数は対局の総数を実際の時間で割った。値は GPU のページと同じ実行のもの。
| 機種 | 同時に進める対局数 | 更新の回数 | 1回の更新にかかった秒数 | 1秒あたりの対局数 |
|---|---|---|---|---|
| RTX 3070 Ti | 4,096 | 73 | 0.208 | 19,706 |
| RTX 3070 Ti | 8,192 | 41 | 0.370 | 22,135 |
| RTX 3070 Ti | 16,384 | メモリ不足で停止 | ― | ― |
| A100 40GB | 16,384 | 37 | 0.411 | 39,839 |
A100()は、1秒あたりの対局数が手元の最大( の 22,135)の 1.8倍だった。これは ・CPU・PyTorch の版も違う条件を1回ずつ測った比で、機種だけの差ではない。手元は を 4,096 から 8,192 に倍にしても1秒あたりの対局数が 12% しか増えなかった。1回の更新の秒数 が の1次式だと仮定する( は によらない固定分、 は1局あたりの時間)。
手元の2点( で 0.208秒、 で 0.370秒)を 式(43) に入れて解くと、 秒、 秒(四捨五入)になる。式(43) が成り立つとして手元で を動かせたとすると約 0.69秒で、A100 の 0.411秒の 1.7倍になる(2点からの外挿による推測)。
このプログラムは torch.autocast(混合精度)も torch.set_float32_matmul_precision(行列積に TF32 を使う設定)も呼んでいないので、全結合層の行列積は FP32 のまま計算される(PyTorch の既定、GPU のページ)。そのため、GPU のページの行列積の 6倍は当てはまらない。FP32 のままの行列積の実測の差は 1.2倍で、1.8倍はこれより大きい。どの処理が時間を決めているかは測っておらず、1.8倍の理由は分からない。
学習の進み方
この節では、学習中の対局で負けた割合が、秒数と更新の回数に対してどう上がったかを比べる。
図1 は、学習中の対局(AI が確率に従って乱数で手を選ぶ)で負けた割合を、横軸を秒数(左)と対局数(右)にして描いたもの。手元の2本は1回の更新ごと、A100 は10回の更新ごとに記録した。手元の2本は、上の表とは別の実行で記録した(1秒あたりの対局数の差は 1% 以内)。曲線が約 50% から始まり、結果の学習前(34.9%)と違うのは、図1 は確率に従って乱数で手を選んだ値、結果の表は確率が最大の手を選んだ値だからである。
図1 学習中の対局で負けた割合。紫の実線は RTX 3070 Ti で 、灰色の破線は RTX 3070 Ti で 、黒い四角は A100 で 。左は横軸が学習開始からの秒数、右は学習に使った対局数(万局)。左で紫の線が最も早く上がる。右で3つを同じ対局数で比べられるのは 16.4万局の点だけで、そこでは紫が最も高く、黒い四角が最も低い。
同じ更新の回数で比べると、10回と20回では が大きいほど負けた割合が高いが、30回では順序が崩れる。差は最大で 3.7 ポイント(10回)である。
| 更新の回数 | RTX 3070 Ti、4,096 局 | RTX 3070 Ti、8,192 局 | A100、16,384 局 |
|---|---|---|---|
| 10 | 83.0% | 85.4% | 86.7% |
| 20 | 95.5% | 96.4% | 96.6% |
| 30 | 97.4% | 97.2% | 97.8% |
(学習中の対局で負けた割合。小数第2位を四捨五入。「10」の行は 10 回目の更新に使った対局、つまり 9 回更新した後の方策で打った対局の値(20・30 も同じ))
同じ秒数で比べると、1秒あたりの更新の回数が多い手元の が最も進んでいた。4秒前後の時点では次のとおり。
| 機種と同時に進める対局数 | 記録した時点 | その時点までの更新の回数 | 学習中の対局で負けた割合 |
|---|---|---|---|
| RTX 3070 Ti、4,096 | 4.2秒 | 20 | 95.5% |
| RTX 3070 Ti、8,192 | 4.1秒 | 11 | 88.7% |
| A100、16,384 | 4.1秒 | 10 | 86.7% |
2つの表から、この実験の範囲では、同じ秒数での差(最大 8.8 ポイント)に比べて、同じ更新の回数での差(最大 3.7 ポイント)は小さかった。10回・20回では が大きいほど高いが、乱数の種を変えたくり返しをしていないので、 の効果か乱数によるばらつきかは分からない。更新の回数でおおよそそろう理由は確かめていない。推測では、式(25) は AI の手の総数で割った平均なので を大きくしても勾配の大きさは増えず、Adam(式(31))は勾配の大きさで割って進む幅をそろえるので、1回の更新で進む量は にあまりよらない。 で走らせた A100 は、1秒あたりの対局数は 1.8倍だったが、1秒あたりの更新の回数が手元の の約半分だったので、同じ秒数での学習は手元より遅れた。12秒以降は、手元の2本が 97.3〜98.3%、A100 が 12.3秒の時点で 97.8% だった。
確認できていない点
この節では、このページの実験で確かめていないことを挙げる。
- A100 で ・ にしたときの速さと学習の進み方。A100 は の1回しか走らせていない。
- 1.8倍の内訳(盤面の判定とネットワークの計算のどちらに時間がかかっているか)。
- A100 で に合わせて学習率を上げた場合に、学習が速くなるか。
- 乱数の種を変えたときの結果のばらつき。どの設定も1回ずつしか走らせていない。