web-dev-qa-db-ja.com

マルコフ決定プロセス:値の反復、どのように機能しますか?

私は Markov Decision Processes(値の反復を使用) について多くのことを読んできましたが、私は単にそれらを回避することができません。私はインターネット/書籍で多くのリソースを見つけましたが、それらはすべて私のコンピテンシーには複雑すぎる数式を使用しています。

これは大学での最初の1年であるため、ウェブで提供される説明や数式は、私にとってあまりにも複雑すぎる概念/用語を使用し、読者は私が聞いたことがない特定のことを知っていると仮定していることがわかりました。

2Dグリッドで使用したい(壁(手に入らない)、コイン(望ましい)、動く敵(これはどうしても避けなければならない)で満たされている)。全体の目標は、敵に触れることなくすべてのコインを収集することであり、マルコフ決定プロセス([〜#〜] mdp [〜#〜 ])。これは部分的にどのように見えるかです(ゲーム関連の側面はここではあまり気にしないことに注意してください。私は本当に理解したいだけですMDPs一般):

enter image description here

私が理解していることから、MDPsの無礼な簡略化は、彼らがどの方向に行く必要があるかを保持するグリッドを作成できるということです(グリッドの種類特定の目標に到達し、特定の障害を回避するために、グリッド上の特定の位置から開始する必要がある場所を指す「矢印」。私の状況に固有のことは、プレイヤーがコインを収集して敵を避けるためにどの方向に進むべきかを知ることができるということです。

ここで、[〜#〜] mdp [〜#〜]の用語を使用すると、状態のコレクション(グリッド)が作成されます。特定の状態(グリッド上の位置)に対して特定のポリシー(実行するアクション->上、下、右、左)を保持します。ポリシーは、各状態の「効用」値によって決定されます。これらの値自体は、短期的および長期的にどれだけ利益を得られるかを評価することによって計算されます。

これは正しいです?または、私は完全に間違った道を進んでいますか?

少なくとも、次の式の変数が私の状況で何を表しているのかを知りたいです。

U_{i+1}(s) \longleftarrow R(s) + \gamma \max \sum\limits_{s'} T(s,a,s') U_i (s') \,.

(Russell&Norvigの本「人工知能-現代のアプローチ」から引用)

sはグリッドのすべての正方形のリストであり、aは特定のアクション(上/下/右/左)であることを知っていますが、残りはどうでしょうか。

報酬およびユーティリティ機能はどのように実装されますか?

誰かが私の状況に似た基本的なバージョンを非常に遅い方法で実装するための擬似コードを示す簡単なリンクを知っていたら、本当に素晴らしいことです。

貴重な時間をありがとうございました。

(注:タグを追加/削除したり、そのような何かについてもっと詳しく説明したい場合はコメントで教えてください)

40
Jesse Emond

はい、数学的な表記により、実際よりもはるかに複雑に見える場合があります。本当に、それは非常に単純なアイデアです。 値の反復デモアプレット を実装しており、これを使用してより良いアイデアを得ることができます。

基本的に、ロボットが入った2Dグリッドがあるとしましょう。ロボットは北、南、東、西に移動しようとすることができます(これらはアクションaです)が、左車輪が滑りやすいため、北に移動しようとすると、正方形に到達する確率は0.9しかありませんそれの北で、それがそれの西の正方形で終わるという.1確率があります(他の3つのアクションのために同様に)。これらの確率は、T()関数によってキャプチャされます。つまり、T(s、A、s ')は次のようになります。

s    A      s'     T    //x=0,y=0 is at the top-left of the screen
x,y  North  x,y+1  .9   //we do move north
x,y  North  x-1,y  .1   //wheels slipped, so we move West
x,y  East   x+1,y  .9
x,y  East   x,y-1  .1
x,y  South  x,y+1  .9
x,y  South  x-1,y  .1 
x,y  West   x-1,y  .9
x,y  West   x,y+1  .1 

次に、報酬をすべての状態で0に設定しますが、目標状態、つまりロボットが到達したい場所では100に設定します。

値の反復が行うのは、目標状態に100のユーティリティを与え、他のすべての状態に0を与えることから始まります。その後、最初の反復で、この100個のユーティリティは目標から1ステップ分だけ後方に分配されるため、1ステップで目標状態に到達できるすべての状態(そのすぐ隣の4つの正方形すべて)に何らかのユーティリティが割り当てられます。つまり、その状態から目標に到達できる確率に等しい効用が得られます。その後、各ステップでユーティリティを目標からさらに1ステップ戻します。

上記の例では、R(5,5)= 100から始めて、他のすべての状態でR(.) = 0から始めます。したがって、目標は5,5に到達することです。

最初の反復で設定します

R(5,6) = gamma * (.9 * 100) + gamma * (.1 * 100)

5,6では、北に行くと.5で終わる可能性が0.9ありますが、西に行く場合は、5,5で終わる可能性が.1あります。

(5,4)、(4,5)、(6,5)についても同様です。

値の反復の最初の反復の後、他のすべての状態はU = 0のままです。

36
Jose M Vidal

実装にはQラーニングを使用することをお勧めします。

私が書いたこの投稿をインスピレーションとして使用できるかもしれません。これは Q-learning demo with Java source code 。このデモは6つのフィールドを持つマップであり、AIはすべての状態からどこに行くべきかを学習します報酬。

Qラーニングは、AIに報酬または罰を与えることにより、AIに自ら学習させる技術です。

この例は、パス検索に使用されるQラーニングを示しています。ロボットは、どの状態からどこに行くべきかを学習します。

ロボットはランダムな場所で開始し、スコアを記憶し続けながらエリアを探索し、目標に到達するたびに新しいランダムな開始で繰り返します。十分に繰り返した後、スコア値は固定されます(収束)。

この例では、アクションの結果は決定的であり(遷移確率は1)、アクションの選択はランダムです。スコア値は、Q学習アルゴリズムQ(s、a)によって計算されます。
画像には、州(A、B、C、D、E、F)、州からの可能な行動、与えられた報酬が表示されます。

q-learn1

結果Q *(s、a)
q-learn2

ポリシーΠ*(s)
q-learn3

Qlearning.Java

import Java.text.DecimalFormat;
import Java.util.Random;

/**
 * @author Kunuk Nykjaer
 */
public class Qlearning {
    final DecimalFormat df = new DecimalFormat("#.##");

    // path finding
    final double alpha = 0.1;
    final double gamma = 0.9;


// states A,B,C,D,E,F
// e.g. from A we can go to B or D
// from C we can only go to C
// C is goal state, reward 100 when B->C or F->C
//
// _______
// |A|B|C|
// |_____|
// |D|E|F|
// |_____|
//

    final int stateA = 0;
    final int stateB = 1;
    final int stateC = 2;
    final int stateD = 3;
    final int stateE = 4;
    final int stateF = 5;

    final int statesCount = 6;
    final int[] states = new int[]{stateA,stateB,stateC,stateD,stateE,stateF};

    // http://en.wikipedia.org/wiki/Q-learning
    // http://people.revoledu.com/kardi/tutorial/ReinforcementLearning/Q-Learning.htm

    // Q(s,a)= Q(s,a) + alpha * (R(s,a) + gamma * Max(next state, all actions) - Q(s,a))

    int[][] R = new int[statesCount][statesCount]; // reward lookup
    double[][] Q = new double[statesCount][statesCount]; // Q learning

    int[] actionsFromA = new int[] { stateB, stateD };
    int[] actionsFromB = new int[] { stateA, stateC, stateE };
    int[] actionsFromC = new int[] { stateC };
    int[] actionsFromD = new int[] { stateA, stateE };
    int[] actionsFromE = new int[] { stateB, stateD, stateF };
    int[] actionsFromF = new int[] { stateC, stateE };
    int[][] actions = new int[][] { actionsFromA, actionsFromB, actionsFromC,
            actionsFromD, actionsFromE, actionsFromF };

    String[] stateNames = new String[] { "A", "B", "C", "D", "E", "F" };

    public Qlearning() {
        init();
    }

    public void init() {       
        R[stateB][stateC] = 100; // from b to c
        R[stateF][stateC] = 100; // from f to c    
    }

    public static void main(String[] args) {
        long BEGIN = System.currentTimeMillis();

        Qlearning obj = new Qlearning();

        obj.run();
        obj.printResult();
        obj.showPolicy();

        long END = System.currentTimeMillis();
        System.out.println("Time: " + (END - BEGIN) / 1000.0 + " sec.");
    }

    void run() {
        /*
         1. Set parameter , and environment reward matrix R
         2. Initialize matrix Q as zero matrix
         3. For each episode: Select random initial state
            Do while not reach goal state o
                Select one among all possible actions for the current state o
                Using this possible action, consider to go to the next state o
                Get maximum Q value of this next state based on all possible actions o
                Compute o Set the next state as the current state
         */

        // For each episode
        Random Rand = new Random();
        for (int i = 0; i < 1000; i++) { // train episodes
            // Select random initial state
            int state = Rand.nextInt(statesCount);
            while (state != stateC) // goal state
            {
                // Select one among all possible actions for the current state
                int[] actionsFromState = actions[state];

                // Selection strategy is random in this example
                int index = Rand.nextInt(actionsFromState.length);
                int action = actionsFromState[index];

                // Action outcome is set to deterministic in this example
                // Transition probability is 1
                int nextState = action; // data structure

                // Using this possible action, consider to go to the next state
                double q = Q(state, action);
                double maxQ = maxQ(nextState);
                int r = R(state, action);

                double value = q + alpha * (r + gamma * maxQ - q);
                setQ(state, action, value);

                // Set the next state as the current state
                state = nextState;
            }
        }
    }

    double maxQ(int s) {
        int[] actionsFromState = actions[s];
        double maxValue = Double.MIN_VALUE;
        for (int i = 0; i < actionsFromState.length; i++) {
            int nextState = actionsFromState[i];
            double value = Q[s][nextState];

            if (value > maxValue)
                maxValue = value;
        }
        return maxValue;
    }

    // get policy from state
    int policy(int state) {
        int[] actionsFromState = actions[state];
        double maxValue = Double.MIN_VALUE;
        int policyGotoState = state; // default goto self if not found
        for (int i = 0; i < actionsFromState.length; i++) {
            int nextState = actionsFromState[i];
            double value = Q[state][nextState];

            if (value > maxValue) {
                maxValue = value;
                policyGotoState = nextState;
            }
        }
        return policyGotoState;
    }

    double Q(int s, int a) {
        return Q[s][a];
    }

    void setQ(int s, int a, double value) {
        Q[s][a] = value;
    }

    int R(int s, int a) {
        return R[s][a];
    }

    void printResult() {
        System.out.println("Print result");
        for (int i = 0; i < Q.length; i++) {
            System.out.print("out from " + stateNames[i] + ":  ");
            for (int j = 0; j < Q[i].length; j++) {
                System.out.print(df.format(Q[i][j]) + " ");
            }
            System.out.println();
        }
    }

    // policy is maxQ(states)
    void showPolicy() {
        System.out.println("\nshowPolicy");
        for (int i = 0; i < states.length; i++) {
            int from = states[i];
            int to =  policy(from);
            System.out.println("from "+stateNames[from]+" goto "+stateNames[to]);
        }          
    }
}

印刷結果

out from A:  0 90 0 72,9 0 0
out from B:  81 0 100 0 81 0
out from C:  0 0 0 0 0 0
out from D:  81 0 0 0 81 0
out from E:  0 90 0 72,9 0 90
out from F:  0 0 100 0 81 0

showPolicy
from a goto B
from b goto C
from c goto C
from d goto A
from e goto B
from f goto C
Time: 0.025 sec.
5
Kunukn

完全な答えではなく、明確な発言。

statenot単一セルです。状態には、関連するすべてのセルの各セルの内容が一度に含まれます。つまり、1つの状態要素には、どのセルが空で、どのセルが空であるかという情報が含まれます。どのモンスターが含まれています。コインはどこですか。プレーヤーはどこですか。

たぶん、各セルからそのコンテンツへのマップを状態として使用できます。これは、おそらく非常に重要なモンスターとプレイヤーの動きを無視します。

詳細は、問題のモデル化方法(状態に属するものと形式を決定する方法)によって異なります。

次に、ポリシーは各状態を左、右、ジャンプなどのアクションにマップします。

まず、値反復などのアルゴリズムがどのように機能するかを考える前に、MDPで表される問題を理解する必要があります。

4
ziggystar

私はこれがかなり古い投稿であることを知っていますが、MDP関連の質問を探しているときに見つけました、私はあなたが「s」と「a」が何であったかについてのいくつかのコメントに注意したいです。

私はあなたにとって絶対に正しいと思います。それはあなたの[上、下、左、右]のリストです。

ただし、sの場合は実際にグリッド内の場所であり、s 'は移動可能な場所です。つまり、状態を選択してから、特定のsを選択し、そのスプリームに移動できるすべてのアクションを実行して、それらの値を計算します。 (それらの最大値を選択します)。最後に、次のsに進み、同じことを行います。すべてのsの値を使い果たしたら、検索したばかりの最大値を見つけます。

隅のグリッドセルを選択した場合、移動できる状態は2つしかないとします(左下隅を想定)。状態の「名前付け」の選択方法に応じて、この場合は状態がx、y座標。したがって、現在の状態sは1,1であり、s '(またはsプライム)リストはx + 1、yおよびx、y + 1(この例では対角線なし)(行く合計部分すべてのs ')

また、あなたはそれをあなたの方程式にリストしていませんが、最大はaまたはあなたに最大を与えるアクションのものですので、最初にあなたがあなたに最大を与えるs 'を選び、その中であなたがアクションを選びます(少なくともこれはアルゴリズムの私の理解です)。

だからあなたが持っていた場合

x,y+1 left = 10 
x,y+1 right = 5 

x+1,y left = 3
x+1,y right 2

S 'としてx、y + 1を選択しますが、最大化されたアクションを選択する必要があります。この場合、x、y + 1に残ります。最大数を見つけることと、状態を見つけてから最大数を見つけることの間に微妙な違いがあるかどうかはわかりませんが、誰かがいつかそれを明らかにするかもしれません。

動きが決定的である場合(前進すると言う場合、100%の確実性で前進する場合)、1つのアクションを実行するのは非常に簡単ですが、それらが非決定的である場合、80%の確実性がある場合は、 could他のアクション。これは、ホセが前述した滑りやすいホイールのコンテキストです。

他の人が言ったことを損なうのではなく、追加情報を提供したいだけです。

2
onaclov2000