sigmoid_cross_entropy_with_logits,softmax_cross_entropy_with_logits,sparse_softmax_cross_entropy_...

╄→гoц情女王★ 提交于 2020-02-19 00:54:37

tf.nn.sigmoid_cross_entropy_with_logits

函数的计算方式就是对输出值先算sigmoid,然后与真实值做交叉商运算。
sigmoid函数的定义:11+ex\displaystyle\frac{1}{1+e^{-x}}
交叉商的计算方式:(labelslog(logits)+(1labels)log(1logits))-(labels*log(-logits)+(1-labels)*log(1-logits))
labelslabels是标签,logitslogits是预测值。
函数的输入通常是形状为(batch_size,num_classes)的张量,输出是(batch_size,num_classes)的张量,每一个值代表当前这个batch_size个数据的每一个数据的loss值,通常接reduce_mean函数计算平均值得到一个标量的loss.
注意这个函数与后两个最大的不同就是它的标签可以同时属于多个类别,即属于多分类且每个类别之间不互斥的情形(例如识别图片中的多个动物,那么有几个动物就有几个类别),而后两个函数的每一个标签只表示一个类别,即属于多分类且类别之间互斥的情形(例如手写数字识别,每一个数据只能属于一个类别)

batch_size=5
num_classes=3
logits=np.random.randn(batch_size,num_classes)
assert logits.shape==labels.shape==(batch_size,num_classes)
def sigmoid(x):
    return 1.0/(1+np.exp(-x))
#注意标签,有的标签属于多个类别
labels=np.array([
    [1,0,1],
    [0,1,0],
    [1,0,0],
    [0,0,1],
    [1,0,1]
])
tf_result=tf.nn.sigmoid_cross_entropy_with_logits(logits=logits,labels=tf.cast(labels,dtype=tf.float64))
tf_result=tf.reduce_mean(tf_result)
sigmoid_logits=sigmoid(logits)
np_result=np.sum(-(labels*np.log(sigmoid_logits)+(1-labels)*np.log(1-sigmoid_logits)))/(batch_size*num_classes)
可以打印tf_result和np_result的结果,是一样的。

在这里插入图片描述

tf.nn.softmax_cross_entropy_with_logits

函数的计算方式就是对输出值先算softmax,然后与真实值做交叉商运算。
logits是形状为(batch_size,num_classes)的张量,softmax的计算方式是对每一行(因为每一行每一个数值代表一个数据预测属于哪一类的得分值)做形如下列式子的运算:eveciieveci\displaystyle \frac{e^{vec_i}}{\sum_ie^{vec_i}},vecvec就是数据的每一行。
交叉商的计算方式是:labelslog(logits),logits-labels*log(logits),logits是经过softmaxsoftmax的。

def softmax(tensor):
    sum_exp=np.sum(np.exp(tensor),axis=-1)
    new_result=np.ones_like(tensor)
    for i in range(tensor.shape[0]):
        new_result[i]=np.exp(tensor[i])/sum_exp[i]
    return new_result

tf_result=tf.nn.softmax_cross_entropy_with_logits(logits=logits,labels=labels)
tf_result=tf.reduce_mean(tf_result)
softmax_logits=softmax(logits)
np_result=np.sum(-labels*np.log(softmax_logits))/batch_size
#注意与sigmoid_cross_entropy_with_logits的不同,它的返回结果是形状为(batch_size,)的张量
#每一个数值表示当前这个batch中的每一个数据属于哪一类的loss值,注意它只能属于一个类别
#而sigmoid_cross_entropy_with_logits返回的形状为(batch_size,num_classes)的张量,每一个数值表示当前这个batch中每一个数据属于每一类的loss值。

在这里插入图片描述

sparse_softmax_cross_entropy_with_logits

它也叫做稀疏交叉商,与上一个的不同之处在于输入的标签。
在softmax_cross_entropy_with_logits中输入的logits和labels有相同的shape和dtype。
而在稀疏交叉商中,如果logits的shape是[batch_size,num_classes],那么labels的形状是[batch_size],类型是int型,每一个数值的取值范围就是[0,num_classes),代表每一个数据对应的类别。如果logits的shape是[batch_size,time_step,num_classes],那么labels的形状是[batch_size,time_step],同样的,dtype必须是int类型,取值范围是[0,num_classes),表示的意思是batch_size个数据中每一个数据属于哪一类,例如在命名实体识别中,就代表在当前的batch_size个句子中,每个句子的每一个单词属于哪一个标签。

batch_size=2
time_step=3
num_classes=3
logits=np.random.randn(batch_size,time_step,num_classes)
labels=np.array([
    [[0,0,1],
    [0,1,0],
    [0,1,0]],
    
    [[0,0,1],
    [1,0,0],
    [1,0,0]]
])
labels_sparse=np.array([
    [2,1,1],#代表的意思是属于第三个类别,第二个类别,第二个类别
    [2,0,0]#代表的意思是属于第3个类别,第1个类别,第一个类别
])
res1=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,labels=labels_sparse)
res2=tf.nn.softmax_cross_entropy_with_logits(logits=logits,labels=labels)

在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!