tf.nn.softmax_cross_entropy_with_logits函数在TensorFlow中计算分类问题交叉熵损失函数时会用到。
这个函数的返回值不是一个数,而是一个向量。如果要求最终的交叉熵损失,我们需要再做一步tf.reduce_sum操作,即对向量中的所有元素求和。
让我们以具体示例来说明tf.nn.softmax_cross_entropy_with_logits函数是怎样工作的:
#-*-coding:utf-8-*-
"""
@author:taoshouzheng
@time:2019/3/25 20:29
@email:tsz1216@sina.com
"""
import tensorflow as tf
"""定义计算图中的计算"""
# 神经网络的最后一层的输出:三条样本在神经网络中的输出
logits = tf.constant([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]) # 常量
# 样本的真实标签,用one-hot编码形式表示:三条样本的真实标签
y_ = tf.constant([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0]])
# 1(1):softmax操作
y = tf.nn.softmax(logits)
# 1(2):cross_entropy操作
y_mul = -(y_ * tf.log(y)) # 所有样本的真实标签乘以其预测概率的对数
cross_entropy = tf.reduce_sum(y_mul) # 计算所有元素之和作为损失函数
# 2(1):使用tf.nn.softmax_cross_entropy_with_logits
softmax_cross_entropy_with_logits = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_)
cross_entropy_2 = tf.reduce_sum(softmax_cross_entropy_with_logits) # 计算所有元素之和作为损失函数
# 在会话中执行计算
with tf.Session() as sess:
softmax = sess.run(y)
print('tf.nn.softmax(logits):')
print(softmax)
print('-------------------------------')
cross_entropy = sess.run(cross_entropy)
y_mul = sess.run(y_mul)
print('- y_ * tf.log(y):')
print(y_mul)
print('tf.reduce_sum(y_mul):')
print(cross_entropy)
print('-------------------------------')
softmax_cross_entropy_with_logits = sess.run(softmax_cross_entropy_with_logits)
print('tf.nn.softmax_cross_entropy_with_logits:')
print(softmax_cross_entropy_with_logits)
cross_entropy2 = sess.run(cross_entropy_2)
print('tf.reduce_sum(softmax_cross_entropy_with_logits):')
print(cross_entropy2)
这里我们以两种方式计算三条样本的交叉熵,结果如下:
tf.nn.softmax(logits):
[[0.09003057 0.24472848 0.66524094]
[0.09003057 0.24472848 0.66524094]
[0.09003057 0.24472848 0.66524094]]
-------------------------------
- y_ * tf.log(y):
[[0. 0. 0.407606 ]
[0. 0. 0.407606 ]
[0. 0. 0.40760598]]
tf.reduce_sum(y_mul):
1.222818
-------------------------------
tf.nn.softmax_cross_entropy_with_logits:
[0.40760595 0.40760595 0.40760595]
tf.reduce_sum(softmax_cross_entropy_with_logits):
1.2228179
可以看到tf.nn.softmax_cross_entropy_with_logits函数内部所做的操作其实就是将每条样本真实标签的ont-hot向量与其预测概率的对数相乘,将结果按元素取负号,然后再按样本将元素逐行相加。
注意:这个函数的返回值不是一个数,而是一个向量。如果要求最终的交叉熵损失,我们需要再做一步tf.reduce_sum操作,即对向量中的所有元素求和。
谢谢!
参考了以下内容: