質問: こんにちは。 pythonを使ってマルバツゲームを学習させたのですが、学習がうまくいきません。 長くなるのでコードは載せませんが、自分がやった手法としては、 ・ニューラルネットワーククラスを作成する → ・重みの初期値を乱数を使って決める → ・9マスのボードゲームなので入力値をnumpyのreshapeを使って1行9列のベクトルに変換する → ・着手可能な手の内、もっとも評価の高い手を選択させる、ただし、10回に3回、着手可能な手のうち、ランダムで着手を選択させる → ・勝った方の各局面(自分が選択してきた全ての局面)に対して0.99、負けた方の各局面に対して0.01を出力させるように学習させる、引き分けの場合はそれぞれに対して0.5で学習させる ニューラルネットワークの構造としては、入力値が1行9列、中間ノード数が100、出力が1行1列で値が0~1の範囲になるように設定しています。 中間層、出力層に対してそれぞれシグモイド関数を適用しています。学習率は0.3です。 入力値は[0,1,0,2,1,0,0,0,0]のように、○が1,☓が2、置いてないところは0となるようにしています。 また、☓の局面の学習では、[-1.5*x**2+3.5*x for x in board.board]のように、リスト内包表記を使って1と2を交換させるように学習させています。 このシステムを使って、可能な局面数より遥かに多い300万対局をさせて学習させてみたのですが、学習後に自分と対局してみても、リーチに対して何も受けず、1000回くらい試しで学習させてみたときと変わらない強さでした。 試しに引き分けの場合は学習させず、とにかく勝ちに行くことを目的とさせる場合でも学習させてみたのですが、やはり変わりませんでした。 勝敗がついた場合の局面が勝った方からしたら一番価値が高い局面のはずなので、勝ちの局面を0.9999その2手前を0.999、4手前を0.99などにして学習させてみたのですが、やはり結果は変わりませんでした。 お互いが自身が勝つための最善を追求しているはずですから、対局を重ねれば重ねるほど強くなるはずだと思っていたのですが、そうでも有りませんでした。 また、仮に学習がうまくいったとして、これらは各局面に対して評価値を学習しているだけで、局面の特徴量を学んでいる、といえるでしょうか? 例えば、人間みたいに相手がリーチをかけているからそのマスを潰さなければいけない、というような学習が出来ていると言えるでしょうか? 自分のやり方の問題点などを挙げて頂けると嬉しいです。宜しくお願い申し上げます。
回答: マルバツゲーム(三目並べ)は、**両者最善手を取った場合に引き分けになる**ことが分かっている、二人零和有限確定完全情報ゲームです。 ※後手の1手目が最善手でない場合は後手の負け決定 問題はリーチに対する評価値が低くなりすぎているような気がします(というより、リーチを潰さない手の評価が高すぎる?)。リーチは無条件に潰さねばなりませんが、10回に3回は潰さない手を打つようになっているわけですから、それが影響しているとかはないでしょうか。 余談: コンピュータで三目並べ、ってのは遙か昔から(それこそパソコン以前から)あるもので、これを重要なギミックに使った映画まであるんですよね......1983年の映画ですから、見たことない人も多いでしょうけれども。(DVD/Blu-ray にはなってますが)