You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字符+词嵌入CNN文本分类模型准确率极低问题求助

文本分类CNN模型低准确率问题排查

我尝试使用CNN进行文本分类,模型采用字符级词嵌入+词嵌入的组合,经CNN层提取特征后接入全连接层,以softmax激活完成分类,损失函数为categorical_crossentropy。模型代码如下:

cnns = [
    [64, 3, 2],
    [128, 3, -1],
    [256, 5, 3],
    [256, 5, -1],
    [512, 5, 3],
]

nb_classes = 2

input_word = Input(shape = (default_max_len_words,), name='input_word')
input_chw = Input(shape = (default_max_len_words, default_max_len_subwords), name='input_chw')

embedding_word = Embedding(input_dim=size_of_word_vocab, output_dim=default_emb_dim, input_length=default_max_len_words, name='word_emb') (input_word)

embedding_chw = Embedding(input_dim=size_of_char_vocab, output_dim=default_emb_dim, input_length=default_max_len_subwords, name='chw_emb') (input_chw)
reduced = tf.keras.layers.Lambda(lambda x: tf.reduce_sum(x, axis=2), name='reduction')(embedding_chw)

x = Add(name='adding')([embedding_word, reduced])

for f, ks, ps in cnns: 
    x = Conv1D(filters=f, kernel_size=ks, padding='valid', activation='relu') (x)
    x = BatchNormalization() (x)
    if ps != -1:
        x = MaxPooling1D(pool_size=ps) (x)

x = Flatten() (x)
x = Dense(256, activation='relu') (x)
x = Dense(128, activation='relu') (x)

x = Dense(2, activation='softmax') (x)

model = keras.Model(inputs=[input_word, input_chw], outputs=x, name='temp')
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['Accuracy'])

训练10轮后,模型的准确率和损失不再变化,且准确率极低,训练指标为:loss: 0.0162 - accuracy: 0.1983 - val_loss: 1.8428 - val_accuracy: 0.0814。已确认数据无NaN值,且训练前已完成数据打乱,以下是可能的问题排查方向:

  • 标签编码与损失函数不匹配:categorical_crossentropy要求标签为one-hot编码格式,如果你的标签是整数形式(比如0/1),应该改用sparse_categorical_crossentropy。若标签编码错误,模型会完全无法学习到有效特征,出现极低准确率。

  • 字符嵌入降维方式不合理:代码中用tf.reduce_sum(axis=2)对字符嵌入降维,直接求和会导致不同字符的嵌入信息相互抵消,丢失字符级特征。建议替换为字符维度的全局池化,比如:

    reduced = tf.keras.layers.GlobalMaxPool1D()(embedding_chw)
    

    或GlobalAveragePool1D,能更合理地提取每个词的字符级特征。

  • CNN层特征维度坍塌:当前CNN序列使用padding='valid',每轮Conv1D都会缩短特征序列长度,再加上多次MaxPooling,可能导致经过几层后特征序列长度变为0或极小,Flatten后无有效特征可用。建议计算每一步的特征长度:
    初始长度为default_max_len_words,每轮Conv1D后长度 = 当前长度 - kernel_size + 1,Pooling后长度 = 当前长度 // pool_size。如果出现长度为负的情况,必须调整kernel_size、pool_size,或把padding改为same避免长度骤降。

  • 过拟合与梯度消失并存:训练集损失极低但验证集损失极高,说明严重过拟合;同时训练准确率也低,说明模型在训练集上也未学到有效特征,大概率存在梯度消失问题。可尝试:

    • 减少CNN层的filter数量(比如从512降到256或128),降低模型复杂度
    • 在Dense层后添加Dropout层(如Dropout(0.5))抑制过拟合
    • 降低Adam优化器的学习率(比如设置optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4))
  • 输入数据预处理错误:检查input_chw的输入格式是否正确,每个词对应的字符序列是否正确填充到default_max_len_subwords长度,是否存在大量全0填充的情况;同时确认词嵌入的输入索引是否正确,未知词的映射处理是否合理。

  • 嵌入层配置问题:确认嵌入层的trainable参数是否为True(默认是True),如果使用预训练词向量,需检查加载是否正确,以及是否设置了合适的微调策略;另外字符词汇表size_of_char_vocab是否准确,过大的词汇表会导致嵌入层参数过多,增加训练难度。

内容的提问来源于stack exchange,提问作者Mohammad Javad Jafari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:31:32