Edited at

ちょいワルQ-Networkの話

More than 3 years have passed since last update.

春の陽気が待ち遠しい今日この頃,皆様いかがお過ごしでしょうか.

はじめまして,休日Deep Learning勢の329と申します.


はじめに

DQNの生い立ち + Deep Q-NetworkをChainerで書いた

http://qiita.com/Ugo-Nama/items/08c6a5f6a571335972d5

東方ProjectをDeepLearningで攻略した…かった。

http://qiita.com/imenurok/items/c6aa868107091cfa509c

これらの記事に影響を受け,

「DQNってもっと面白いことできるんじゃないの」

「DQN,強化学習,Deep Learningに興味を持ってもらうためのライトな記事を書こう」

などと考え,この記事を書きました.


対象読者


  • DQNって聞いたことあるけど.詳しくは知らない(詳しく知るためのモチベが欲しい)

  • DQNの気分を味わい,知った気になりたい

以上のような方に読んで頂き,将来的に面白コンテンツが1つでも増えれば良いと思っています.

DQNの,よりDeeeepな解説は強い技術者・研究者の皆様にお願いしたいと思います.


攻略対象

この記事では,ニューラルネットワークを使って「後出しジャンケン」を攻略します.

相手が出した手を見た後に自分のジャンケンの手を決定し,勝利するDQNなAIを生み出します.


プログラムと解説

github

上記のプログラムは, 状態を入力すると,各行動の良さを出力することを目指して学習します.

後出しジャンケンで言うなら,「相手の手を見た時に,グー,チョキ,パーがそれぞれ何点くらいの価値がありそうかを計算する」ことに相当します.

勝利で1点,負けたら-1点,あいこでは0点が得られることにすると,相手の手を見た後の自分の手の価値は以下のようになります.

グーの価値
チョキの価値
パーの価値

相手がグー
0
-1
+1

相手がチョキ
+1
0
-1

相手がパー
-1
+1
0

# 後出しジャンケンゲームに関してはこの表があれば既に必勝ですね?

相手の手を入力した際に,対応する列を出力するモデルを学習により獲得します.

以下がニューラルネットワークに関する記述です.

class DqnModel(Chain):

def __init__(self,num_of_state,num_of_action):
self.num_of_state = num_of_state
self.num_of_action = num_of_action
super(DqnModel, self).__init__(
state=F.EmbedID(num_of_state, 32),
l2=L.Linear(32, 64),
l3=L.Linear(64, 64),
l4=L.Linear(64, 32),
q_action=L.Linear(32, self.num_of_action, initialW=np.zeros((self.num_of_action, 32), dtype=np.float32))
)

def __call__(self, state, target, train=True):
h = self.state(state)
h = self.l2(h)
h = self.l3(h)
h = self.l4(h)
h = self.q_action(h)
if train:
loss = F.mean_squared_error(h, target)
return loss
else:
return h

後出しジャンケンゲームでは状態が3つ,行動が3つ存在するので以下のように初期化します.

model = DqnModel(num_of_state=3,num_of_action=3)

ネットワークの出力が,教師信号に近付くように最適化問題を解きます.

以下の記述で,最適化手法を選択しています.いろいろあります.

optimizer = optimizers.Adam()

optimizer.setup(model)

以上で準備は完了です.あとはデータを用意して,

optimizer.zero_grads()

loss = model(state, target)
loss.backward()
optimizer.update()

とすると最適化問題を解いて,「後出しジャンケンゲーム」の関数近似による攻略を試みます.

githubからcloneたプログラムを実行すると,以下のような結果が得られると思います.

[[ 0.02005649 -0.00832902 -0.01909292]]

相手 : チョキ
あとだし : グー

やりました.

後出しジャンケンゲームを「ちょい悪 Q Network」で攻略することができました.


残された課題

私が書いたプログラムでも,「後出しジャンケン」のような小規模なゲームなら攻略することができます.

しかし,以下のような課題からこのプログラムを通常のゲームに用いることは難しそうです.

1.「状態に対する行動の良さ」の測定方法が不明である

2. 状態の番号付けが困難(TVゲームの画面状態って,いったいどのくらいあるの?)

上記の問題は.今回私がお見せしたプログラムが「なんちゃってDQN」だったことに由来しています.

つまり「本物のDQN」は,これらの問題を何らかの方法で解決しているということです.

どうです,気になってきましたか?


おわりに

読んで下さった方がもれなく「私気になります」となったなら私は小躍りでもしそうになるわけですが,

きっとそのようにはならないのだろうと予測しています.

ぜひとも不明な点や間違っている点などなどなどなど,コメントとして投稿して頂ければと思います.


Chainerはいいぞ