Вход 0 слоя lstm_24 несовместим со слоем: ожидалось ndim = 3, найдено ndim = 2. Получена полная форма: [64, 8] - PullRequest
0 голосов
/ 01 августа 2020

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

Код, который работает с двумя плотными слоями, записывается следующим образом:

class DuelingDeepQNetwork(keras.Model):
    def __init__(self, n_actions, fc1_dims, fc2_dims):
        super(DuelingDeepQNetwork, self).__init__()
        self.dense1 = keras.layers.Dense(fc1_dims, activation='relu')
        self.dense2 = keras.layers.Dense(fc2_dims, activation='relu')
        self.V = keras.layers.Dense(1, activation=None)
        self.A = keras.layers.Dense(n_actions, activation=None)
        
    def call(self, state):
        x = self.dense1(state)
        x = self.dense2(x)
        V = self.V(x)
        A = self.A(x)

        Q = (V + (A - tf.math.reduce_mean(A, axis=1, keepdims=True)))

        return Q

    def advantage(self, state):
        x = self.dense1(state)
        x = self.dense2(x)
        A = self.A(x)

        return A

Он работает без ошибок, но когда я превращаю два первых плотных слоя в LSTM следующим образом:

class DuelingDeepQNetwork(keras.Model):
    def __init__(self, n_actions, fc1_dims, fc2_dims):
        super(DuelingDeepQNetwork, self).__init__()
        self.dense1 = keras.layers.LSTM(fc1_dims, activation='relu')
        self.dense2 = keras.layers.LSTM(fc2_dims, activation='relu')
        self.V = keras.layers.Dense(1, activation=None)
        self.A = keras.layers.Dense(n_actions, activation=None)

Появляется эта ошибка:

Вход 0 слоя lstm_24 несовместим со слоем: ожидается ndim = 3, найдено ndim = 2. Получена полная форма: [64, 8]

После этого вопроса " ожидалось ndim = 3, найдено ndim = 2 Я уже пытался установить форму ввода, используя" state = state .reshape (64, 1, 8) "перед запуском нейронной сети следующим образом:

    def choose_action(self, observation):
    if np.random.random() < self.epsilon:
        action = np.random.choice(self.action_space)
    else:
        state = np.array([observation])
        state = state.reshape(64, 1, 8) #<--------
        actions = self.q_eval.advantage(state)
        action = tf.math.argmax(actions, axis=1).numpy()[0,0]

    return action

Но я получаю точно такую ​​же ошибку. Я также попытался добавить аргумент" return_sequences = True "в обоих слоях но это не сработало.

Я не знаю, что делать, и я должен сдать это через неделю, кто-нибудь просветит меня?

EDIT

Я использую fc1_dims = 64, fc2_dims = 32 и n_actions = 2. Модель использует 8 переменных и имеет размер пакета 64. Я загрузил код в github, чтобы вы могли выполнить его, если хотите. Проект не завершен поэтому я пока не буду писать надлежащую версию для чтения.

[github с кодом] [2]

1 Ответ

0 голосов
/ 02 августа 2020

Итак, приведенный ниже код работает для меня без каких-либо проблем.

class DuelingDeepQNetwork(keras.Model):
    def __init__(self, n_actions, fc1_dims, fc2_dims):
        super(DuelingDeepQNetwork, self).__init__()
        self.dense1 = keras.layers.LSTM(fc1_dims, activation='relu', return_sequences=True)
        self.dense2 = keras.layers.LSTM(fc2_dims, activation='relu')
        self.V = keras.layers.Dense(1, activation=None)
        self.A = keras.layers.Dense(n_actions, activation=None)
        
    def call(self, state):
        x = self.dense1(state)
        x = self.dense2(x)
        V = self.V(x)
        A = self.A(x)

        Q = (V + (A - tf.math.reduce_mean(A, axis=1, keepdims=True)))

        return Q

    def advantage(self, state):
        x = self.dense1(state)
        x = self.dense2(x)
        A = self.A(x)

        return A

И затем вызов модели, как показано ниже:

LSTMModel = DuelingDeepQNetwork(2, 64, 32)
LSTMModel.build(input_shape=(None,1,8))
LSTMModel.summary()

Результат, как показано ниже:

Model: "dueling_deep_q_network_7"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm_12 (LSTM)               multiple                  18688     
_________________________________________________________________
lstm_13 (LSTM)               multiple                  12416     
_________________________________________________________________
dense_16 (Dense)             multiple                  33        
_________________________________________________________________
dense_17 (Dense)             multiple                  66        
=================================================================
...