Tensorflow выдает ошибку «Несовместимые фигуры» в лямбда-слое, когда batch_size> 1 - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть простой 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

1 Ответ

0 голосов
/ 08 апреля 2019

При вызове лямбда-слоя ваш тензор x имеет форму (batch_size, MAX_LENGTH, EMB_SIZE), а inp_w имеет форму (batch_size, MAX_LENGTH).Так как вы выполняете транспонирование inp_w внутри своей пользовательской функции mult, вы получаете формы, упомянутые в сообщении об ошибке, которые несовместимы.

Другая проблема с вашим кодом заключается в том, что вы пытаетесьиспользовать функцию numpy внутри лямбда-слоя.Вы должны использовать только бэкэнд-функции Keras.Вместо этого должен работать следующий код:

def mult(tensors):
    x = tensors[0] # shape (bs, len, dim)
    weights = K.expand_dims(tensors[1], -1) # shape (bs, len, 1)
    return weights * x # pointwise multiplication
...