TensorFlow模型恢复推理问题:基于tf.layers与softmax_cross_entropy_with_logits
看起来你踩了一个TensorFlow老版本模型恢复的典型坑——混淆了模型参数张量和输出张量,再加上softmax激活的位置差异,直接导致推理结果完全偏离预期。我给你梳理几个关键的解决步骤:
先找准正确的预测张量
你之前用'output/bias:0'完全错了,这个只是输出层的偏置参数本身,根本不是模型的输出结果!训练时你用tf.layers.dense构建输出层时,因为softmax_cross_entropy_with_logits要求输入是未经过softmax的logits,所以输出层肯定没加激活函数。此时输出的logits张量名称应该是'output/BiasAdd:0'(tf.layers.dense的底层操作是权重乘输入加偏置,对应这个操作的输出)。
如果你记不清准确名称,有两个办法:一是回到训练代码,给输出层的logits张量显式命名,比如logits = tf.layers.dense(..., name='output_logits'),然后打印logits.name就能拿到准确的张量名;二是恢复模型后,用[op.name for op in tf.get_default_graph().get_operations()]列出所有操作,找到输出层对应的输出节点。补上推理时的softmax(如果需要)
训练时tf.nn.softmax_cross_entropy_with_logits内部已经做了数值稳定的softmax计算,所以你的模型输出层没有加softmax激活。推理时必须自己对logits做softmax才能得到概率形式的预测值:logits = tf.get_default_graph().get_tensor_by_name('output_logits:0') predictions = tf.nn.softmax(logits)如果是回归任务(毕竟你提到了PCC,可能是多变量回归场景),那输出层本来就不需要激活,直接用logits作为预测值即可。
验证模型是否正确加载
可以用训练集里的一小批数据,分别在训练结束时和模型恢复后跑一遍,对比两者的输出logits是否几乎一致。如果差异很大,说明模型参数没加载对;如果差异很小,那问题就出在预测张量选择或者后处理上。
另外也可以检查输出层的参数:比如取出'output/kernel:0'(权重)和'output/bias:0'(偏置),和训练时保存的参数值对比,确认加载正确。排查数据预处理和PCC计算的问题
别忽略了数据环节!推理时的数据预处理必须和训练时完全一致——比如归一化用的均值、方差要和训练时相同,不能用测试集的统计量;数据的维度、顺序也要和训练时匹配(比如是否是batch在前,通道在后)。
最后检查PCC的计算代码,比如是不是把预测值和真实值的顺序搞反了,或者对预测值做了不必要的缩放/转换。
内容的提问来源于stack exchange,提问作者John

