人工知能でなにかする

人工知能によるゲームの学習、データ解析などを行っていきます。

【テトリスをAIに学習させてみた】 解説編

投稿日:

はじめに

前回の記事で、ニューラルネットワーク遺伝的アルゴリズムでテトリスをAIに学習させてみた動画をご紹介しましたが、実際どのように作ったかの詳細をご説明したいと思います。

 

環境条件

OS Windows10
CPU Core i5
メモリ 8GB
開発言語 C#
開発環境 Visual Studio 2017 Community

 

概要

テトリスを遺伝的アルゴリズムニューラルネットワークを使用して学習させます。
まず、ニューラルネットワークはAIがテトリスプレイする上で、盤面情報を評価値に変換する評価関数として使用します。
そして遺伝的アルゴリズムはニューラルネットワークの構成遺伝子データとして扱い、評価と世代交代を繰り返してより高いスコアを出せる個体(ニューラルネットワークの構成)を探索します。

 

AIがブロックを置く場所の判断

1.現在の盤面の情報から、現在とその次のブロックから考慮できる全パターンの盤面情報を生成します。

2.生成された各盤面の情報を、評価関数(ニューラルネットワーク)によって評価値に変換していきます。

3.その中で一番高い評価値の盤面を採用し、同じ盤面になるように現在のブロックを配置させます。

 

もっと先のブロックまで考慮することで、より安定して高いスコアを出せるようになりますが、すべてのパターンを計算させると相当な計算量が必要となりますので、今回は一つ先のブロックまで考慮する形としました。

 

ニューラルネットワークによる評価関数の構成

盤面情報を評価値に変換する評価関数に、ニューラルネットワーク(以下NN)を使用します。

NNの構成は以下です。

形式 3層パーセプトロン
入力層のノード数(バイアス含む) 11
中間層のノード数(バイアス含む) 6
出力層のノード数 1
中間層の活性化関数 RELU
出力層の活性化関数 なし(値をそのまま出力)

3層パーセプロトロンの形式で、入力層のノードを10個、中間層を5個、出力層を1個としています。
実際にはバイアスのノードも含めるので、11−6−1という構成になります。
活性化関数に関しては中間層でRELUを使用し、出力層は中間層からの値をそのまま出力するようにしています。

 

盤面情報

NNの入力層に入力する盤面情報は全部で10個としています。
基本的には参考文献の論文と同じようにしていますが、2つほど入力情報を追加しています。

1.直前に置いたピースの高さ
2.消えたラインの数×ピースの中で消えたブロックの数
3.横方向にスキャンした時にセルの内容が変化する回数
4.縦方向にスキャンした時にセルの内容が変化する回数
5.穴の数
6.井戸の高さの階和の和
7.穴の上のブロックの数の和
8.穴のある行数
9.各列の高さの平均値
10.各列の高さの標準偏差

 

遺伝的アルゴリズムによるNN(評価関数)の最適化

NNは基本的にバックプロパゲーションによる教師あり学習が多いですが、今回教師データはありません。
そのため今回は遺伝的アルゴリズムによる教師なし学習を採用しました。
NNの教師なし学習の方法も色々とありますが、実装が楽でそれなりな結果が出るため、遺伝的アルゴリズムを選択しました。

遺伝的アルゴリズムの構成は以下です。

世代数 100
個体数 100
遺伝子数 61 (NNの重みの総数)
遺伝子データ NNの重み(実数)
個体選択 上位一体をエリート選択し、残りはルーレット選択
交叉方法 BLX-α (ブレンド交叉)
突然変異  なし ※BLX-αでは特に必要ないらしい

シミュレートにやたらと時間が掛かるため、世代数、個体数に関しては少なめに設定しています。
遺伝子データに関してはNNの重みとしていますが、重みは実数なためBLX-α交叉を使用しています。

 

学習時のシミュレート条件

遺伝的アルゴリズムによる学習のシミュレートの条件は以下です。

1.スコアの加算は消したラインの2乗とし、ゲームオーバーになるまでのスコアを計算

2.適応度は4回ゲームを行ったときの平均スコア

3.4回のゲームは固定乱数を使用(始めに4種のシード値を設定し、世代毎に変更しない)
解説:

各世代ごとに毎回違うパターンでシミュレートを行うのではなく、毎回同じ4つのパターンでシミュレートを行います。
事前の検証で固定乱数で学習させてから、他の乱数でシミュレートを行ってみましたが、固定乱数の場合のスコアより少し低いぐらいで
十分な性能が確認でいたため、固定乱数による学習を行いました。
各世代で毎回異なるパターンのシミュレートを行う場合は、回数を多くすればより正確に個体の適応度を計算できますが、
CPUの性能不足及びコーディングの技術不足により20回、30回のゲームの平均値を計算すると相当な時間を必要とするため
今回はこのような条件で適応度を計算しています。

4.Z型ブロック、S型ブロックの出現頻度を3倍
解説:

シミュレート時間の短縮のためこのような条件を設定しています。
参考論文によるとZ型、S型のブロックを多く出現させた場合のスコアと、通常時の場合のスコアには強い正の相関があります。
そのため、最適化の質を落とさずシミュレートの短縮が行えるとのことで、この条件を採用しています。

 

学習結果

学習結果のグラフは以下です。

最大適応度:その世代で一番適応度が高かった個体の適応度です。
平均適応度:その世代の適応度の平均値です、

固定乱数によるシミュレート&エリート選択を採用しているため、最大適応度は下がらずに成長するような結果となっています。
ただこのやり方だと、最初の方に最もよかった個体の遺伝子データを中心に成長してくため、局所解には落ちやすいです。

最終世代の通常時のゲームの平均スコアは1000万ライン以上は確認できましたが、ずっと終わりそうにないため途中で断念しました。
ちなみに5世代で70万ライン程度だったので、学習時と通常時の適応度でちゃんと正の相関になっているようです。(その辺をちゃんとグラフで結果を見せるようにしないと意味ないだろと言われそうですが)

 

参考文献

参考論文:
宮崎 真奈実, 荒川 正幹, “ニューラルネットワークと遺伝的ア ルゴリズムを用いたテトリスコントローラの開発”, 情報処理 学会第74 回全国大会, 539–540 (2012).

参考ソース(テトリスのロジック、描画処理など):
テトリスを c# と WPF で作ってみた

-未分類

Copyright© 人工知能でなにかする , 2017 AllRights Reserved Powered by AFFINGER4.