SARSA с линейным значением Func.Прибл.не сходится к правильным Q-факторам - PullRequest
0 голосов
/ 17 апреля 2019

Я пытался внедрить SARSA с LVFA. До сих пор я реализовал следующий код, но он, похоже, не работает (не сходится к правильным Q-факторам даже для самых простых проблем).

Любая помощь с тем, почему мой код не работает, будет принята с благодарностью! Спасибо!

Я реализовал следующее правило обновления TD (оно получено из стохастического градиентного спуска на TDBE из того, что я понимаю): https://i.ibb.co/Jyt5DFd/Capture.png

Я просто заменил правило обновления TD в Q на вышеприведенное, которое должно работать, поскольку SARSA с LVFA гарантированно сходится (в определенных пределах) к истинной фиксированной точке теоретически. Поэтому я предполагаю, что с моей реализацией что-то не так, но я пока не смог обнаружить никаких ошибок.

def SARSA_LVFA(theta, phi, r, s, gamma = 0.5, a = 0.005):
    """ SARSA algorithm with LVFA """
    limit = 10**5

    # choose action u from eps-greedy policy
    if np.random.random() < 0.9:
        u = np.argmax(np.matmul(phi(s).T, theta))
    else:
        u = np.random.choice(U)

    for i in range(limit):
        phi_s = phi(s)                            # get features for current state s
        s_ = np.random.choice(S, p = f(s, u))     # perform action u (noisy model)
        phi_s_ = phi(s_)                          # get features for new state s_

        # choose action u_ from eps-greedy policy
        if np.random.random() < 0.9:
            u_ = np.argmax(np.matmul(phi_s_.T, theta))
        else:
            u_ = np.random.choice(U)

        # caculate temporal difference delta
        td_target = r(s, u) + gamma*np.matmul(theta[:, u_].T, phi_s_)
        delta = td_target - np.matmul(theta[:, u].T, phi_s)

        # update feature weights
        theta[:, u] = theta[:, u] + a * delta * phi_s.T

        s = s_
        u = u_

    return theta

Некоторые примечания по коду:

  • U - это пространство действий, а S - это пространство состояний.
  • theta - это матрица весов формы len( phi ) x len( U ), где phi - вектор признаков (столбцов) для состояния s.
  • Вы получаете свою Q-матрицу, просто выполняя np.matmul(Phi.T, theta), где Phi - это просто набор всех ваших векторов признаков [phi(s1) | phi(s2) | … | phi(sN)].
  • Оставьте любые другие вопросы, которые могут у вас возникнуть в комментариях!

Давайте попробуем описанную выше функцию для задачи со следующей строкой игрушки. Для пространства состояний S = [0, 1, 2] (слева от строки, на строке и справа от строки соответственно) и пространства действия U = [0, 1, 2] (справа, в режиме ожидания и слева соответственно). Возьмите следующую функцию вознаграждения r, модель системы f и функцию функции phi:

def r(x, u):
    """ reward function """
    if x == S[1]:
        return 1.0
    else:
        return 0.0

def f(x, u):
    '''
    list with probabilities for each successor is returned.
    All states are valid successors, but they can receive zero probability.
    '''
    if x == S[1]:       # on line
        if u == U[2]:   # left
            result = [0.2, 0.7, 0.1]
        elif u == U[0]: # right
            result = [0.1, 0.7, 0.2]
        elif u == U[1]: # none
            result = [0.0, 1.0, 0.0]
    elif x == S[0]:     # left of line
        if u == U[2]:
            result = [1.0,0.0,0.0]
        elif u == U[0]:
            result = [0.0,1.0,0.0]
        elif u == U[1]:
            result = [1.0, 0.0, 0.0]
    elif x == S[2]:     # right of line
        if u == U[2]:
            result = [0.0,1.0,0.0]
        elif u == U[0]:
            result = [0.0,0.0,1.0]
        elif u == U[1]:
            result = [0.0, 0.0, 1.0]
    return result

def phi1(s):
    if s == S[1]:
        return 1.0
    else:
        return 0.0

def phi2(s):
    if s != S[1]:
        return 1.0
    else:
        return 0.0

def phi(x):
    """ get features for state x """
    features = np.asarray([[phi1(x), phi2(x)]]).T
    return features

Выполнение theta_optimal = SARSA_LVFA(theta, phi, r, some_start_state) дает неверную матрицу Q, что-то вроде:

[[0.27982704 0.13408623 0.28761029]
 [1.71499981 1.98207434 1.72503455]
 [0.27982704 0.13408623 0.28761029]]

и соответствующая неправильная политика [2 1 2] или иногда [0 1 0].

Я пробовал ту же игрушечную задачу на простом SARSA и Q-learning (без LVFA) и получил правильную политику [0 1 2] и Q-matrix:

[[0.98987301 0.46667215 0.4698729 ]
 [1.80929669 1.98819096 1.8406385 ]
 [0.47045638 0.47047932 0.99035824]]
...