SparseCategoricalCrossentropy

import tensorflow as tf
import numpy as np
y_true = tf.constant([1, 2])
y_pred = tf.constant([[0.05, 0.95, 0], [0.1, 0.8, 0.1]])
loss = tf.reduce_mean(tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred))
scce = tf.keras.losses.SparseCategoricalCrossentropy()

print(loss.numpy())
print(scce(y_true, y_pred).numpy())
output
1.1769392
1.1769392

其中有两个基准值1,2说明一共有两类且分别为第一类,第二类,又有两个预测数组[0.05, 0.95, 0], [0.1, 0.8, 0.1]。表明在预测第一个的时候,属于第一类的概率为0.05,属于第二类的概率为0.95,既不属于第一类也不属于第二类的概率为0。同理,在预测第二个的时候,属于第一类的概率为0.1,属于第二类的概率为0.8,既不属于第一类也不属于第二类的概率为0.1。
所以在使用这个函数时,需要如下组织y_true和y_pred:
假如分类时存在三类:其中y_true为:[1,2,1,3]

因为sparse_categorical_crossentropy接受的是离散值,且y_true出现了1,2,3 所以共三类,共四个需要预测。y_pred的组织应该如下:

[0.05, 0.95, 0,0],
[0.1, 0.8, 0.1,0],
[0.1, 0.8, 0.1,0],
[0.1, 0.8, 0.1,0]

意思为,对于第1个预测:属于第一类,第二类,第三类的概率分别为0.05,0.95,0;不属于任何一类的概率为0。
对于第2,3,4个的预测依次类推。
其中这样的组织方式,适用于分类任务,也适用于语义分割任务。因为语义分割任务就是像素点所属类别的预测。
再比如:

y_true = tf.constant([1, 2, 3, 4])
y_pred = tf.constant([
    [0.05, 0.95, 0, 0, 0],
    [0.1, 0.8, 0.1, 0, 0],
    [0.1, 0.8, 0.1, 0, 0],
    [0.1, 0.8, 0.1, 0, 0]
    })

注意,假如y_true:[1, 2, 4, 4],还是看做三类:
y_pred:

[0.05, 0.95, 0,0],
[0.1, 0.8, 0.1,0],
[0.1, 0.8, 0.1,0],
[0.1, 0.8, 0.1,0]

 

 

 

在搭建深度学习模型,构建损失函数经常用到交叉熵函数,同时用到SparseCategoricalCrossentropy。

 

m = tf.keras.metrics.SparseCategoricalCrossentropy()
m.update_state(
  [1, 2],
  [[0.05, 0.9, 0.05], [0.1, 0.8, 0.1]])

# y_true = one_hot(y_true) = [[0, 1, 0], [0, 0, 1]]
# logits = log(y_pred)
# softmax = exp(logits) / sum(exp(logits), axis=-1)
# softmax = [[0.05, 0.95, EPSILON], [0.1, 0.8, 0.1]]

# xent = -sum(y * log(softmax), 1)
# log(softmax) = [[-2.9957, -0.0513, -16.1181], [-2.3026, -0.2231, -2.3026]]
# y_true * log(softmax) = [[0, -0.0513, 0], [0, 0, -2.3026]]

# xent = [0.0513, 2.3026]
# Reduced xent = (0.0513 + 2.3026) / 2

print('Final result: ', m.result().numpy())  # Final result: 1.176

输出结果为Final result: 1.2039728。

loss = 0
j = [[0,1,0],[0,0,1]]
z = [[0.05, 0.9, 0.05], [0.1, 0.8, 0.1]]
z = np.log(z)
for i in range(2):
    print(j[i])
    print(np.log(np.exp(z[i][0])/(np.exp(z[i][0])+np.exp(z[i][1])+np.exp(z[i][2]))))
    
    loss = loss + j[i][0]*np.log(np.exp(z[i][0])/(np.exp(z[i][0])+np.exp(z[i][1])+np.exp(z[i][2])))+\
            j[i][1]*np.log(np.exp(z[i][1])/(np.exp(z[i][0])+np.exp(z[i][1])+np.exp(z[i][2])))+\
            j[i][2]*np.log(np.exp(z[i][2])/(np.exp(z[i][0])+np.exp(z[i][1])+np.exp(z[i][2])))
       
    
#     loss = loss+0*np.log(np.exp(i[0])/(np.exp(i[0])+np.exp(i[1])+np.exp(i[2])))/3+\
#                                               1*np.log(np.exp(i[1])/(np.exp(i[0])+np.exp(i[1])+np.exp(i[2])))/3+\
#         1*np.log(np.exp(i[2])/(np.exp(i[0])+np.exp(i[1])+np.exp(i[2])))/3
loss/2

对上面的结果取负数,得到与上面相同的结果。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值