我正在尝试为多类分类(6个类)构建NLP CNN模型。结构的第一部分是:
输入->嵌入->转换-> GlobalMaxPool->退出->密集
在密集层之后,每个输入句子将转换为100维嵌入。
此后,我传入一个常数矩阵(6,100),它是六个不同标签的词嵌入矩阵(每行代表100维词嵌入),并计算句子嵌入与每个词之间的余弦相似度标签词嵌入作为评分函数的结果,结果为(6,100)。
接下来,我将其结果传递到致密层以获得输出,使用1个神经元和S形作为激活,得到的结果为(6,1),但编译时给了我标题错误。
下面是所有代码,感谢所有帮助!
MAX_SEQUENCE_LENGTH = 250
jdes_sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='float32')
word_embedding_layer = embedding_layer(jdes_sequence_input)
jdes = word_embedding_layer
jdes = Conv1D(filters=1000, kernel_size=5, strides=1, activation='tanh')(jdes)
jdes = GlobalMaxPooling1D()(jdes)
jdes = Dense(1000, activation='tanh')(jdes)
jdes = Dropout(0.3)(jdes)
jdes = Dense(100, activation='relu')(jdes)
def cosine_distance(input): # label_embedding is the constant matrix
jd = K.l2_normalize(input, axis=-1)
jt_six = K.l2_normalize(label_embedding, axis=-1)
return jd * jt_six # return a 6*100 result
distance = Lambda(cosine_distance, output_shape=(6,100))(jdes)
result = Dense(1, activation='sigmoid')(distance)
model = Model(inputs=jdes_sequence_input, outputs = result)
sgd = optimizers.SGD(lr=0.05)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
model.fit(pad_data, labels, validation_split=0.2, batch_size=64, nb_epoch=1)
pad_data的形状为:(18722,250) 标签的形状:(18722,6)
答案 0 :(得分:0)
花了很多时间来理解问题和错误。我得出的结论是:
形状(?,?,?)和(6,1)必须具有相同的等级
这表明输出(形状(6,1))有问题。您在模型的末尾即密集层之后使用了自定义层。错误在于该自定义层。
距离= Lambda(余弦距离,output_shape =(6,100))(jdes)
您将输出形状定义为(6,100)。我的想法是,您忘记了在Keras中编写的图层必须能够一次处理整个批处理。因此,输出应为(batch_size,6,100)形状。
现在,output_shape将为(?,6,100),其等级为'3',与形状的等级(?,?,?)相同。
尝试一下。
答案 1 :(得分:0)
我遇到了类似的问题,这与我的自定义距离lambda和传递给它的函数有关。
要修复它,我必须这样做
def get_abs_diff( vects ):
x, y = vects
return K.abs( x - y )
def eucl_dist_output_shape(shapes):
shape1, shape2 = shapes
return (shape1[0], 1)
#Original
#return(1,) This messed up the ranking
这不一定是解决您问题的方法,但它是一个起点。 @Kadam Parikh是正确的,因为问题出在自定义距离公式中。