У меня есть простой CNN с двумя входами для обработки текста (код ниже).Один вход для токенов, другой для весов.Оба входа являются последовательностями одного и того же MAX_LENGTH
.После прохождения токенов через слой внедрения я бы хотел умножить эти вложения на соответствующие веса.Поэтому я определил новый лямбда-слой и функцию mult для этой цели.
Фактическое поведение
Когда я пытаюсь подгонять модель только с вводом в batch_size==1
это работает.Но если batch_size > 1
показывает
InvalidArgumentError: Incompatible shapes
Ожидаемое поведение
Модель корректно подходит для партий любого размера.
Исключение
Вот пример исключения при выполнении подгонки с batch_size=256
, MAX_LENGTH=30
, EMB_SIZE=300
:
InvalidArgumentError: Incompatible shapes: [256,30,300] vs. [30,256] [[{{node lambda_41/mul}}]]
Означает ли это imp_w тензорной формы, равной [30,256]
?Не должно ли оно быть равным [256,30]
вместо этого?
Наконец, вопрос в том, что не так с моей конфигурацией сети?Спасибо!
def mult(tensors):
# print(tensors[0].shape, tensors[1].shape)
return np.multiply(tensors[0], K.transpose(tensors[1]))
def TextSentCNN(n_filters, filter_sizes):
inp_t = Input(shape=(MAX_LENGTH,))
inp_w = Input(shape=(MAX_LENGTH,))
x = Embedding(MAX_FEATURES, EMB_SIZE, weights=[embedding_matrix], trainable=False)(inp_t)
x = keras.layers.Lambda(mult, output_shape=(MAX_LENGTH, EMB_SIZE,))([x, inp_w])
x = SpatialDropout1D(0.2)(x)
x = Reshape((MAX_LENGTH, EMB_SIZE, 1))(x)
pools = []
for filter_size in filter_sizes:
conv = Conv2D(n_filters, kernel_size=(filter_size, EMB_SIZE), padding='valid', kernel_initializer='normal', activation='relu')(x)
pool = MaxPool2D(pool_size=(MAX_LENGTH - filter_size + 1, 1), strides=(1,1), padding='valid')(conv)
pools.append(pool)
x = Concatenate(axis=1)(pools)
x = Flatten()(x)
x = Dropout(.5)(x)
out = Dense(3, activation='softmax')(x)
model = Model(inputs=[inp_t, inp_w], outputs=out)
model.compile(
loss='categorical_crossentropy',
optimizer=Adam(lr=0.001),
metrics=['accuracy']
)
return model