【Unity】三目ならべのディープラーニング(ML-Agents v0.8.1)
三目ならべ
三目ならべをやってみました。ちなみに英語では「Ticktacktoe」と呼ぶようです。
Unity2018.4.4
Ml-Agentsv0.8.1
で取り組みしました。
ご存じだと思いますが、ルールは先に3×3のマス目に同じマークが3つ並べば勝ちとなるルールです。
ゲーム的には先手有利ですが、必ず引き分けにすることができるためそのあたりをちゃんと学習するのか?後手の学習上手にできれば成功だと思います。
構成のイメージ
構成ですが、1つのBrainに2つのAgentを利用しました。〇担当するAgentと×担当するAgentです。1戦毎に先行後攻を入れ替えていきます。
Brainに与える情報について
ブレインに与えた情報は以下の通り、詳しくはコメントを読んでください。
//Stateの取得
public override void CollectObservations()
{
//Agentの担当を与えています。〇=0 ×=1
if (manager.player_O == PLAYER.AI_O)
{
AddVectorObs(0);
}
else
{
AddVectorObs(1);
}
//ターン数 0~8
AddVectorObs(manager.turn);
//前のターンで相手が出した答え 1~9
AddVectorObs(manager.anser);
//現在のCELLの値
for (int i = 0; i < 9; i++)
{
int cellValue = -1;
if (manager.cell[i] >= CELL.none)
{
cellValue = (manager.cell[i] == (CELL)agentId) ? 1 : 0;
}
AddVectorObs(cellValue);
}
//入力済みのセルは誤入力できないようにMASKをかけた。
if (maskActions)
{
SetMask();
}
}
private void SetMask()
{
//MASKをセットする
for (int i = 0; i < 9; i++)
{
if (agentId == (manager.turn + (int)manager.playMode) % 2)
{
//MASKをセット
if (manager.cell[i] != CELL.none)
{
SetActionMask(i + 1);
}
}
else
{
//ALLマスク(このコードは無意味ですよ)
SetActionMask(i + 1);
}
}
}
上記でのポイントは、2つ。マスク処理で無駄な学習時間させてないこと。前のターンでの答えを教えること。
2つ目は意外に重要です。効率が革新的に上がりました。
Agent動作について
最終的にAgentは交互に動作するようにしました。同時に動くようにしたりしましたが制御が難しくて断念しました。
交互に動作させるためには、OnDemandDecisionsをONにします。そのうえで、呼びたいAgentにRequestDecision()を使います。FixedUpdate() から下記を呼びます。
//AIの処理
private void WaitTimeInference()
{
//
if (!academy.GetIsInference())
{
//学習中
//Debug.Log("CALL Agent GetIsInference =" + academy.GetIsInference());
agent[(turn + (int)playMode) % 2].RequestDecision();
}
else
{
//対戦モード timeBetweenDecisionsAtInference まで待機
if (timeSinceDecision >= timeBetweenDecisionsAtInference)
{
//Debug.Log("CALL Time TimeSinceDecision =" + (turn + (int)playMode) % 2 );
timeSinceDecision = 0f;
agent[(turn + (int)playMode) % 2].RequestDecision();
}
else
{
timeSinceDecision += Time.fixedDeltaTime;
}
}
}
academy.GetIsInference()は機械学習中trueになりますので、対戦PLAYと機械学習で切り分けに使います。
報酬について
引き分けの数字を+0.8にしています。勝ち+1.0 負け-1.0です。
引分けを0.5~0.8 先手後手で数字を変えたりしましたが、あまり変わらないです。
学習結果について
5万STEP学習程度では、まだまだバカです。先行の場合は負けないですが、後攻ではあっさり負けます。
10万STEP学習させた結果、まぁまぁ強くなりました。しかし、まだ100%引き分けに持ち込ませることは無理です。先手では負けないですが勝てません。後手も、負けが少なくなりましたが、まったく勝利を取るような手配はできませんww
30万STEP学習させてもどうなのかなぁと思っています。
トレーニング設定ファイル
今回はProximal Policy Optimization(PPO)と呼ばれる強化学習手法を使用しています。Ml-Agentは、模倣学習用のBehavioral Cloning (BC)も可能です。
PPOとは、ニューラルネットワークを使用して、観察結果を考慮してエージェントが常に最善の行動をするように学習していく方法です。ML-AgentsのPPOアルゴリズムはTensorFlowに実装されており、独立したPythonプロセス(ソケットを介して実行中のUnityアプリケーションと通信する)で実行されます。
最善の行動をした場合に、きちんと学習していくためには、トレーニング設定ファイルを設定する必要があります。
しかしながら、どこをどのようにすれば強くなるのか? 現状はまったくわかりません。
現在は、下記のようにしています。
default:
trainer: ppo
batch_size: 1024
beta: 5.0e-3
buffer_size: 10240
epsilon: 0.2
gamma: 0.99
hidden_units: 128
lambd: 0.95
learning_rate: 3.0e-4
max_steps: 5.0e4
memory_size: 256
normalize: false
num_epoch: 3
num_layers: 2
time_horizon: 64
sequence_length: 64
summary_freq: 1000
use_recurrent: false
use_curiosity: false
curiosity_strength: 0.01
curiosity_enc_size: 128
TictactoeLearningBrain:
batch_size: 512
normalize: false
num_layers: 1
hidden_units: 128
beta: 1.0e-3
gamma: 0.9
buffer_size: 10240
max_steps: 10.0e5
summary_freq: 1000
time_horizon: 64
もっと強くなるためには・・・よくわからないんだよなぁ。
最後に
このまま、30万STEP~50万STEPと学習させても学ぶべきことが少ないような気がします。
なので次のゲームにチャレンジしようと思います。
今回の結果は、ストア買ったアセットを使っているため、Qiitaに上げられないのですが、興味のある方は、連絡いただければ個人的に送ります。アセット利用しないようにするのが面倒w