Keras训练中loss与val_accuracy全为0.0000e+00的问题求助
针对你100分类任务中出现的loss为0、验证集accuracy为0、训练accuracy提升缓慢的问题,从代码和训练逻辑上排查出以下核心问题及修复方案:
1. 验证集标签参数拼写错误
代码中验证集生成器的标签参数存在拼写错误:
valid_dataset = tf.data.Dataset.from_generator( generator, args = (ValiFilePath, VailLabelPath), ...)
这里VailLabelPath应为ValiLabelList(与训练集的TrainLabelList对应),传入路径而非标签列表会导致标签完全错误,直接引发验证集accuracy为0。
2. 损失函数与标签编码格式不匹配
你使用了categorical_crossentropy损失函数,但从encoder.transform([Label])的写法来看,大概率是用了LabelEncoder(输出单个整数标签)而非OneHotEncoder(输出one-hot编码向量):
- 如果是整数标签:损失函数应改为
sparse_categorical_crossentropy,这是专门针对整数目标的多分类损失函数,原损失函数会因标签维度不匹配导致计算异常,出现loss为0的情况。 - 如果是one-hot标签:需要确保
transformed_label的形状为(100,),且数据类型转为tf.float32,否则与模型输出的softmax结果计算损失时会出错。
修改示例(假设是整数标签):
model.compile(optimizer=rmsprop, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
3. 生成器内洗牌逻辑冗余
生成器函数内每次调用都会执行np.random.shuffle(tmp),但tf.data.Dataset.from_generator会完整遍历生成器一次,建议在生成器外部完成训练集和验证集的洗牌,避免逻辑混乱:
# 训练集洗牌(外部处理) tmp_train = list(zip(TrainFilePath, TrainLabelList)) np.random.shuffle(tmp_train) TrainFilePath_shuffled = [x[0] for x in tmp_train] TrainLabelList_shuffled = [x[1] for x in tmp_train] # 验证集洗牌(外部处理) tmp_val = list(zip(ValiFilePath, ValiLabelList)) np.random.shuffle(tmp_val) ValiFilePath_shuffled = [x[0] for x in tmp_val] ValiLabelList_shuffled = [x[1] for x in tmp_val] # 简化生成器,仅负责加载数据 def generator(filePath, labelList): for File, Label in zip(filePath, labelList): File = np.load(File) x = tf.cast(tf.squeeze(File), tf.float32) # 统一为float32,匹配模型默认类型 transformed_label = encoder.transform([Label]) yield x, transformed_label[0]
4. 数据类型不一致问题
生成器输出的特征是tf.float64,而Keras模型默认使用tf.float32,虽然兼容但会降低计算效率,建议统一转为tf.float32(如上述代码所示)。
5. 优化器配置检查
确保rmsprop是正确实例化的优化器,可尝试调整学习率适配任务:
rmsprop = tf.keras.optimizers.RMSprop(learning_rate=0.0005) # 可在0.0001~0.001区间尝试调整
6. 数据有效性验证
加载几个np.load(File)的数据,确认特征是否包含有效信息(非全零):如果特征大部分为0,Masking层会屏蔽这些数据,导致模型无法学习;同时确认mask_value=0.是否符合你的数据无效值定义。
内容的提问来源于stack exchange,提问作者Pengu

