当前位置: 首页 > Tensorflow, 神经网络 > 正文

交叉熵实例,Tensorflow交叉熵函数

目 录
 [ 隐藏 ]

1. 概述

学习Tensorflow关于交叉熵的计算方法时:

  • tf.nn.sparse_softmax_cross_entropy_with_logits
  • tf.nn.softmax_cross_entropy_with_logits

需要弄清楚这两个方法的差异,以及方法内部的细节,即这个方法是如何计算出来交叉熵的. 因此,使用一个具体的例子来说明.

上述两个方法有两个主要参数logitslabels. logits 是神经网络前向传播完成以后的计算结果.

注意 不要再logits上应用softmax.因为上面两个函数会使用更高效的方式计算softmax和cross entropy.

labels是训练数据的标签.

2. 实例

上面的两个计算交叉熵的方法一般用于单分类问题(一个图片只能属于一个类别)的损失函数.

假如有个图片识别问题,一张图片只可能属于狗,猫,兔之一,对于下面这个训练图片,其结果是,
因此这个训练数据的label格式为 0,1,0,而神经网络的前向传播计算结果logit可能为0.1, 0.8, 0.2.

猫

综合上面的labellogit可得如下表格:

item
label 0 1 0
logit 0.1 0.8 0.2

3. 计算公式

上面两个计算交叉熵的方法中,涉及到两个函数softmax和cross_entropy, 下面分别说明这两个函数的计算方法.
为简化说明,直接给出计算公式,避免用抽象的数学表达语言.

3.1. softmax

softmax 是将 数组[a, b, c] 变换成概率分布,假如转换完成后得到数组[A,B,C]满足:

  1. A,B,C都在0和1之间,
  2. A+B+C=1成立

则A,B,C就是一种概率分布.

对于[a, b, c] 求softmax的公式为:
$$ softmax = \left[ \frac{e^a}{e^a + e^b + e^c}, \; \frac{e^b}{e^a + e^b + e^c}, \; \frac{e^c}{e^a + e^b + e^c} \right]$$
其中$e$是自然底数.

3.2. cross entropy

假设$label=[l_1,l_2,l_3]$, $logits=[a,b,c]$, 则交叉熵计算公式如下:

  1. 计算 logitssoftmax $softmax([a,b,c]) = [S_a,S_b,S_c]$;
  2. 计算的softmax的对数(以$e$为底的 ) $log([S_a,S_b,S_c]) = [LS_a],LS_b,LS_c]$;
  3. 计算cross entropy $cross entropy = -(l_1 \times LS_a + l_2 \times LS_b + l_3 \times LS_c)$.

4. 代码实现

下面给出Python的实现代码, 以及和Tensorflow自带的方法的计算结果对比.

NOTE: 概述部分给出的两个函数的区别在于参数labels的形式. 假如labels=[0,1,0]sparse开头的方法,
传给labels参数的是数组([0,1,0])中1的位置,即1(从0开始的),这也是下面tf.argmax方法的功能.
因为sparse表示label是稀疏的,只有一个1,其他都是0,知道了1的位置就可以构造这个数组了.

#!/usr/bin/env python3

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as skDs
import sklearn as skl
import tensorflow as tf_old

tf = tf_old.compat.v1
logit = [0.1, 0.8, 0.2]
label = [0, 1, 0]

def softmax(X):
    total_exp = 0.0
    xLen = len(X)
    y = np.zeros(xLen)
    for i in range(xLen):
        exp = np.exp(X[i])
        y[i] = exp
        total_exp += exp
    y = y / total_exp
    return y

def cross_entropy(logit_, label_):

    the_label = label_

    current_output_softmax = softmax(logit_)

    current_output_softmax_log = np.log(current_output_softmax)

    result = - np.sum(the_label * current_output_softmax_log)
    return result

def main():
    y = tf.constant([logit])
    y_ = tf.constant([label])
    cross_entropy1 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
    cross_entropy2 = tf.nn.softmax_cross_entropy_with_logits(logits=y, labels=y_)

    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        print(sess.run(cross_entropy1))
        print(sess.run(cross_entropy2))

if __name__ == '__main__':
    main()
    # main的输出结果为
    # [0.7155919]
    # [0.7155919]
    print(cross_entropy(logit, label))
    # 输出结果为 -0.7155918732927512

5. 参考链接

赞 赏

   微信赞赏  支付宝赞赏


本文固定链接: https://www.jack-yin.com/coding/ml/dl/3146.html | 边城网事

该日志由 边城网事 于2019年09月24日发表在 Tensorflow, 神经网络 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 交叉熵实例,Tensorflow交叉熵函数 | 边城网事

交叉熵实例,Tensorflow交叉熵函数 暂无评论

发表评论

快捷键:Ctrl+Enter