Мне трудно заставить агента Deep Q-Learning найти оптимальную политику. Вот как моя текущая модель выглядит в TensorFlow:
model = Sequential()
model.add(Dense(units=32, activation="relu", input_dim=self.env.state.size)),
model.add(Dense(units=self.env.allActionsKeys.size, activation="softmax"))
model.compile(loss="mse", optimizer=Adam(lr=0.00075), metrics=['accuracy'])
Для задачи, над которой я сейчас работаю, 'self.env.state.size' равно 6, а количество возможных действий ('self.env.allActionsKeys.size') равно 30.
Входной вектор состоит из битов, каждый из которых имеет разные диапазоны (хотя в этой задаче они не слишком отличаются). Диапазон 2 битов равен [0,3], для остальных 2 [0,2] и для оставшихся [0,1]. Пожалуйста, обратите внимание, что это должна быть простая задача, я также стремлюсь к более сложным, где размер ввода будет, например, 15, а диапазоны могут отличаться немного больше, чем это ([0,15], [0 ,3],...).
Вот как выглядит мой метод поезда:
def train(self, terminal_state):
if len(self.replay_memory) < MIN_REPLAY_MEMORY_SIZE:
return
# Get MINIBATCH_SIZE random samples from replay_memory
minibatch = random.sample(self.replay_memory, MINIBATCH_SIZE)
# Transition: (current_state, action, reward, normalized_next_state, next_state, done)
current_states = np.array([transition[0] for transition in minibatch])
current_qs_minibatch = self.model.predict(current_states, batch_size=MINIBATCH_SIZE, use_multiprocessing=True)
next_states = np.array([transition[3] for transition in minibatch])
next_qs_minibatch = self.model.predict(next_states, batch_size=MINIBATCH_SIZE, use_multiprocessing=True)
env_get_legal_actions = self.env.get_legal_actions
np_max = np.max
X = []
y = []
for index, (current_state, action, reward, normalized_next_state, next_state, done) in enumerate(minibatch):
if not done:
legalActionsIds = env_get_legal_actions(next_state)
max_next_q = np_max(next_qs_minibatch[index][legalActionsIds])
new_q = reward + DISCOUNT * max_next_q
else:
new_q = reward
current_qs = current_qs_minibatch[index].copy()
current_qs[action] = new_q
X.append(current_state)
y.append(current_qs)
self.model.fit(np.array(X), np.array(y), batch_size=MINIBATCH_SIZE, verbose=0, shuffle=False)
где СКИДКА = 0,99 и MINIBATCH_SIZE = 64.
Я читал, что рекомендуется нормализовать входной вектор, поэтому я протестировал 2 разных метода нормализации атрибутов: минимальная-максимальная норма. и норма z-оценки. И, поскольку диапазоны значений не сильно различаются, я также тестировал без нормализации. Ни один из этих методов не оказался лучше других.
Что происходит, так это то, что в начале, на этапе исследования, оценка со временем становится лучше, что означает, что модель чему-то учится, но затем, на этапе эксплуатации, когда значение эпсилон низкое и агент жадно выполняет большинство действий. , оценка резко снижается, что означает, что на самом деле он не узнал ничего хорошего.
Это мой алгоритм глубокого Q-обучения:
epsilon = 1
for episode in range(1, EPISODES+1):
episode_reward = 0
step = 0
done = False
current_state = env_reset()
while not done:
normalized_current_state = env_normalize(current_state)
if np_random_number() > epsilon: # Take legal action greedily
actionsQValues = agent_get_qs(normalized_current_state)
legalActionsIds = env_get_legal_actions(current_state)
# Make the argmax selection among the legal actions
action = legalActionsIds[np_argmax(actionsQValues[legalActionsIds])]
else: # Take random legal action
action = env_sample()
new_state, reward, done = env_step(action)
episode_reward += reward
agent_update_replay_memory((normalized_current_state, action, reward, env_normalize(new_state), new_state, done))
agent_train(done)
current_state = new_state
step += 1
# Decay epsilon
if epsilon > MIN_EPSILON:
epsilon *= EPSILON_DECAY
где ЭПИЗОДЫ = 4000 и EPSILON_DECAY = 0,9995.
Я поиграл со всеми этими гиперпараметрами, но результаты очень похожи. Я не знаю, что еще попробовать. Я что-то не так делаю с нормализацией? Есть ли какой-либо другой метод нормализации, который более рекомендуется? Может ли проблема быть в моей модели нейронной сети, которая недостаточно хороша?
Я думаю, что не должно быть так сложно заставить его работать для такой простой задачи, как эта, с размером входных данных 6, выходным слоем 30 узлов и скрытым слоем 32.
Обратите внимание, что для той же задачи я использовал другое представление состояния, используя двоичный массив размером 14, и он отлично работает с теми же гиперпараметрами. В чем может быть проблема, когда я использую это другое представление?