tensorflow的softmax实现

第一个参数logits:就是神经网络最后一层的输出,如果有batch的话,它的大小就是[batchsize,num_classes],num_classes就是分类的数量。单样本的话,大小就是num_classes
第二个参数labels:实际的标签,它的shape同上

第一步是先对网络最后一层的输出做一个softmax,
这一步通常是求取输出属于某一类的概率,对于单样本而言,
输出就是一个num_classes大小的向量([Y1,Y2,Y3…]其中Y1,Y2,Y3…分别代表了是属于该类的概率),
多样本的话就是输出[batchsize,num_classes]大小的矩阵
softmax的公式是:

第二步是softmax的输出向量[Y1,Y2,Y3…]和样本的实际标签做一个交叉熵cross_entropy,公式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- coding: utf-8 -*-
# https://blog.csdn.net/m0_37041325/article/details/77040060
import tensorflow as tf

# our NN's output (尚未经过softmax)
logits = tf.constant([[0.9, 2.1, 3.0], [0.9, 2.1, 3.0], [0.9, 2.1, 3.0]])
# true label
# 注意这里标签必须是浮点数,不然在后面计算tf.multiply时就会因为类型不匹配tf_log的float32数据类型而出错
y_ = tf.constant([[0, 0, 1.0], [0, 0, 1.0], [0, 0, 1.0]])


# 方式一:自己算cross entropy
y = tf.nn.softmax(logits)
tf_log = tf.log(y)
pixel_wise_mult = tf.multiply(y_, tf_log)
cross_entropy = -tf.reduce_sum(pixel_wise_mult)


# 方式二:用组合版 softmax_cross_entropy (TF进行了内部优化)
cross_entropy2_step1 = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=logits)
cross_entropy2_step2 = tf.reduce_sum(cross_entropy2_step1) # dont forget tf.reduce_sum()!!
with tf.Session() as sess:
y_value, tf_log_value, pixel_wise_mult_value, cross_entropy_value = sess.run(
[y, tf_log, pixel_wise_mult, cross_entropy])
cross_entropy2_step1_value, cross_entropy2_step2_value = sess.run([cross_entropy2_step1, cross_entropy2_step2])
print("==== 方式一 ====\n")
print("step1:softmax result=\n%s\n" % (y_value))
print("step2:tf_log_result result=\n%s\n" % (tf_log_value))
print("step3:pixel_mult=\n%s\n" % (pixel_wise_mult_value))
print("step4:cross_entropy result=\n%s\n" % (cross_entropy_value))

print("==== 方式二 ====\n")
print("Function(softmax_cross_entropy_with_logits) result=\n%s\n" % (cross_entropy2_step1_value))
print("Function(tf.reduce_sum) result=\n%s\n" % (cross_entropy2_step2_value))