Почему мое глубокое Q-обучение забывает то, чему оно научилось? - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть агент глубокого обучения, который учится решать CartPole. Он выучит оптимальную политику, а затем периодически забудет ее. Я приложил изображение моей последней тренировки из 3000 эпизодов, чтобы продемонстрировать, что я имею в виду.

Вот скрипт, который я использовал, чтобы определить и обучить агента:

import gym
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
import matplotlib.pyplot as plt
from collections import deque
import pickle

epsilon_max = 1
epsilon_min = 0.01
exploration_decay = 0.995
learning_rate = 0.001
batch_size = 20
gamma = 0.95
max_memory = 200000


class DQN:

    def __init__(self, observation_space, action_space):
        self.exploration_rate = epsilon_max
        self.observation_space = observation_space

        self.action_space = action_space

        self.memory = deque(maxlen=max_memory)

        self.model = self.make_model()

    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))

    def act(self, state):
        self.exploration_rate *= exploration_decay
        self.exploration_rate = max(epsilon_min, self.exploration_rate)
        if np.random.uniform() < self.exploration_rate:
            return np.random.randint(0, self.action_space)
        q_values = self.model.predict(state)
        return np.argmax(q_values)

    def experience_replay(self):
        if len(self.memory) < batch_size:
            return
        indexes = np.random.choice([i for i in range(len(self.memory))], batch_size)
        batch = [self.memory[i] for i in indexes]
        for state, action, reward, state_next, terminal in batch:
            q_update = reward
            if not terminal:
                q_update = (reward + gamma * np.amax(self.model.predict(state_next)[0]))
            q_values = self.model.predict(state)
            q_values[0][action] = q_update
            self.model.fit(state, q_values, verbose=0)

    def make_model(self):
        model = Sequential()
        model.add(Dense(24, input_shape=(self.observation_space,), activation='relu'))
        model.add(Dense(24, activation='relu'))
        model.add(Dense(self.action_space, activation='linear'))
        model.compile(loss='mse', optimizer=Adam(lr=learning_rate))
        return model


def reward_giver(reward, terminal, steps):
    if terminal and steps < 500:
        return -1
    else:
        return reward


def cartpole(no_eps):
    score = []
    env = gym.make("CartPole-v1")
    observation_space = env.observation_space.shape[0]
    action_space = env.action_space.n
    dqn = DQN(observation_space, action_space)
    run = 0
    while run < no_eps:
        a = 0
        run += 1
        print("Episode number {}".format(run))
        state = env.reset()
        state = np.reshape(state, [1, observation_space])
        while True:
            a += 1
            action = dqn.act(state)
            state_next, reward, terminal, info = env.step(action)
            # env.render()
            reward = reward_giver(reward, terminal, a)
            state_next = np.reshape(state_next, [1, observation_space])
            dqn.remember(state, action, reward, state_next, terminal)
            state = state_next
            if terminal:
                break
            dqn.experience_replay()
        score.append(a)
    return dqn, score


final_dqn, score = cartpole(3000)

with open("/Users/ft19377/Documents/cartpole_dqn", "wb") as cartpole_file:
    pickle.dump(final_dqn, cartpole_file)

plt.plot(score)
file_path = "/Users/ft19377/Documents/cartpole_score.pdf"
plt.savefig(file_path)
plt.show()

Вот самый последний построенный сюжет. участок длины трасс . Как вы можете видеть, около 300-500 баллов он получает постоянный игровой счет 10, и примерно с ~ 2870 и далее. Это проблема программирования, которая вызывает это неоптимальное заклинание из 10 очков? Я следовал за этим из статьи TDS и сделал только небольшие изменения (например, функцию вознаграждения, так что обратная связь является только отрицательным вознаграждением, если завершение происходит меньше, чем выделенное время, отведенное для проблемы в среде Gym), которое не должно вызывать Эта проблема.

e: когда я загружаю обученного агента и запускаю его, когда он остановился на этом неоптимальном шаге 10, и визуализирую среду, это почти точно такой же шаблон, который происходит каждый раз, что заставляет меня задуматься возможно, это ошибка кодирования.

e2: я исследовал дальше, и кажется, что если я перезагружу последнюю обученную модель и запускаю ее, то эпизод почти идентично завершает последний прогон обучения. Например, он всегда может двигаться вправо, удерживая полюс несколько сбалансированным, пока тележка не сойдет с экрана. Это кажется мне странным, поскольку начальное состояние является случайным, и поэтому оно не всегда должно одинаково воспроизводиться, то есть иногда может быть лучше go влево, чем вправо.

...