Как заставить полностью сверточную Unet архитектуру вести себя как гибридная CNN - Рекуррентная архитектура? - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть эта CNN -> двунаправленная архитектура GRU https://github.com/bmcfee/ismir2017_chords, которая используется для прогнозирования последовательности / классификации нескольких активных шагов во времени. Это контролируемая проблема обучения, поэтому у меня есть свои ярлыки. Затем у меня есть другая UNet архитектура, с которой я хочу сделать то же самое, но без использования повторяющихся или плотных слоев. Для того, чтобы вы полностью поняли, что я хочу, я сначала опубликую архитектуру CNN-Bi-GRU:

x = pump.layers()['cqt/mag']

b = BatchNormalization()(x)

c0 = Convolution2D(1, (5, 5), padding='same', activation='relu',
                            data_format='channels_last')(b)

c1 = Convolution2D(36, (1, int(c0.shape[2])), padding='valid', activation='relu',
                            data_format='channels_last')(c0)

r1 = Lambda(lambda x: squeeze(x, axis=2))(c1)

rs = Bidirectional(GRU(64,
                                         return_sequences=True))(r1)

# 1: pitch class predictor
pc_p = TimeDistributed(Dense(pump.fields['chord_struct/pitch'].shape[1], activation='sigmoid'),
                       name='chord_pitch')(rs)

# 2: root predictor
root_p = TimeDistributed(Dense(13, activation='softmax'),
                         name='chord_root')(rs)

# 3: bass predictor
bass_p = TimeDistributed(Dense(13, activation='softmax'),
                         name='chord_bass')(rs)

# 4: merge layer
codec = concatenate([rs, pc_p, root_p, bass_p])


p0 = Dense(len(pump['chord_tag'].vocabulary()), activation='softmax',
                    bias_regularizer= tf.keras.regularizers.l2())

tag = TimeDistributed(p0, name='chord_tag')(codec)


model = Model(x, [tag, pc_p, root_p, bass_p])

Сводка модели дает мне:

Слой (тип) Выходной параметр формы #
Подключен к
===================================== ================================================== ========== cqt / mag (InputLayer) (Нет, Нет, 216, 3) 0

__________________________________________________________________________________________________ batch_normalization_4 (BatchNor (Нет, нет, 216, 3) 12
cqt / mag [0] [0]
__________________________________________________________________________________________________ conv2d_8 (Conv2D) (нет, нет, 216, 1) 76
batch_normalization_4 [0] [0]
________________________________________________________________________________________________ conv2d_9 (Conv2D) (нет, 1 , 36) 7812
conv2d_8 [0] [0]
_____________________________________________________________________________________________ _____ лямбда_4 (лямбда) (нет, нет, 36) 0
conv2d_9 [0] [0]
__________________________________________________________________________________________________ двунаправленный (4) (нет, 128) 38784
лямбда_4 [0] [0]
__________________________________________________________________________________________________ chord_pitch (TimeDistributed) (Нет, Нет, 12) 1548
bidirectional_4 [0] [0]
__________________________________________________________________________________________________ chord_ root (TimeDistributed) (Нет, None, 13) 1677
двунаправленный_ ] [0]
__________________________________________________________________________________________________ chord_bass (TimeDistributed) (нет, отсутствует, 13) 1677
двунаправленный_4 [0] [0]
________________________________________________________________________________________________ concatenate_4 (объединенный) (нет, отсутствует, 166) 0
двунаправленный_ [0] [0]
chord_pitch [ 0] [0]
chord_root [0] [0]
chord_bass [0] [0]
__________________________________________________________________________________________________ chord_tag ​​(TimeDistributed) (нет, нет, 170) 28390
concatenate_4 [0] [0] ]
=================================================== ================================================== == Всего параметров: 79 976 Обучаемых параметров: 79 970 Необучаемых параметров: 6

Входные данные для обеих моделей представляют собой одно и то же частотно-временное представление с формой (партия, Время, Частота, Каналы) для Рекуррентная архитектура и (пакет, каналы, время, частота) для архитектуры UNet. По существу, в рекуррентной архитектуре два уровня CNN сначала используются для извлечения соответствующих признаков, а затем лямбда-уровень отбрасывает частотные интервалы, и результат подается в двунаправленный GRU. Затем три слоя TimeDistributed Dense используются для классификации трех разных вещей, а именно (активных тонов, root и баса), и эти три слоя объединяются с выходом BI-GRU. На последнем этапе к объединенному слою применяется слой TimeDistributed Dense со 170 единицами (количество моих классов). Теперь предположим, что у меня есть UNet архитектура, которая состоит из настройки кодера / декодера. Мой последний UNet Блок перед обычным классификационным слоем имеет форму = (?, 51,?, 216) и называется mresblock8 . Теперь мое решение получить те же прогнозы из моего UNET состоит в следующем:

# 1: pitch class predictor
pc_p = Conv2D((pump.fields['chord_struct/pitch'].shape[1]),1 , 1 ,activation='sigmoid',
                       data_format='channels_first')(mresblock8)

# 2: root predictor
root_p = Conv2D(13, 1 , 1 ,activation='softmax',
                        data_format='channels_first')(mresblock8)
# 3: bass predictor
bass_p = Conv2D(13, 1, 1,activation='softmax',
                         data_format='channels_first')(mresblock8)

display(pc_p,root_p,bass_p)

<tf.Tensor 'conv2d_49/Sigmoid:0' shape=(?, 12, ?, 216) dtype=float32>

<tf.Tensor 'conv2d_53/truediv:0' shape=(?, 13, ?, 216) dtype=float32>

<tf.Tensor 'conv2d_54/truediv:0' shape=(?, 13, ?, 216) dtype=float32>

Кроме того, моя UNET модель имеет data_format = '' channel_first. Поэтому вместо использования TimeDistributed (Dense ...)) я использовал Conv2D с тем же количеством фильтров, что и при необходимости, и использовал размер фильтра (1,1). А затем соединили выходные данные моего последнего UNet слоя (mresblock8) с ранее упомянутыми тремя слоями Conv2D (pc_p, root_p, bass_p):

 codec = concatenate([mresblock8,pc_p, root_p, bass_p],axis = 1)
 codec

tf.Tensor 'concatenate_20 / concat: 0 'shape = (?, 89,?, 216) dtype = float32>

 codec = BatchNormalization(axis=1, scale=False)(codec) 
 codec

tf.Tensor' batch_normalization_149 / cond / Merge: 0 'shape = (?, 89 ,?, 216) dtype = float32>

Затем вместо применения слоя TimeDistributed Dense к моему сцепленному слою (как рекуррентная архитектура) я применяю слой Conv2D со 170 фильтрами (количество моих классов ) к моему сцепленному слою, т.е.:

p0 = Conv2D(len(pump['chord_tag'].vocabulary()), 1, 1, activation='softmax', data_format = 'channels_first')(codec)
p0

tf.Tensor 'conv2d_58 / truediv: 0' shape = (?, 170,?, 216) dtype = float32>

и на последнем шаге я делаю:

model = Model(x, [p0, pc_p, root_p, bass_p])

Правильно ли мое решение / процесс мышления ?? Мне тоже нужно избавиться от оси частот ? или я могу позволить этому быть там ?? Для ясности, вы можете просто сравнить часть декодера рекуррентной архитектуры с моим предложенным решением / заменой? Кроме того, я должен использовать TimeDistributed (Conv2D (....)) или это нормально, если я просто использую Conv2D здесь ??

Любая помощь будет принята с благодарностью, и если что-то неясно, не стесняйтесь спрашивать меня о разъяснениях.

Приветствия,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...