Таким образом, даже если значение трассы приемлемости не равно нулю для предыдущих состояний, значения дельты в приведенном выше случае будут равны нулю (поскольку изначально вознаграждение и функция полезности инициализируются 0). Тогда как предыдущие состояния могут получить значения других утилит, отличные от нуля, при первом обновлении?
Вы правы в том, что, в первом обновлении , все награды и обновления будут по-прежнему 0
(за исключением случаев, когда нам уже удастся достичь цели за один шаг, тогда награда не будет быть 0
).
Тем не менее, отслеживание соответствия e_t
будет продолжать «запоминать» или «запоминать» все состояния, которые мы ранее посетили. Таким образом, как только нам удастся достичь целевого состояния и получить ненулевое вознаграждение, следы соответствия будут помнить все состояния, через которые мы прошли. Эти состояния будут по-прежнему иметь ненулевые записи в таблице трасс приемлемости, и поэтому все сразу получат ненулевое обновление, как только вы заметите свое первое вознаграждение.
Таблица трасс приемлемости затухает каждый временной шаг (умноженный на gamma * lambda_
), поэтому величина обновлений состояний, которые были посещены давно, будет меньше, чем величина обновлений для утверждает, что мы посетили совсем недавно, но мы будем продолжать помнить все эти состояния, они будут иметь ненулевые записи (при условии, что gamma > 0
и lambda_ > 0
). Это позволяет обновлять значения всех посещенных состояний , не как только мы достигнем этих состояний , а , как только мы наблюдаем ненулевое вознаграждение (или в эпоху после первой эпохи, как только мы достигнем состояния, для которого у нас уже есть существующее ненулевое прогнозируемое значение) после посещения их в более ранний момент времени .
Также в данной реализации Python после одной итерации выдается следующий вывод:
[[ 0. 0.04595 0.1 0. ]
[ 0. 0. 0. 0. ]
[ 0. 0. 0. 0. ]]
Здесь обновляются только 2 значения вместо всех 5 предыдущих состояний, как показано на рисунке. Что мне здесь не хватает?
Первая часть их кода выглядит следующим образом:
for epoch in range(tot_epoch):
#Reset and return the first observation
observation = env.reset(exploring_starts=True)
Итак, каждую новую эпоху они начинают со сброса окружения с помощью флага exploring_starts
. Если мы посмотрим на реализацию их среды , мы увидим, что использование этого флага означает, что мы всегда начинаем с случайной начальной позиции .
Итак, я подозреваю, что когда код запускался для генерации этого вывода, начальная позиция была просто случайно выбрана, чтобы быть позицией в двух шагах слева от цели, а не позицией в левом нижнем углу. Если начальная позиция выбирается случайным образом так, чтобы она уже была ближе к цели, агент посещает только те два состояния, для которых вы видите ненулевые обновления, поэтому они также будут единственными состояниями с ненулевыми записями в таблице приемлемости. трассировки и, следовательно, будут единственными состояниями с ненулевыми обновлениями.
Если начальная позиция действительно является позицией в нижнем левом углу, правильная реализация алгоритма действительно обновит значения для всех состояний вдоль этого пути (при условии, что дополнительные трюки не добавляются, например, установка записей в * 1049). * если они оказываются "достаточно близкими" к 0
из-за разложения).
Я также хотел бы отметить, что на самом деле в коде на этой странице есть ошибка: они не сбрасывают все записи таблицы трасс приемлемости на 0
при сбросе среды / начале новой эпохи. , Это должно быть сделано. Если этого не сделать, трассы соответствия будут по-прежнему запоминать состояния, которые были посещены в предыдущие эпохи, а также обновлять все из них, даже если они не были посещены снова в новой эпохе. Это неверно Правильная версия их кода должна начинаться так:
for epoch in range(tot_epoch):
#Reset and return the first observation
observation = env.reset(exploring_starts=True)
trace_matrix = trace_matrix * 0.0 # IMPORTANT, added this
for step in range(1000):
...