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