图像分割——交叉熵损失

news2024/11/25 0:07:49

一、前言

写这篇博客的目的主要有两点,首先一点就是,以为对于交叉熵学过就会了,当初笔记也没有详细写过,但今天看论文发现里面的公式没有看懂才发现自己了解的还不够,平时用也是直接用的框架,原来一直认为会的东西其实还不会。还有一点原因就是对于语义分割任务使用交叉熵基本是固定的,但是我并不知道为什么使用交叉熵来作为损失函数,因此写下来笔记来加深对交叉熵的理解。

二、语义分割——MSE  and Cross entropy

2.1什么是MSE

MSE为均方差损失函数,均方差是求一个batch中n个样本的n个输出与期望输出的差的平方的平均值

例如:对于n个样本中有:

 MSE = \frac{\sum_{i = 1}^n(Y_i - \hat{Y_i}) ^2}{n} 

 2.2.什么是熵,交叉熵,也即Cross entropy

2.2.1.什么是熵?

       熵代表着混乱程度、不确定性、不可预测性、信息量。熵是由香农在考虑无损信息编码时提出,目的是为了寻找一种既高效又无损的信息编码方式,简单来说熵就是:无损编码事件信息的最小平均编码长度。

2.2.2.什么是最小无损平均编码长度?

       我们先来看编码怎么是怎么传递信息的,假设我们要传递东京的天气信息好坏给纽约,我们可以打一段话直接告诉纽约那边这边天气很好或者不好,但是这样一段话编码的信息是很长的,事实上我们也没有必要打一大段话来传递信息,因为对于双方来说都知道传递的信息是关于东京的天气的。这样看来我们可以直接用好/不好来传递,这样似乎也不是最短的,再进一步缩减我们可以用Y/N来传递天气好坏,但好像已经很简单了,都只用了一个字母,然而字母本质还是0/1编码来传递的,还是不够短。最后不难想到我们想要传递东京的天气好坏直接用0/1这两个数字就足够传递信息了,因此对于这个例子最小平均编码长度事实上为(1 + 1)/2 = 1。

上面的例子是只传递两种天气,那对于更多的天气该怎么编码呢,例如我们要同时传递fine/snow/cloudy/Rainy四种信息该怎么编码呢,一个比特0/1只能传递两种信息,对于四种信息,不难想到两个比特恰好可以传递四种信息,编码可以为00/01/10/11,平均编码长度为(2 +2 +2 +2 )/ 4 = 2 ,但这是当我们要传递的四种天气信息概率相等得到的,对于天气概率不相等的情况下,这么编码还是不是最小的。例如,假设我们要传递的天气概率分别为下表:

fine

snow

cloudy

rainy

50%

12.5%

25%

12.5%

假设我们依旧使用上面的编码方式00/01/10/11,这样得到的平均编码长度为0.5 * 2 + 0.25 * 2 + 0.125 * 2 + 0.125 * 2 = 2,但是这样并不是最短的平均编码长度。

而如果我们使用0来代表fine,10代表cloudy,111代表snow,110代表rainy,这样编码没有歧义,也没有多余的编码,因此这样的平均编码长度为:0.5 * 1 + 0.25 * 2 + 0.125 * 3 + 0.125 * 3 = 1.75 < 2可以看到这样的编码方式优于2位比特的编码方式。

2.2.3.那么在已知事件概率分布的情况下,如何编码才能得到最短平均编码长度呢,也就是如何才能得到熵?

假设我们有八种信息需要传递,他们的概率都为1/8,不难想到最短编码长度的方式就是使用3个比特来传递信息分别为:000/001/010/011/100/101/110/111,那熵(平均最小编码长度)计算则为3 * 0.125 * 8 = 3

推广到更普遍的情况如果我们要传递n种信息,则需要log(N)数目的比特来编码,然后概率都为1/N = P,这样计算熵有:

 Entorpy = \sum_{i = 1}^{n} log_2^{N} * P(i)= \sum_{i = 1}^{n} log_2^{\frac{1}{P(i)}} * P(i)= -\sum_{i = 1}^{n} log_2^{P(i)} * P(i)

这就是熵的计算公式的由来,我们回过头来看前面传递四种天气的例子,熵事实上是这样得到的:Entropy = -( log(0.5) * 0.5 + log(0.25) * 0.25 + log(0.125) * 0.125 + log(0.125) * 0.125) = 1.75,这也是这个例子的最短编码长度。

因此我们得到了求最小编码长度也即熵得方法,只需要知道事件的概率分布,由公式:

Entorpy = -\sum_{i=1}^{n}log_2^{P(i)} * P(i)

则可以计算得到,而仔细看这个公式为什么可以得到最小编码长度:主要还是它把概率大的信息用更短的编码来表示,不难证明得到的就是最小的平均编码长度,主要还是基于贪心算法,与哈夫曼编码很相似

2.2.4怎么理解熵可以代表混乱度、不确定性,信息量呢?

可以这样理解:对于同样的一个事件,概率分布的不同,熵也就不同,熵越大,代表事件概率分布的越平均,这样不确定性就增大了,混乱度也增大了,我们就很难对其准确预测,例如天气分布如果为7/8, 1/24, 1/24, 1/24以及1/4,1/4,1/4,1/4这样我们可以计算熵:前者为-(log(7/8) * 7/8 + 3 * log(1/24) * 1/24) = 0.74, 后者为2,可以看到熵越大分布更平均,也就预测的结果不确定性更大。

而信息量可以这样理解,当一个概率更低的事件发生时,它可以帮我们排除掉更多的可能性,信息熵是用来衡量事物的不确定性的,信息熵越大,则不确定性越大

2.2.5.那什么是交叉熵?

交叉熵是用来评估当前训练得到的概率分布与真实分布的差异情况。 它刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近

熵的计算是在给定概率分布得到的,但是很多时候交叉熵是用在机器学习里面的loss,这时我们并不知道概率分布,但是我们可以得到预测的概率分布来估计熵,由此引出了交叉熵的概念,我们可以假设Q为预测的概率分布,则估计熵为

-\sum_{i=1}^{n}log_2^{Q(i)}*Q(i)

但是Q是预测的概率分布,这可能与实际的概率分布P偏差很远,这就达不到我们用这个来估计的目的了,在使用交叉熵作为loss时,我们可以使用真实的观测概率分布P也即真实值与对应的预测概率Q预测值来计算,这样才能在训练的时候来拟合概率分布,因此就有了交叉熵公式

Cross entropy = -\sum_{i=1}^{n}log_2^{Q(i)}*P(i)

因为熵是最小的理论编码长度,因此交叉熵是大于等于熵

2.2.6.为什么可以交叉熵可以作为训练的损失函数?

在训练时,我们往往会把输出转换为one-hot编码,例如可以有一个三分类的真实标签如下,有两个预测分布分别为Q1 = [0.9, 0.05, 0.05]和Q2[0.4, 0.3, 0.3]则可以分别得到交叉熵为cross entropy1 = -1 * log 0.9 = 0.15而cross entropy2 = -1 * log0.4 = 1.32,可以看到第二个交叉熵远远大于第一个,可见预测结果分布越准确,交叉熵越小,因此交叉熵可以作为损失函数。

cat

dog

pig

[1, 0, 0]

[0, 1, 0]

[0, 0, 1]

强烈建议看看参考博客里面这两篇文章,结合起来看写的很透彻!

Entropy Demystified. Is it a disorder, uncertainty or… | by Naoki | Medium

一文搞懂熵(Entropy),交叉熵(Cross-Entropy) - 知乎 (zhihu.com)

 2.3语义分割使用交叉熵作为损失函数的原因

2.3.1交叉熵权重更新更快

交叉熵往往都是用来替代均方差MSEsigmoid的组合,对于二分类的损失函数又有

L = -[(y * log^{\hat{y}})+(1-y)*log^{1-\hat{y}}]

sigmoid损失函数:

sigmoid = \frac{1}{1+e^{-z}}

有其图像及其导数图像如下:

画图代码:

import matplotlib.pyplot as plt

import numpy as np

def sigmoid(x):

    y = 1.0/(1 + np.exp(-x))

    return y

def show_sigmoid_and_sigmoid_derivative(x, y1, y2):

    plt.plot(x, y1, label = "sigmoid")

    plt.plot(x, y2, color = "red", label = "sigmoid deactivate")

    plt.axhline(1, color = 'blue', label = "y = 1")

    plt.axhline(0.5, color = "green", label = "y = 0.5")

    plt.legend(loc = "best")

    plt.title("sigmoid and sigmoid_derivative", loc="right")

    plt.xlabel("x", loc='right')

    plt.ylabel("y", loc='top')

    ax = plt.gca() # 获得当前轴

    ax.spines['left'].set_position(('data', 0))

    ax.spines['right'].set_color("None")

    ax.spines['top'].set_color("None")

    plt.savefig("sigmoid.jpg")

    plt.show()

   

def sigmoid_derivative(x):

    y = np.exp(-x) / np.power((1 + np.exp(-x)), 2)

    return y



if __name__ =='__main__':

    x = np.arange(-7, 7, 0.2)

    y1 = sigmoid(x)

    y2 = sigmoid_derivative(x)

    show_sigmoid_and_sigmoid_derivative(x, y1, y2)

   

对于sigmoid函数,x越大或者越小,导数趋于0

对于单个样本,我们可以这样假设:

其中前两步为前向传播,后面L1为均方差损失,L2为交叉熵损失,w,b为权重,σ为激活函数sigmoid,对于权重更新有:

对于均方差损失的偏导数有:

分析:在z很大或者很小的区间,预测值接近1,两个偏导数都比较小,这样会导致参数更新比较慢,收敛自然就变慢了

同时当真实值为1的时候,预测值为10导数都为0真实值为0的时候,预测值为10导数也为0,理论上在梯度下降会采取缩小学习率的方式来减小步长,但是在梯度很小的时候,网络并不知道这时候离真实值远还是近,所以这也是不采用MSE的原因

对于交叉熵的偏导数有:

分析:这时候梯度主要受预测值与真实值的差来决定,差越大梯度越大,参数更新越快,差越小,梯度越小参数更新更慢

四、交叉熵的计算

对于图像分割一个训练集,我们需要寻找参数w ̂使得Loss最小,也即

N为训练集图片数量,𝑥(𝑛), 𝑦(𝑛)为图片与真实值的配对,代表第几张图片,对于每一张图片的Loss有

其中𝛺𝑝为每张图所有像素构成的空间,i指每一个像素,𝑦𝑖𝑗代表该位置上j类别的真实值,k表示分割的k个类别。

为在该像素位置上j类别的的预测概率

𝑎𝑗(𝑥𝑖)为该像素位置上激活函数输出的值,一般情况下,我们都需要对激活函数的输出做softmax处理来使预测值在[0,1]之间,所以P其实就是对应类别的可能性。

4.1多通道交叉熵的计算

如图为1个三通道的交叉熵的计算,对于输出的每个像素上的值,我们先计算softmax值,得到对应的每个类别的概率,与标签的onehot编码进行计算得到交叉熵

参考博客

语义分割单通道和多通道输出交叉熵损失函数的计算问题 - GShang - 博客园 (cnblogs.com)

【超详细公式推导】关于交叉熵损失函数(Cross-entropy)和 平方损失(MSE)的区别 - 知乎 (zhihu.com)

最详细的语义分割---07交叉熵到底在干什么?_语义分割交叉熵损失函数怎么算_正在学习的浅语的博客-CSDN博客

Entropy Demystified. Is it a disorder, uncertainty or… | by Naoki | Medium

一文搞懂熵(Entropy),交叉熵(Cross-Entropy) - 知乎 (zhihu.com)

为什么用交叉熵做损失函数 - 知乎 (zhihu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/424279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基础--数据结构

阅读目录 目录 数据结构 Java 集合框架 List Set Map 数据结构 Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类&#xff1a; 枚举&#xff08;Enumeration&#xff09;、位集合&#xff08;BitSet&#xff09;、向量&#xff08;Vector&a…

进阶C语言:程序环境和预处理

有关C语言的知识马上就要结束了&#xff0c;在学完了前面的基础之上我们就来深究一下程序底层的逻辑&#xff0c;关于程序的预处理编译指令&#xff0c;话不多说&#xff0c;我们直接开始&#xff1a; 目录 1.程序的翻译环境和执行环境 2. 详解编译链接 2.1翻译环境 2.2编译…

IT培训有靠谱的机构吗,长什么样的?

关于IT培训的问题&#xff0c;网上有一大波劝退的声音&#xff1a;现在的IT越来越卷&#xff0c;高校计算机专业毕业生每年那么多&#xff0c;作为小白转行的你竞争力又在哪里呢&#xff1f;而且去年互联网大厂那么多裁员&#xff0c;还有大幅度降薪等等&#xff0c;IT行业已经…

通达信破底翻选股公式,用缠论底分型进行优化

上次在写《通达信破底翻形态选股公式&#xff0c;选出破底之后再翻回的股票》这篇文章时&#xff0c;编写破底翻选股公式就考虑使用缠论底分型&#xff0c;但是底分型的包含关系较为复杂&#xff0c;不容易处理&#xff0c;只能暂时搁置&#xff0c;采用了一种简单的方式&#…

【PyTorch】第九节:Softmax 函数与交叉熵函数

作者&#x1f575;️‍♂️&#xff1a;让机器理解语言か 专栏&#x1f387;&#xff1a;PyTorch 描述&#x1f3a8;&#xff1a;PyTorch 是一个基于 Torch 的 Python 开源机器学习库。 寄语&#x1f493;&#xff1a;&#x1f43e;没有白走的路&#xff0c;每一步都算数&#…

低延迟流式语音识别技术在人机语音交互场景中的实践

美团语音交互部针对交互场景下的低延迟语音识别需求&#xff0c;提出了一种全新的低出字延迟流式语音识别方案。本方法将降低延迟问题转换成一个知识蒸馏过程&#xff0c;极大地简化了延迟优化的难度&#xff0c;仅通过一个正则项损失函数就使得模型在训练过程中自动降低出字延…

靶机精讲之Holynix

找不到ip 就设置两个网络适配器 再添加一个NAT 主机发现 nmap扫描 端口扫描 UDP扫描 服务扫描 脚本扫描 拒绝服务攻击 sql注入 枚举 web渗透 sql注入 证明有注入 sql注入语句 语句 ‘ or 11 --&#xff08;空格&#xff09; 目录结构像有文件包含 有报错但无法利用 调用系统…

从零开始学架构-计算高性能

一、概述 高性能是每个程序员的追求&#xff0c;无论做一个系统、还是写一组代码&#xff0c;都希望能够达到高性能的效果。而高性能又是最复杂的一环&#xff0c;磁盘、操作系统、CPU、内存、缓存、网络、编程语言、数据库、架构等&#xff0c;每个都可能影响系统的高性能&…

ChatGPT API接口使用+fine tune微调+prompt介绍

目录1 接口调用1.1 生成key1.2 接口功能1.2.1 图片生成 (image generation)1.2.2 对话(chat)1.2.3 中文纠错 (Chinese Spelling Correct)1.2.4 关键词提取 &#xff08;keyword extract)1.2.5 抽取文本向量 (Embedding)1.2.6 微调 (fine tune)2 如何写好prompt2.1分类任务2.2 归…

工业智能网关应用场景:高层楼宇智慧消防解决方案

随着城市化建设的飞速发展&#xff0c;人员聚集与土地资源稀缺的矛盾越来越明显。为了让有限的空间满足更多人的居住需求&#xff0c;高层楼宇越来越多&#xff0c;对于安全消防形成更大的挑战。 基于物联网和云计算平台的智慧消防在消防管理、火灾报警和实时监管方面发挥越来…

java内部类入门(接口)

我有一个玩具狗&#xff0c;有一个接口用于启动它&#xff0c;按照传统方法就是写一个类并实现该接口&#xff0c;且该类只使用一次&#xff08;在启动时使用&#xff0c;后面再不使用&#xff09; 但是如果我有一堆玩具&#xff0c;我每个玩具都要去写一个类来实现start这个接…

GPT-3.5还没研究明白,GPT-4又来了,chatGPT会进化成什么样?

基于GPT-3.5的chatGPT热度才稍稍减退没多久&#xff0c;GPT-4又来了&#xff0c;文新一言的发布会也槽点满满&#xff0c;差距似乎越来越大了。 chatGPT到底厉害在哪&#xff1f;为什么突然就爆火了呢&#xff1f; 它的爆火&#xff0c;一方面&#xff0c;和它的出现形态有关…

代码随想录第18天 | 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 var getMinimumDifference function (root) {//中序遍历法&#xff1a;左中右let res []if (!root) return res;const st [root] //栈&#xff0c;pop(),push()while (st.length) {let x st.pop()if (!x) {res.push(st.pop().val)continue}if (…

Linux环境下搭建composer私服及memory_limit问题

Composer是 PHP项目中用来管理依赖&#xff08;dependency&#xff09;关系的工具&#xff0c;允许声明项目所依赖的代码库 &#xff0c;然后在项目的某个目录中(默认是vendor目录) 中安装相关的依赖包。 在介绍如何安装私服之前&#xff0c;我们先熟悉下 composer 相关 compo…

对话框与子窗口控件(写给大忙人看的快速复习掌握)

对话框与子窗口控件&#xff08;写给大忙人看的快速复习掌握&#xff09;1、对话框的概念2、控件的概念我更喜欢称控件为预定义的窗口类3、我们一步一步写代码熟悉常用的预定义的窗口类3.1 什么叫模板呢&#xff1f;3.2 什么是资源文件4、消息处理函数&#xff08;有这么几个消…

护眼灯哪些牌子好?2023护眼灯品牌推荐

护眼灯就是保护眼睛的&#xff0c;很多人长时间工作和学习&#xff0c;主要还是光的刺激和错误的坐姿&#xff0c;会引起眼睛的近视&#xff0c;导致视觉疲劳的主要原因就是灯光的频闪&#xff0c;而护眼灯就能很好减少频闪。 特别是青少年们的视力发育为成熟&#xff0c;视力…

使用Sentieon加速甲基化WGBS数据分析

全基因组甲基化测序(WGBS)是一种研究DNA甲基化的方法&#xff0c;以全面了解在基因组水平上的表观遗传变化。在进行WGBS数据分析时&#xff0c;通常需要使用专门的比对工具&#xff0c;因为这些工具需要能够处理亚硫酸盐转化后的数据。 以下是四个不同的WGBS比对分析流程&…

ADIDAS阿里纳斯励志广告语

系列文章目录 精选优美英文短文1——Dear Basketball&#xff08;亲爱的篮球&#xff09;精选优美英文短文2——Here’s to the Crazy Ones&#xff08;致疯狂的人&#xff09;“我祝你不幸并痛苦”——约翰罗伯茨毕业致辞“亲爱的波特兰——CJ麦科勒姆告别信” Hi, I’m Gilb…

七、Django进阶:第三方库Django-extensions的开发使用技巧详解(附源码)

Django-extensions是 Django 的扩展应用&#xff0c;给django开发者提供了许多便捷的扩展工具(extensions)&#xff0c;它提供了许多有用的工具和命令行工具&#xff0c;帮助 Django 开发者更高效地进行开发和调试。它的作用包括&#xff1a; - 提供了更多的Django命令&#x…

循环依赖详解及解决方案

介绍 上图就是循环依赖的三种情况,虽然方式不同,但是循环依赖的本质是一样的,就A的完整创建要依赖与B,B的完整创建要依赖于A,相互依赖导致没办法完整创建造成失败. 循环依赖代码演示 public class Demo {public static void main(String[] args) {new Demo1();} }class Demo1…