『TensorFlow』分类问题与两种交叉熵

时间:2022-09-16 02:04:25

关于categorical cross entropy 和 binary cross entropy的比较,差异一般体现在不同的分类(二分类、多分类等)任务目标,可以参考文章keras中两种交叉熵损失函数的探讨,其结合keras的API讨论了两者的计算原理和应用原理。

本文主要是介绍TF中的接口调用方式。

一、二分类交叉熵

对应的是网络输出单个节点,这个节点将被sigmoid处理,使用阈值分类为0或者1的问题。此类问题logits和labels必须具有相同的type和shape

原理介绍

x = logits, z = labels.
logistic loss 计算式为:
其中交叉熵(cross entripy)基本函数式

z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))
    = z * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x)))
    = z * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x)))
    = z * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x))
    = (1 - z) * x + log(1 + exp(-x))
    = x - x * z + log(1 + exp(-x))

对于x<0时,为了避免计算exp(-x)时溢出,我们使用以下这种形式表示

x - x * z + log(1 + exp(-x))
    = log(exp(x)) - x * z + log(1 + exp(-x))
    = - x * z + log(1 + exp(x))

综合x>0和x<0的情况,并防止溢出我们使用如下公式,

max(x, 0) - x *z + log(1 + exp(-abs(x)))

接口介绍

import numpy as np
import tensorflow as tf input_data = tf.Variable(np.random.rand(1, 3), dtype=tf.float32)
# np.random.rand()传入一个shape,返回一个在[0,1)区间符合均匀分布的array output = tf.nn.sigmoid_cross_entropy_with_logits(logits=input_data, labels=[[1.0, 0.0, 0.0]])
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))
# [[ 0.5583781 1.06925142 1.08170223]]

二、多分类交叉熵

对应的是网络输出多个节点,每个节点表示1个class的得分,使用Softmax最终处理的分类问题。

原理介绍

cross_entropy = -tf.reduce_mean(y * tf.log(tf.clip_by_value(y_pre, 1e-10, 1.0))

调用一下:

import tensorflow as tf

input_data = tf.Variable([[0.2, 0.1, 0.9], [0.3, 0.4, 0.6]], dtype=tf.float32)
labels=tf.constant([[1,0,0], [0,1,0]], dtype=tf.float32) cross_entropy = -tf.reduce_mean(labels * tf.log(tf.clip_by_value(input_data, 1e-10, 1.0))) with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))

接口介绍

softmax之后,计算输出层全部节点各自的交叉熵(输出向量而非标量)

cross_entropy_mean = tf.reduce_mean(
tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=tf.argmax(labels,1), logits=logits), name='cross_entropy') cross_entropy_mean = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(
logits=logits, labels=labels), name='cross_entropy')

tf.nn.softmax_cross_entropy_with_logits()

函数的参数label是稀疏表示的,比如表示一个3分类的一个样本的标签,稀疏表示的形式为[0,0,1]这个表示这个样本为第3个分类,而非稀疏表示就表示为2,同理[0,1,0]就表示样本属于第2个分类,而其非稀疏表示为1。

import tensorflow as tf

input_data = tf.Variable([[0.2, 0.1, 0.9], [0.3, 0.4, 0.6]], dtype=tf.float32)
output = tf.nn.softmax_cross_entropy_with_logits(logits=input_data, labels=[[1,0,0],
[0,1,0]])
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))

tf.nn.sparse_softmax_cross_entropy_with_logits()

此函数大致与tf.nn.softmax_cross_entropy_with_logits的计算方式相同,
适用于每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象

但是在对于labels的处理上有不同之处,labels从shape来说此函数要求shape为[batch_size],
labels[i]是[0,num_classes)的一个索引, type为int32或int64,即labels限定了是一个一阶tensor,
并且取值范围只能在分类数之内,表示一个对象只能属于一个类别

import tensorflow as tf

input_data = tf.Variable([[0.2, 0.1, 0.9], [0.3, 0.4, 0.6]], dtype=tf.float32)
output = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=input_data, labels=[0, 2])
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))
# [ 1.36573195 0.93983102]

比tf.nn.softmax_cross_entropy_with_logits多了一步将labels稀疏化的操作。因为深度学习中,图片一般是用非稀疏的标签的,所以tf.nn.sparse_softmax_cross_entropy_with_logits()的频率比tf.nn.softmax_cross_entropy_with_logits高。

不过两者输出尺寸等于输入shape去掉最后一维(上面输入[2*3],输出[2]),所以均常和tf.reduce_mean()连用。

『TensorFlow』分类问题与两种交叉熵的更多相关文章

  1. 『TensorFlow』SSD源码学习&lowbar;其一:论文及开源项目文档介绍

    一.论文介绍 读论文系列:Object Detection ECCV2016 SSD 一句话概括:SSD就是关于类别的多尺度RPN网络 基本思路: 基础网络后接多层feature map 多层feat ...

  2. 『TensorFlow』模型保存和载入方法汇总

    『TensorFlow』第七弹_保存&载入会话_霸王回马 一.TensorFlow常规模型加载方法 保存模型 tf.train.Saver()类,.save(sess, ckpt文件目录)方法 ...

  3. 『TensorFlow』分布式训练&lowbar;其三&lowbar;多机分布式

    本节中的代码大量使用『TensorFlow』分布式训练_其一_逻辑梳理中介绍的概念,是成熟的多机分布式训练样例 一.基本概念 Cluster.Job.task概念:三者可以简单的看成是层次关系,tas ...

  4. 『TensorFlow』专题汇总

    TensorFlow:官方文档 TensorFlow:项目地址 本篇列出文章对于全零新手不太合适,可以尝试TensorFlow入门系列博客,搭配其他资料进行学习. Keras使用tf.Session训 ...

  5. 『TensorFlow』滑动平均

    滑动平均会为目标变量维护一个影子变量,影子变量不影响原变量的更新维护,但是在测试或者实际预测过程中(非训练时),使用影子变量代替原变量. 1.滑动平均求解对象初始化 ema = tf.train.Ex ...

  6. 『TensorFlow』流程控制

    『PyTorch』第六弹_最小二乘法对比PyTorch和TensorFlow TensorFlow 控制流程操作 TensorFlow 提供了几个操作和类,您可以使用它们来控制操作的执行并向图中添加条 ...

  7. 『TensorFlow』命令行参数解析

    argparse很强大,但是我们未必需要使用这么繁杂的东西,TensorFlow自己封装了一个简化版本的解析方式,实际上是对argparse的封装 脚本化调用tensorflow的标准范式: impo ...

  8. 『TensorFlow』SSD源码学习&lowbar;其五:TFR数据读取&amp&semi;数据预处理

    Fork版本项目地址:SSD 一.TFR数据读取 创建slim.dataset.Dataset对象 在train_ssd_network.py获取数据操作如下,首先需要slim.dataset.Dat ...

  9. 『TensorFlow』读书笔记&lowbar;降噪自编码器

    『TensorFlow』降噪自编码器设计  之前学习过的代码,又敲了一遍,新的收获也还是有的,因为这次注释写的比较详尽,所以再次记录一下,具体的相关知识查阅之前写的文章即可(见上面链接). # Aut ...

随机推荐

  1. 开刷LeetCode

    还是觉得自己在算法这块太弱鸡了 不多废话开刷吧,LeetCode与算法导论相辅相成双管齐下,期望能填上算法这个坑 解法没意外都是用Python2.7 由于LeetCode有提供Top Solution ...

  2. Openbox简单支持平铺

    使用和gnome shell同样的热键定义 rc.xml中 <keybind key="W-Up"> <action name="Maximize&qu ...

  3. fiddler 命令

    Fiddler内置的命令有如下几种: 1. select命令. 选择所有相应类型(指content-type)为指定类型的HTTP请求,如选择图片,使用命令select image.而select c ...

  4. JS valueOf与字符串

    js在处理字符串和数值加运算的时候会转换数值为字符串 然后执行字符串连接 在覆盖String.prototype.valueOf之前,new String(111)这样的字符串与数值加法也是字符串连接 ...

  5. OSI

    1.物理(硬:HUB位) *****************信道接口型状.尺寸.引脚.排列电压.电流.阻抗.波形.速率及平衡单.半双.全双工RS232,RS422,RS423,RS485X.25.X. ...

  6. 指针强转和void&ast;

    C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值.不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的 ...

  7. MySQL 建表字段长度的限制

    脑补,varchar(N),N指的是最大字符数,不是字节数. 先上测试说明:   在MySQL建表时,遇到一个奇怪的现象: root@localhost : test 10:30:54>CREA ...

  8. &lbrack;LeetCode&rsqb;题解(python):097-Interleaving String

    题目来源: https://leetcode.com/problems/interleaving-string/ 题意分析: 给定字符串s1,s2,s3,判断s3是否由s1和s2穿插组成.如“abc” ...

  9. SpringBoot cache-control 配置静态资源缓存 (以及其中的思考经历)

    昨天在部署项目时遇到一个问题,因为服务要部署到外网使用,中间经过了较多的网络传输限制,而且要加载arcgis等较大的文件,所以在部署后,发现页面loading需要很长时间,而且刷新也要重新从服务器下载 ...

  10. Java NIO 概览

    Java面试通关手册(Java学习指南) Github地址:https://github.com/Snailclimb/Java_Guide 一 NIO简介 Java NIO 是 java 1.4 之 ...