LoginSignup
11
9

More than 5 years have passed since last update.

ボルツマン選択の実装

Last updated at Posted at 2015-04-05

はじめに

ブロック崩しを攻略する人工知能を作成しています(前回の記事)。

前回のコードでは,バーがの動きがランダムに選択されるか,Q値が大きいものが選択されていました。この選択の欠点はQ値があまり変わらなくても,一番大きなQ値が採用される点です。具体的には,Q(s,0)=0.3800とQ(s,1)=0.3799であれば必ずQ(s,0)が採用されるということです。
この問題を解決するために,確率的に選択をするボルツマン選択を使ってみようと思います。
※独学で作ったので適切なコードでない可能性もある

ボルツマン選択

$A$:行動を要素とする集合
$T$:時間とともに0に収束する関数
状態$s$のときに行動$a$を行う確率$\pi(s,a)$を


\pi(s,a)=\frac{exp{(\frac{Q(s,a)}{T})}}{\displaystyle \sum_{b\in A}\exp{(\frac{Q(s,b)}{T})}}\\

と定める。
補足:$T$は温度をイメージした関数で,時間とともに0に収束するものを選ぶ。具体的には

T=\frac{1}{\log(t+1.1)}

など。

今回のコードに合わせたボルツマン選択

例えば状態sの時に0を選択する確率は,Q値がQ(s,0),Q(s,1),Q(s,2)の3パターンであることから

\pi(s,0)=\frac{exp{(\frac{Q(s,0)}{T})}}{\exp{(\frac{Q(s,0)}{T})}+\exp{(\frac{Q(s,1)}{T})}+\exp{(\frac{Q(s,2)}{T})}}\\

となる。

ボルツマン選択の性質

今回のコードに合わせて性質を見ていく。
$T$が十分大きいとき,すべての確率は均等に近くなる。
例えば$T\to \infty$のとき$\exp{(\frac{1}{T})}\to 1$ より

\pi(s,0)\to\frac{1}{1+1+1}=\frac{1}{3}

$T$が十分0に近いとき,Q値の大きい行動の確率が1に近くなり,他の確率は0に近くなる。
例えば $Q(s,0)=\frac{1}{2},Q(s,1)=\frac{1}{6},Q(s,2)=\frac{1}{3}$ のもとで, $T\to 0$のとき$exp(\frac{Q(s,a)}{T})$の増加するスピードがもっとも速いのは$Q(s,0)$なので

\pi(s,0)\to 1\\
\pi(s,1)\to 0\\
\pi(s,2)\to 0

となる。

javascriptコード

//ボルツマン選択
function Boltzmann(x,y,z,T){
    var myQ = [Q(x,y,z,0),Q(x,y,z,1),Q(x,y,z,2)];
    var prob = new Array(3);
    for(var i=0;i<3;i++){
        prob[i] = Math.exp(myQ[i]/T)/(Math.exp(myQ[0]/T) + Math.exp(myQ[1]/T) + Math.exp(myQ[2]/T));
    };
    var r = Math.random();

    if(r < prob[0]){
        return 0;
    }else if(r < prob[0]+prob[1]){
        return 1;
    }else{
        return 2;
    };
};

コードの説明

ボルツマン選択よりも,確率の実装がややこしかったので,確率の実装


    var r = Math.random();

    if(r < prob[0]){
        return 0;
    }else if(r < prob[0]+prob[1]){
        return 1;
    }else{
        return 2;
    };

について説明します。
例えばボルツマン選択によって定められた確率がそれぞれ


prob = [1/2,1/6,1/3]

なら


    var r = Math.random();

    if(r < 1/2){
        return 0;
    }else if(r< 4/6 ){
        return 1;
    }else{
        return 2;
    };

となります。このとき0から1までを,1/2 : 1/6 : 1/3 に分けて,ランダムに選択した0≤r≤1がどこに入るかで確率を実装しています。

結果

うまくいかない。
2回ほどボールを拾うのみです。

課題

なかなか学習しない。

原因

Q値が変化しにくいからだと思います。Q-learningの性質上,同じような状況でボールを何回も拾えば,拾う数回前の行動のQ値まで評価されていきます。一方,今回のように同じような状況でボールを拾える回数が少ない場合は,ボールを拾ったその行動のQ値のみ大きく評価され,他のQ値はあまり変わりません(推測)。

解決策

Q値の評価を過去にも反映させる方法を実装してみようと思います。具体的な話は実装してから書きます。

参考資料

Q学習wiki

最後に

実装方法は手探りなので,根本から間違っているかもしれません。
アイデアやアドバイスがある人は教えて下さい。

11
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
9