Я пытался внедрить 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]]