Внедрение SARSA в Unity

Поэтому я использовал следующий код для реализации Q-learning в Unity:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace QLearner
{
    public class QLearnerScript
    {
        List<float[]> QStates; // Q states over time
        List<float[]> QActions; // Q actions over time

        float[] initialState;
        int initialActionIndex;
        float[] outcomeState;
        float outcomeActionValue;
        bool firstIteration;

        int possibleActions;

        float learningRate; // denoted by alpha
        float discountFactor; // denoted by gamma

        float simInterval;


        System.Random r = new System.Random();

        public int main(float[] currentState, float reward)
        {
            QLearning(currentState, reward);

            // Applies a sim interval and rounds
            initialState = new float[2] {(float)Math.Round((double)currentState[0] / simInterval) * simInterval , (float)Math.Round((double)currentState[1] / simInterval) * simInterval};

            firstIteration = false;

            int actionIndex = r.Next(0, possibleActions);

            bool exists = false;
            if(QStates.Count > 0)
            {
                for(int i = 0; i < QStates.Count; i++)
                {
                    float[] state = QStates.ElementAt(i);
                    float[] actions = QActions.ElementAt(i);

                    if(state[0] ==  initialState[0] && state[1] ==  initialState[1])
                    {
                        exists = true;
                        initialActionIndex = Array.IndexOf(actions, MaxFloat(actions));

                        return initialActionIndex;
                    }
                }
            }

            if(!exists)
            {
                float[] actionVals = new float[possibleActions];
                for (int i = 0; i < possibleActions; i++)
                {
                    actionVals[i] = 0f;
                }
                QStates.Add( initialState);
                QActions.Add(actionVals);
            }

            initialActionIndex = actionIndex;
            return initialActionIndex;
        }

        public QLearnerScript(int possActs)
        {
            QStates = new List<float[]>();
            QActions = new List<float[]>();
            possibleActions = possActs;

            learningRate = .5f; // Between 0 and 1
            discountFactor = 1f;

            simInterval = 1f;

            firstIteration = true;
        }

        public void QLearning(float[] outcomeStateFeed, float reward)
        {
            if(!firstIteration)
            {
                outcomeState = new float[2] {(float)Math.Round((double)outcomeStateFeed[0] / simInterval) * simInterval , (float)Math.Round((double)outcomeStateFeed[1] / simInterval) * simInterval};

                bool exists = false;
                for(int i = 0; i < QStates.Count; i++)
                {
                    float[] state = QStates.ElementAt(i);
                    float[] actions = QActions.ElementAt(i);

                    if(state[0] == outcomeState[0] && state[1] == outcomeState[1])
                    {
                        exists = true;
                        outcomeActionValue = MaxFloat(actions);
                    }
                }

                for(int i = 0; i < QStates.Count; i++)
                {
                    float[] state = QStates.ElementAt(i);
                    float[] actions = QActions.ElementAt(i);

                    if(state[0] ==  initialState[0] && state[1] ==  initialState[1])
                    {

                        if(exists)
                        {
                            actions[initialActionIndex] += learningRate * (reward + discountFactor * outcomeActionValue - actions[initialActionIndex]);
                        }
                        if(!exists)
                        {
                            actions[initialActionIndex] += learningRate * (reward + discountFactor * 0f - actions[initialActionIndex]);
                        }
                    }
                }
            }
        }

        public int getQtableCount()
        {
            return QStates.Count;
        }

        float MaxFloat(float[] numbers)
        {
            float max = numbers[0];

            for (int i = 0; i < numbers.Length; i++)
                if (max < numbers[i])
                {
                    max = numbers[i];
                }

            return max;
        }
    }
}

Что отлично работает с моей средой. Однако я также пытаюсь реализовать SARSA, чтобы проверить два алгоритма друг против друга. Я знаю, что Q-обучение не соответствует политике, а SARSA соответствует политике, то есть я должен реализовать политику, чтобы получить следующее действие, а не просто вызывать

MaxFloat(actions)

Однако фактическая реализация этого меня смущает, как мне изменить свой сценарий, чтобы включить эту политику?


person user3631213    schedule 08.06.2018    source источник


Ответы (1)


В SARSA название алгоритма также является алгоритмом: вы сохраняете состояние, действие, вознаграждение и следующее состояние и действие, а затем используете эту информацию для выполнения обновления.

Вам нужно вычислить обновление в момент, когда у вас есть не только текущее состояние и награда за него, но и в момент, когда у вас есть предыдущее состояние, вознаграждение за предыдущее состояние и текущее состояние. SARSA будет использовать текущее состояние, а Q-Learning заменит его предсказанием жадной политики.

person Don Reba    schedule 08.06.2018
comment
Я (в некоторой степени) понимаю теорию, моя задача заключается в том, чтобы применить ее на практике (отсюда и мой вопрос). Моя логика подсказывает мне, что это должна быть небольшая модификация моего текущего кода, но я не вижу, как реализовать теорию. - person user3631213; 08.06.2018
comment
Вам нужно вычислить обновление в момент, когда у вас есть не только текущее состояние и награда за него, но и в момент, когда у вас есть предыдущее состояние, вознаграждение за предыдущее состояние и текущее состояние. Q-Learning отбросит информацию о текущем состоянии, SARSA будет использовать ее. - person Don Reba; 08.06.2018
comment
Q-Learning отбросит информацию о текущем состоянии, SARSA будет использовать ее. — если быть точнее, Q-Learning заменит текущее состояние предсказанием жадной политики. - person Don Reba; 08.06.2018