как объединить предварительно обученный слой встраивания и слой ввода - PullRequest
1 голос
/ 13 февраля 2020
normal_input = Input(shape=(56,))

pretrained_embeddings = Embedding(num_words, 200, input_length=max_length, trainable=False,
                                                            weights=[ft_embedding_matrix])

concatenated = concatenate([normal_input, pretrained_embeddings])

dense = Dense(256, activation='relu')(concatenated)

Моя идея состояла в том, чтобы создать вход с размером 256 и передать его в плотный слой.

Я получил следующую ошибку.

ValueError : Слой concatenate_10 был вызван со входом, который не является символом c тензор. Полученный тип:. Полный ввод: [,]. Все входные данные для слоя должны быть тензорами.

Пожалуйста, помогите мне, как это сделать.

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

Вам нужен ввод, чтобы выбрать, какое встраивание вы используете.

Поскольку вы используете 150 слов, ваши вложения будут иметь форму (batch,150,200), которую невозможно каким-либо образом объединить с (batch, 56). Вам нужно что-то преобразовать, чтобы соответствовать форме. Я предлагаю вам попробовать слой Dense, чтобы преобразовать 56 в 200 ...

word_input = Input((150,))
normal_input = Input((56,))

embedding = pretrained_embeddings(word_input)
normal = Dense(200)(normal_input)

#you could add some normalization here - read below

normal = Reshape((1,200))(normal)
concatenated = Concatenate(axis=1)([normal, embedding]) 

Я также предлагаю, поскольку вложения и ваши входные данные имеют разную природу, что вы применяете нормализацию, чтобы они стали более похожими :

embedding = BatchNormalization(center=False, scale=False)(embedding)
normal = BatchNormalization(center=False, scale=False)(normal)

Другая возможность (я не могу сказать, что лучше) - это объединить в другом измерении, преобразовав 56 вместо 150:

word_input = Input((150,))
normal_input = Input((56,))

embedding = pretrained_embeddings(word_input)
normal = Dense(150)(normal_input)

#you could add some normalization here - read below

normal = Reshape((150,1))(normal)
concatenated = Concatenate(axis=-1)([normal, embedding]) 

I Если вы считаете, что это больше подходит для периодических и сверточных сетей, вы добавляете новый канал вместо добавления нового шага.


Вы даже можете попробовать двойное объединение, что звучит круто: D

word_input = Input((150,))
normal_input = Input((56,))

embedding = pretrained_embeddings(word_input)
normal150 = Dense(150)(normal_input)
normal201 = Dense(201)(normal_input)

embedding = BatchNormalization(center=False, scale=False)(embedding)
normal150 = BatchNormalization(center=False, scale=False)(normal150)
normal201 = BatchNormalization(center=False, scale=False)(normal201)


normal150 = Reshape((150,1))(normal150)
normal201 = Reshape((1,201))(normal201)
concatenated = Concatenate(axis=-1)([normal150, embedding]) 
concatenated = Concatenate(axis= 1)([normal201, concatenated])
0 голосов
/ 13 февраля 2020

Это потому, что составной слой называется так:

concatenated = Concatenate()([normal_input, pretrained_embeddings])
...