Как использовать слой TimeDsitributed для объединения нейронных сетей (в частности, CNN + LSTM)? - PullRequest
0 голосов
/ 29 мая 2020

Итак, это первый из двух способов, которые я пробовал:

inputs=Input(shape=(frames, 103*4, 1))

z=TimeDistributed(Conv2D(32, (5,25), padding='same', activation='relu'), input_shape=(frames, 103*4, 1))(inputs)
z=TimeDistributed(BatchNormalization())(z)
z=TimeDistributed(ReLU())(z)
z=TimeDistributed(Dropout(0.2))(z)
z=TimeDistributed(MaxPooling2D(pool_size=(1,2)))(z)

z=TimeDistributed(Conv2D(32, (3,5), padding='same', activation='relu'))(z)
z=TimeDistributed(BatchNormalization())(z)
z=TimeDistributed(ReLU())(z)
z=TimeDistributed(Dropout(0.2))(z)
z=TimeDistributed(MaxPooling2D(pool_size=(1,2)))(z)

z=TimeDistributed(Flatten())(z)

z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)

z=Flatten()(z)

z=Dense(1000, activation='relu')(z)
z=Dropout(0.5)(z)

z=Dense(500, activation='relu')(z)
z=Dropout(0.5)(z)

z=Dense(200, activation='relu')(z)
z=Dropout(0.5)(z)

outputs=Dense(88, activation='sigmoid')(z)

Я получаю эту ошибку (хотя в моем коде нет размера шага 2):

ValueError: strides should be of length 1, 1 or 3 but was 2

Я уже рассмотрел этот вопрос , и мне кажется, что я реализовал совет, данный в моем коде. Но в чем проблема? Я не могу получить его gr asp.

Наконец мне удалось объединить CNN и LSTM через FunctionalAPI Keras:

inputs=Input(shape=(frames, 103*4, 1))

z=Conv2D(32, (5,25), padding='same', activation='relu')(inputs)
z=BatchNormalization()(z)
z=ReLU()(z)
z=Dropout(0.2)(z)
z=MaxPooling2D(pool_size=(1,2))(z)

z=Conv2D(32, (3,5), padding='same', activation='relu')(z)
z=BatchNormalization()(z)
z=ReLU()(z)
z=Dropout(0.2)(z)
z=MaxPooling2D(pool_size=(1,2))(z)

z=TimeDistributed(Flatten())(z)

z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)

z=Flatten()(z)

z=Dense(1000, activation='relu')(z)
z=Dropout(0.5)(z)

z=Dense(500, activation='relu')(z)
z=Dropout(0.5)(z)

z=Dense(200, activation='relu')(z)
z=Dropout(0.5)(z)

outputs=Dense(88, activation='sigmoid')(z)


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

Это работает, но я все еще на потеря, если это правильный путь. Я вижу через model.summary(), что моя оболочка TimeDstributed имеет форму вывода (None, 7, 3296), а все слои LSTM имеют форму вывода (None, 7, 1000). Что мне нужно изменить, чтобы дать ему центральный кадр вместо 7 кадров?

Говоря о моем наборе данных, я даю 7 кадров значений амплитуд частот для прогнозирования значений в центральном кадре.

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

@ priyach Вы правы, но, как я вижу, я дал несколько скудное объяснение своего набора данных. У меня есть 2d-массивы со временем по оси x и частотой по оси y (пытаясь предсказать воспроизводимые ноты с учетом информации о частотах)

Итак, если бы я подавал столбцы моего 2-го массива (каждый из которых представляет все частоты на заданное время) в мою сеть, тогда Conv1D и MaxPooling1D были бы правильным выбором

Но вместо столбцов в качестве входных данных я загружаю каждый столбец, окруженный 3 столбцами слева от него и 3 столбцами справа от него ( или используя нулевое заполнение, я не могу получить столбцы). Таким образом, мои входные данные - это, по сути, 2d, и я рассматриваю их как изображения.

Мне удалось создать другую сеть (CNN + DNN + LSTM + DNN) и использовать слой Reshape перед 1-м уровнем LSTM (вместо TimeDistributed) *. 1007 *

Еще вопрос остается (из любопытства и для будущего программирования). Что плохого в том, что я использую слой TimeDistributed?

0 голосов
/ 29 мая 2020

Я предполагаю, что вы хотите применить слой TimeDistributed к измерению кадров, что делает наш ввод двухмерным, который отправляется на слой свертки. Если это так, вам следует использовать Conv1D, а не Conv2D. Соответственно измените размер ядра. Также измените Maxpooling2D на Maxpooling1D соответственно.

Например,

z=TimeDistributed(Conv1D(32, 2, padding='same', activation='relu'))(inputs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...