Embedded-RNN с Keras - проблема с объединением - PullRequest
0 голосов
/ 27 мая 2018

Для классификации аудио я хотел бы попробовать встроенный RNN.Основываясь на MFCC или FFT 30-секундных выборок, я хотел бы создать первый выход для каждой подвыборки 1 с, а затем использовать 30 выходов, чтобы отправить его в другой RNN, чтобы получить окончательный прогноз.Идея состоит в том, чтобы бороться с проблемой исчезающего градиента, разделяя проблему на несколько частей (ваше мнение также приветствуется по поводу этой идеи, она исходит из визуализации, которую я видел с Wavenet).

Это представление модели только с 4 временными шагами и 1 слоем LSTM для каждого уровня:

enter image description here

На следующемкод, у меня есть проблема с измерением Concatenate.Вход iX (Нет, 30, 84), а выход (Нет, 32).После объединения по оси 0 я хотел бы (Нет, 30, 32).

i1 = Input((30, 84))
l1 = CuDNNLSTM(units=32, return_sequences=False) (i1)

i2 = Input((30, 84))
l2 = CuDNNLSTM(units=32, return_sequences=False) (i2)

i3 = Input((30, 84))
l3 = CuDNNLSTM(units=32, return_sequences=False) (i3)

i4 = Input((30, 84))
l4 = CuDNNLSTM(units=32, return_sequences=False) (i4)

i5 = Input((30, 84))
l5 = CuDNNLSTM(units=32, return_sequences=False) (i5)

i6 = Input((30, 84))
l6 = CuDNNLSTM(units=32, return_sequences=False) (i6)

i7 = Input((30, 84))
l7 = CuDNNLSTM(units=32, return_sequences=False) (i7)

i8 = Input((30, 84))
l8 = CuDNNLSTM(units=32, return_sequences=False) (i8)

i9 = Input((30, 84))
l9 = CuDNNLSTM(units=32, return_sequences=False) (i9)

i10 = Input((30, 84))
l10 = CuDNNLSTM(units=32, return_sequences=False) (i10)

i11 = Input((30, 84))
l11 = CuDNNLSTM(units=32, return_sequences=False) (i11)

i12 = Input((30, 84))
l12 = CuDNNLSTM(units=32, return_sequences=False) (i12)

# ... up to 30

input_layer = [i1, i2, i3, i4, i5, i6 ,i7, i8, i9, i10, i11, i12]
first_layer = [l1, l2, l3, l4, l5, l6 ,l7, l8, l9, l10, l11, l12]

# f = Concatenate(axis=0)(first_layer) # Sequential format
f = concatenate(first_layer, axis=0)   # Functional API version

o1 = CuDNNLSTM(units=32, return_sequences=False) (f)

outputs = Dense(16, activation='softmax') (o1)

model = Model(inputs=input_layer, outputs=outputs)

model.summary()

Ошибка логична, поскольку форма (Нет, 32) не совместима с LSTM.

ValueError: вход 0 несовместим со слоем cu_dnnlstm_13: ожидаемый ndim = 3, найденный ndim = 2

Во-вторых, есть ли способ обучить модель с таким же " ячейка"для первого слоя.Например, на изображении я хотел бы иметь красных клеток = синих клеток = желтых клеток = зеленых клеток в терминах состояния ячеек .Это потому, что я хотел бы, чтобы инвариантный вывод для данного звука.Определенный звук в 0 секунд должен иметь такой же выходной сигнал при том же звуке в 10 секунд.Но как и сейчас, выходные данные будут различаться в зависимости от состояния ячейки .

Если это невозможно в Keras, есть ли способ сделать это с помощью tenorflow?

Большое спасибо за вашу поддержку,

Николас

1 Ответ

0 голосов
/ 27 мая 2018

Что касается вашей ошибки, кажется, что вы хотите складывать ваши тензоры (объединять / складывать тензоры по новому измерению), а не объединять их (объединять тензоры по существующему измерению).

Использование K.stack():

import keras.backend as K
from keras.models import Model
from keras.layers import Lambda, Input, CuDNNLSTM, Dense
import numpy as np

# Demonstrating K.stack() on simple tensors:
list_l = [K.variable(np.random.rand(32)) for i in range(30)]
f = K.stack(list_l, axis=0)
print(f)
# > Tensor("stack:0", shape=(30, 32), dtype=float32)

# Actual usage, in your model:
input_layer = [Input(shape=(30, 84)) for n in range(30)]
first_layer = [CuDNNLSTM(units=32, return_sequences=False)(i) for i in input_layer]
f = Lambda(lambda tensors: K.stack(tensors, axis=1))(first_layer)
print(f)
# > Tensor("lambda_1/stack:0", shape=(?, 30, 32), dtype=float32)

o1 = CuDNNLSTM(units=32, return_sequences=False)(f)
outputs = Dense(16, activation='softmax') (o1)
model = Model(inputs=input_layer, outputs=outputs)
model.summary()

Мне не совсем понятно, что вы имеете в виду в своем sup.вопрос ... Может быть, распределение веса для ваших 1-х CuDNNLSTM слоев (см. документ по Shared Layers )?

Если это так, вы можете определить свои первые слои как:

cudnn_lstm_first = CuDNNLSTM(units=32, return_sequences=False)
first_layer = [cudnn_lstm_first(i) for i in input_layer]
...