Keras / Tensorflow Input для слоев RNN - PullRequest
0 голосов
/ 10 марта 2019

Я пытаюсь построить RNN в Керасе. Я не совсем понимаю требуемый формат ввода. Я могу построить плотные сети без проблем, но я думаю, что слои RNN ожидают входное измерение х пакет х шаг по времени? Кто-нибудь может это проверить?

Вот код, который я хотел бы обновить:

Оригинальный код:

def get_generative(G_in, dense_dim=200, out_dim=50, lr=1e-3):
   x = Dense(dense_dim)(G_in)
   x = Activation('tanh')(x)
   G_out = Dense(out_dim, activation='tanh')(x)
   G = Model(G_in, G_out)
   opt = SGD(lr=lr)
   G.compile(loss='binary_crossentropy', optimizer=opt)
   return G, G_out

G_in = Input(shape=[10])
G, G_out = get_generative(G_in)
G.summary()

Модифицировано со слоями GRU и некоторыми немного другими размерами:

def get_generative(G_in, dense_dim=10, out_dim=37, lr=1e-3):
   clear_session()
   x = GRU(dense_dim, activation='tanh',return_state=True)(G_in)
   G_out = GRU(out_dim, return_state=True)(x)
   G = Model(G_in, G_out)
   opt = SGD(lr=lr)
   G.compile(loss='binary_crossentropy', optimizer=opt)
   return G, G_out

G_in = Input(shape=(None,3))
G, G_out = get_generative(G_in)
G.summary()

Ошибка, которую я вижу в этом коде: ValueError: Tensor ("gru_1 / strided_slice: 0", shape = (3, 10), dtype = float32) должен быть из того же графика, что и Tensor ("strided_slice_1: 0 ", shape = (?, 3), dtype = float32).

Если я удаляю «None» выше, я получаю: ValueError: Вход 0 несовместим со слоем gru_1: ожидаемый ndim = 3, найденный ndim = 2

Здесь может быть полезно любое объяснение.

Ответы [ 2 ]

1 голос
/ 10 марта 2019

Вы получаете ошибку, потому что очищаете сеанс после создания входного тензора. Вот почему входной тензор не идет из того же графика, что и остальная часть вашей сети. Чтобы это исправить, просто пропустите строку clear_session().

Другая проблема с вашим кодом: второй уровень GRU ожидает ввода последовательности, поэтому вы должны использовать return_sequences=True внутри первого уровня GRU. Возможно, вы захотите пропустить аргумент return_state=True, поскольку это заставляет слой возвращать кортеж тензоров (output и state) вместо одного выходного тензора.

Подводя итог, следующий код должен сделать это:

def get_generative(G_in, dense_dim=10, out_dim=37, lr=1e-3):
   x = GRU(dense_dim, activation='tanh', return_sequences=True)(G_in)
   G_out = GRU(out_dim)(x)
   G = Model(G_in, G_out)
   opt = SGD(lr=lr)
   G.compile(loss='binary_crossentropy', optimizer=opt)
   return G, G_out
0 голосов
/ 10 марта 2019

Проблема здесь в том, что слои RNN ожидают ввода трехмерного тензора в форме: [num samples, временные шаги, особенности].

Таким образом, мы можем изменить код выше как:

def get_generative(G_in, dense_dim=10, out_dim=37, lr=1e-3):
   x = GRU(dense_dim, activation='tanh',return_state=True)(G_in)
   G_out = GRU(out_dim, return_state=True)(x)
   G = Model(G_in, G_out)
   opt = SGD(lr=lr)
   G.compile(loss='binary_crossentropy', optimizer=opt)
   return G, G_out

G_in = Input(shape=(1,3))
G, G_out = get_generative(G_in)
G.summary()

Итак, мы говорим, что мы ожидаем ввода произвольного числа выборок, каждый из которых состоит из 1 временного шага с 3 функциями.

Анна права, что clear_session () не должна быть внутри функции генератора.

Наконец, если вы действительно хотите вводить данные в сеть, их форма также должна соответствовать тому, что мы только что обсуждали. Вы можете сделать это, используя numpy reshape:

X = np.reshape(X, (X.shape[0], 1, X.shape[1]))

...