当batch_size> 1时,Tensorflow在Lambda层中引发``不兼容的形状''错误

时间:2019-04-07 21:34:06

标签: tensorflow lambda keras embedding

我有一个简单的CNN,带有两个用于文本处理的输入(下面的代码)。一个输入用于令牌,另一个输入用于权重。两个输入都是相同的MAX_LENGTH的序列。在将令牌传递给嵌入层之后,我想将这些嵌入乘以相应的权重。因此,我为此目的定义了新的Lambda层和功能 mult

实际行为

当我尝试仅使用batch_size==1中的输入进行模型拟合时,它可以工作。但是如果显示batch_size > 1

InvalidArgumentError: Incompatible shapes

预期行为

模型可以正确地适合任何大小的批次。

例外

以下是与batch_size=256MAX_LENGTH=30EMB_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 :(得分:0)

调用lambda层时,张量x的形状为(batch_size, MAX_LENGTH, EMB_SIZE)inp_w的形状为(batch_size, MAX_LENGTH)。由于要在自定义inp_w函数内部进行mult的转置,因此最终会出现错误消息中提到的不兼容的形状。

您的代码的另一个问题是您试图在lambda层中使用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