背景
学校でC言語の授業があり、授業の最後に自由になにか作品を作って提出するとのことだったので、オセロAIを作ってついでに学習させてみることにしました。あくまで学校の授業の延長で、ガバガバなところは許してください。
オセロAIの概要
8×8マス全てに個々に重みを設定し、置ける場所で最も重いマスに石を置くという、至って単純なAIです。各マスの重みをNNで求めます。
NNの概要
入力層 64個 各マスに置かれている石のデータ
中間層 10個 2層
出力層 64個 各マスの重み
活性化関数、バイアスはよくわからなかったです。
GAの概要
NNは各ノードを繋ぐシナプスがあり、そこに重みが設定されていて、それを元に次のノードの値を計算します。今回はGAを使って重みを最適化します。交配方法は二点交叉を採用しました。理由は、なんとなくです。
GAの使い方
親データはExcelのランダム関数で適当に生成したのを二つ用意しました。
基本的にポイント制で、ポイントの降順で順位付けしています。
突然変異の確率、評価の方法、親の選定をいろいろ変えていました。
1 突然変異の確立 遺伝子の要素1つにつき 5 %
評価方法:勝ち + 1 負け + 0
次世代の親の選定 上位1~5位と20位からランダムに2体
2 突然変異の確立 3 %
評価方法:勝ち 30 + とった石 * 2 負け 0
次世代の親の選定 上位1~5位と20位からランダムに2体
3 突然変異の確立 0.5%
評価方法:勝ち 30 + とった石 ^ 2 負け 0
次世代の親の選定 上位1~5位と20位からランダムに2体
4 突然変異の確立 0.5%
評価方法:勝ち とった石 * 2 + 四隅一個当たり + 30 負け 0
次世代の親の選定 上位1~5位と20位からランダムに2体
5 突然変異の確立 0.3%
評価方法:勝ち とった石 * 2 + 四隅一個当たり + 30 負け 0
次世代の親の選定 確定で上位1、2位
親データとして2を6万世代学習させたデータと4を3万世代学習させたデータを使用
学習結果
対戦相手として固定のAIを用意したかったので、こちらのサイトを参考にしました。
上がオセロの盤面、下の数字がNNが求めた各マスの重みです。
方法1
学習世代:1000
弱い
角の重みが低いのに、角の周りは高くなっています。
こんなの強いはずがありません。
ただ右端の角は高くなっています。
方法2
学習世代:6万
あまり1と変わってない印象。
ちなみに先行の時は勝ったけど、後攻では負けた。
わりと運で勝ってる感はある。
方法3
学習世代:3万
相も変わらずといった感じ
石を取った分だけポイントが莫大になるから多く石取ってくれると思ったが、そんなことはなかった
というか自分はそんなにオセロの戦略とか詳しくないので、四隅しか見てません。
方法4
学習世代:3万
四隅を取ると多くポイントがもらえるようにしてみました。
が、うまくいかなかったです
方法5
学習世代:1万
基本ルールは変えず、親を既存のデータにして、突然変異の確率を下げました。
ですが、あんまり変わんない感じ。
結論
今回のやり方ではあまり強くなっている感じではなかったと思います。評価の方法を変えたり、既存のAIの手を教師として教師有り学習をさせたりすれば多少は強くなったかもしれません。
最後に
今回のソースコードをgithub gistに載せておきます。自由にダウンロード、改変、再配布などしてくれてOKです。再配布するときにTwitterとかで教えてくれると嬉しかったりします(面倒くさければしなくて大丈夫です)。
遺伝子データについて
.cppファイルと同じフォルダに.txtファイルで保存されています。
ファイル名はgeneticX-YYY.txtです。
Xは学習方法の種類です。
YYYは学習した世代数です。
parent1.txt、parent2.txtを作って最初の親としてください。