Text classification CNN加入人工特征后loss变为nan问题求助
问题根因
你将人工特征置0后训练正常,说明问题完全出在人工特征的数值分布、以及和文本特征的融合逻辑上,和优化器、正则等通用配置无关,核心原因包括:
- 人工特征存在未清理的极端异常值/inf值,流入模型后引发计算溢出
- 人工特征和CNN提取的文本特征数值尺度差异过大,直接拼接后梯度更新被大数值特征主导,触发梯度爆炸
- 人工特征张量和文本特征张量拼接时存在隐性维度不匹配,触发广播机制生成无效值
解决方法
- 先做异常值清理:对8个人工特征先做离群值截断,使用箱线图法将超过上下1.5倍四分位距的特征值截断到边界,再基于训练集拟合归一化器(不要用全量数据做归一化),应用到验证、测试集,训练前逐批次校验特征不存在inf、nan值。
- 调整特征融合逻辑:不要直接拼接原始人工特征,先给人工特征单独加小型全连接层做空间投影,映射到和文本特征一致的数值空间后再拼接,示例代码如下:
# 为评论、父评论的人工特征分别做投影 comment_feat_proj = Dense(32, activation='relu')(non_text_comment_input) parent_feat_proj = Dense(32, activation='relu')(non_text_parent_input) # 再和CNN输出的文本特征拼接 convs.extend([comment_feat_proj, parent_feat_proj]) l_merge = concatenate(convs, axis=1)
- 避免计算溢出:修改损失计算逻辑,移除输出层的sigmoid激活,使用带from_logits参数的交叉熵损失,避免sigmoid饱和引发的对数计算溢出:
preds = Dense(labels_index)(x) model.compile( loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), optimizer=adam_optimizer, metrics=['acc'] )
- 增加梯度裁剪:给优化器添加梯度裁剪参数,强制限制梯度最大范数,避免梯度爆炸:
adam_optimizer = Adam(learning_rate=0.000001, clipnorm=1.0)
- 校验张量维度:确认人工特征张量维度为
(batch_size, 5),和CNN池化输出的(batch_size, filters)维度匹配,拼接时axis=1的逻辑不存在维度错位。
内容的提问来源于stack exchange,提问作者Ramapriyan Srivatsan
相关产品推荐
相关产品推荐

