自定义Estimator输出层无激活函数及损失计算相关技术问询
让我来一步步解答你的两个问题,结合你的代码场景来说会更清楚:
问题1:一般情况下输出层是否应当设置激活函数?
这完全取决于你要解决的任务类型,没有绝对的「必须」规则:
- 对于回归任务(比如预测房价、温度这类连续值):输出层通常不需要设置激活函数,因为我们要预测的是任意范围内的连续数值,激活函数会限制输出范围,反而影响预测效果。
- 对于分类任务:
- 二分类任务:通常会用
sigmoid作为激活函数,让输出落在(0,1)区间,直接表示样本属于目标类别的概率。 - 多分类任务:如果搭配普通的
softmax_cross_entropy损失函数,你可以在输出层添加softmax激活;但如果是用你代码里的sparse_softmax_cross_entropy,反而不建议在输出层加softmax——具体原因我们在第二个问题里展开说。
- 二分类任务:通常会用
问题2:使用sparse_softmax_cross_entropy计算损失时,是否等同于将softmax作为输出层的激活函数?
从最终损失的计算结果来看,二者是等价的,但从数值稳定性和工程最佳实践的角度,直接用sparse_softmax_cross_entropy处理未加激活的logits是更优的选择:
sparse_softmax_cross_entropy内部会自动对输入的logits执行softmax运算,然后计算交叉熵损失。也就是说,它把「softmax激活+交叉熵计算」合并成了一步操作。- 为什么要这么做?如果分开计算(先加softmax激活,再算交叉熵),softmax输出的概率值可能会非常小(比如远小于1e-10),导致数值下溢,进而影响损失计算的稳定性。而合并计算的方式在TensorFlow内部做了数值优化,能避免这个问题。
- 回到你的代码:
logits = tf.layers.dense(net, params['n_classes'], activation=None)+loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)的写法是完全正确的,而且是多分类任务(尤其是标签是稀疏整数形式时)的推荐写法——它和你在输出层加softmax再用普通交叉熵得到的损失结果一致,但数值表现更稳定。
内容的提问来源于stack exchange,提问作者potato
相关产品推荐
相关产品推荐

