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

基于预训练Word2Vec的多作者文本分类模型训练出现loss为nan、accuracy为0问题求助

嘿,我来帮你搞定这个训练异常的问题!

看了你的代码和描述,马上找到了核心问题,还有几个细节需要调整,咱们一步步来解决:

核心问题:多分类任务用了二分类的模型配置

你要做的是8/9位作者的文本分类,属于多分类任务,但代码里却用了二分类的设置:

  • 输出层写的是Dense(1, activation='sigmoid'):这个只能输出0或1,根本没法区分多个作者
  • 损失函数用了binary_crossentropy:这玩意儿只适用于二分类场景,多分类用它会直接导致损失计算出错,出现nan,模型自然学不到东西,准确率就一直是0了

怎么改?

根据你标签的形式(用0、1、2...这样的整数代表不同作者),最方便的是用sparse_categorical_crossentropy损失函数,不用把标签转成one-hot编码,同时调整输出层:

# 重新定义模型的输出层
model = Sequential()
model.add(embedding_layer)
model.add(Conv1D(filters=128, kernel_size=5, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
# 这里要改成你的作者数量,代码里你写了9个(a1到a9),所以填9;如果实际是8位就改8
model.add(Dense(9, activation='softmax'))
print(model.summary())

# 编译的时候换损失函数
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

如果你更习惯用categorical_crossentropy,那得先把标签转成one-hot编码:

from keras.utils import to_categorical

# 把训练和测试标签转成one-hot格式
ytrain = to_categorical(ytrain)
ytest = to_categorical(ytest)

# 输出层还是Dense(9, activation='softmax'),然后编译时用这个损失
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

其他几个潜在小问题也要注意

1. 预训练词向量里没有的词怎么处理?

你的get_weight_matrix函数里,如果词汇表中的词不在预训练Word2Vec里,embedding.get(word)会返回None,这时候对应的权重会是全0,可能影响模型效果。可以改成用随机小值初始化这些词:

import numpy as np

def get_weight_matrix(embedding, vocab):
    vocab_size = len(vocab) + 1
    weight_matrix = zeros((vocab_size, 100))
    for word, i in vocab.items():
        vec = embedding.get(word)
        if vec is not None:
            weight_matrix[i] = vec
        else:
            # 给没找到的词赋随机小值,比全0好
            weight_matrix[i] = np.asarray(np.random.uniform(-0.05, 0.05, 100), dtype='float32')
    return weight_matrix

2. 作者数量要对应上

你描述里说的是8位作者,但代码里写了a1到a9共9个,得确认你的文件夹里确实是9位作者的文本,不然标签数量和样本数量不匹配,也会出问题。比如训练集每个作者10本,9个作者就是90个样本,ytrain的长度得是90,测试集每个2本就是18个样本,ytest长度18,这点要核对清楚。

3. 文本长度可以适当限制

你用max_length = max([len(s.split()) for s in train_docs])来取最长文本长度当输入长度,如果有特别长的文本,会让模型输入维度太大,训练起来慢还容易出问题。可以考虑设一个固定值,比如max_length = 500,太长的文本截断,短的补全。

改完之后再试试

调整完这些地方,重新运行代码,应该就能看到loss正常下降,准确率慢慢提升了,测试集也能得到合理的准确率啦!


内容的提问来源于stack exchange,提问作者Sona Joseph

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:47:50