在深度学习中,损失函数用来评估模型的预测值与真实值之间的差异程度,是模型对数据拟合程度的反映,拟合的越差,损失函数的值越大;反之,损失函数越小,说明模型的预测值就越接近真实值,模型的准确性也就越好。深度学习的模型训练的目标就是使损失函数的值尽可能小。因此损失函数又被称为目标函数。深度学习的模型训练的过程就是不断地最小化损失函数。选择适合的损失函数不仅影响最终预测的准确性,而且影响训练的效率。

      常用的损失函数包括:最小均方差损失函数、L1范数损失函数、L2范数损失函数、交叉熵损失函数等。

      1948年,香农提出了信息熵的概念,并且发展为一门独立的学科,即信息论。香农将平均自信息量定义为信息熵,简称为熵。在信息论中,信息熵是为了消除不确定性所需的度量,为了验证概率低的事件,需要大量的信息,此时的信息熵很大;相反,为了验证概率高的事件,则需要少量的信息,此时的信息熵很小。

      交叉熵用于度量分布之间的信息差异。交叉熵是信息论中的重要概念,熵是对不确定问题的度量准则,而交叉熵是信息论领域的一种度量,建立在熵的基础上,通常是用来度量两个概率分布之间信息的差异。

      最小化交叉熵的过程也就是极大似然估计,深度学习训练的目的,就是最小化交叉熵,使预测的数据分布与真实的数据分布尽量相同。

      交叉熵损失函数(Cross-Entropy Loss Function)通常被用来解决深度学习中的分类问题。

      对于多分类,每个样本都有一个已知的类标签(class label),概率为1.0,所有其它标签的概率为0.0。模型(model)可以估计样本属于每个类别标签的概率。然后可以使用交叉熵来计算两个概率分布之间的差异。

      如果一个分类问题具有三个类别,并且一个样本具有第一类的标签,则概率分布将为[1,0,0];如果一个样本具有第二类的标签,则它概率分布为[0,1,0]。

      PyTorch中的交叉熵损失函数的计算还包含了Softmax。Softmax能将原网络输出转变为概率形式。

      Softmax交叉熵损失函数是最常用的分类损失函数。若要将样本分为C个类别,在使用Softmax交叉熵损失时,需要将神经网络的最后一层输出设置为C,得到C个分数后输入Softmax交叉熵损失函数。

      Softmax交叉损失函数实际上分为两步:求Softmax和求交叉熵损失,其中第一步操作可以得到当前样本属于某类别的概率,然后将这些概率与实际值One-Hot向量求交叉熵,因为实际值是仅在第y个位置为1,其它部分为0,所以最终只保留了第y个位置的交叉熵。

      在深度学习样本训练的过程中,采用One-Hot形式进行标签编码,再计算交叉熵损失。在使用交叉熵损失函数的网络训练之前,需要将样本的实际值也转化为概率值形式。为达到这个目的,常用的方法为独热编码即One-Hot编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。

     Softmax的介绍参考:https://blog.csdn.net/fengbingchun/article/details/75220591

      交叉熵损失函数公式如下:来自于:https://programmathically.com/an-introduction-to-neural-network-loss-functions/

     

      N:样本数;M:类别数;y:预期结果;y hat:模型产生的结果

      交叉熵损失函数的C++实现如下:

template<typename _Tp> // y实际值; t预测值; m类别数
_Tp loss_function_cross_entropy(const _Tp* y, const _Tp* t, int m)
{_Tp loss = 0.;for (auto i = 0; i < m; ++i)loss += -y[i] * std::log(t[i]);return loss;
}

      测试代码如下:

int test_loss_function()
{
{ // only one sampleconst int classes_number = 5;std::vector<float> sample = { 0.0418, 0.0801, -1.3888, -1.9604, 1.0712 };std::vector<float> target = { 0, 0, 1, 0, 0 }; // One-Hotstd::vector<float> input(classes_number);assert(sample.size() == classes_number && target.size() == classes_number && input.size() == classes_number);fbc::activation_function_softmax(sample.data(), input.data(), classes_number);float output = fbc::loss_function_cross_entropy(target.data(), input.data(), classes_number);fprintf(stdout, "output: %.4f\n", output);
}{ // five samplesconst int classes_number = 5, samples_number = 5;std::vector<std::vector<float>> samples = {{0.0418, 0.0801, -1.3888, -1.9604, 1.0712 },{0.3519, -0.6115, -0.0325,  0.4484, -0.1736},{0.1530,  0.0670, -0.3894, -1.0830, -0.4757},{-1.3519, 0.2115, 1.2325,  -1.4484, 0.9736},{1.1230,  -0.5670, 1.0894, 1.9890, 0.03567}};std::vector<std::vector<float>> targets = {{0, 0, 0, 0, 1},{0, 0, 0, 1, 0},{0, 0, 1, 0, 0},{0, 1, 0, 0, 0},{1, 0, 0, 0, 0}};std::vector<std::vector<float>> inputs(samples_number);assert(samples[0].size() == classes_number && targets[0].size() == classes_number && inputs.size() == samples_number);float output = 0.;for (int i = 0; i < samples_number; ++i) {inputs[i].resize(classes_number);fbc::activation_function_softmax(samples[i].data(), inputs[i].data(), classes_number);output += fbc::loss_function_cross_entropy(targets[i].data(), inputs[i].data(), classes_number);}output /= samples_number;fprintf(stdout, "output: %.4f\n", output);
}return 0;
}

      执行结果如下:

      调用PyTorch接口测试代码如下:

import torch
import torch.nn as nnloss = nn.CrossEntropyLoss()input = torch.tensor([[0.0418, 0.0801, -1.3888, -1.9604, 1.0712]])
target = torch.tensor([2]).long() # target为2,one-hot表示为[0,0,1,0,0]
output = loss(input, target)
print("output:", output)data1 = [[ 0.0418,  0.0801, -1.3888, -1.9604,  1.0712],[ 0.3519, -0.6115, -0.0325,  0.4484, -0.1736],[ 0.1530,  0.0670, -0.3894, -1.0830, -0.4757],[ -1.3519, 0.2115, 1.2325,  -1.4484, 0.9736],[ 1.1230,  -0.5670, 1.0894, 1.9890, 0.03567]]
data2 = [4, 3, 2, 1, 0]input = torch.tensor(data1)
target = torch.tensor(data2)
output = loss(input, target)
print("output:", output)

      执行结果如下:可见C++实现的代码与调用PyTorch接口两边产生的结果完全一致

       GitHub

              https://github.com/fengbingchun/NN_Test

              https://github.com/fengbingchun/PyTorch_Test

损失函数之Cross-Entropy介绍及C++实现相关推荐

  1. 交叉熵损失函数(Cross Entropy Loss)

    基础不牢,地动山摇,读研到现在有一年多了,发现自己对很多经常打交道的知识并不了解,仅仅是会改一改别人的代码,这使我感到非常焦虑,自此开始我的打基础之路.如果博客中有错误的地方,欢迎大家评论指出,我们互 ...

  2. python损失函数实现_pytorch 实现cross entropy损失函数计算方式

    均方损失函数: 这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标. 很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数.因为一般损失函 ...

  3. 目标检测分类损失函数——Cross entropy、Focal loss

    一.Cross Entropy Loss 交叉熵是用来判定实际的输出与期望的输出的接近程度,刻画的是实际输出与期望输出的距离,也就是交叉熵的值越小,两个概率分布就越接近. 1. CE Loss的定义 ...

  4. 训练分类器为什么要用cross entropy loss(交叉熵损失函数)而不能用mean square error loss(MSE,最小平方差损失函数)?

    在一个人工智能群里,有人问起,训练分类器为什么要用cross entropy loss(交叉熵损失函数)而不能用mean square error loss(MSE,最小平方差损失函数)呢? 正好,在 ...

  5. TensorFlow学习笔记(二十三)四种Cross Entropy交叉熵算法实现和应用

    交叉熵(Cross-Entropy) 交叉熵是一个在ML领域经常会被提到的名词.在这篇文章里将对这个概念进行详细的分析. 1.什么是信息量? 假设是一个离散型随机变量,其取值集合为,概率分布函数为 p ...

  6. TensorFlow四种Cross Entropy算法实现和应用

    交叉熵介绍 交叉熵(Cross Entropy)是Loss函数的一种(也称为损失函数或代价函数),用于描述模型预测值与真实值的差距大小,常见的Loss函数就是均方平方差(Mean Squared Er ...

  7. 干货回顾丨TensorFlow四种Cross Entropy算法的实现和应用

    交叉熵介绍 交叉熵(Cross Entropy)是Loss函数的一种(也称为损失函数或代价函数),用于描述模型预测值与真实值的差距大小,常见的Loss函数就是均方平方差(Mean Squared Er ...

  8. 平均符号熵的计算公式_交叉熵(Cross Entropy)从原理到代码解读

    交叉熵(Cross Entropy)是Shannon(香浓)信息论中的一个概念,在深度学习领域中解决分类问题时常用它作为损失函数. 原理部分:要想搞懂交叉熵需要先清楚一些概念,顺序如下:==1.自信息 ...

  9. AAAI 2019 Oral | 把Cross Entropy梯度分布拉‘平’,就能轻松超越Focal Loss

    单阶段物体检测(One-stage Object Detection)方法在模型训练过程中始终面临着样本分布严重不均衡的问题,来自香港中文大学的研究者们在论文 Gradient Harmonized ...

  10. 为什么要返回softmax_为什么softmax搭配cross entropy是解决分类问题的通用方案?

    众所周知,softmax+cross entropy是在线性模型.神经网络等模型中解决分类问题的通用方案,但是为什么选择这种方案呢?它相对于其他方案有什么优势?笔者一直也困惑不解,最近浏览了一些资料, ...

最新文章

  1. oracle全局索引 前缀索引_Oracle 分区索引介绍和实例演示
  2. 【正一专栏】评《我的前半生》——我们需要怎样的价值观
  3. C语言函数库:动态库和静态库优缺点比较
  4. 非maven配置SpringBoot框架
  5. math 向上取整_自我说明:关于Math和File类的具体说明.
  6. C#LeetCode刷题-极小化极大
  7. /dev/mapper/centos-root 100% 虚拟机硬盘空间占满
  8. 【Java教程】dubbo源码解析-SPI机制
  9. 基于PHP+小程序(MINA框架)+Mysql数据库的共享会议室预约小程序系统设计与实现
  10. MT7628处理器介绍,MT7628芯片原理图资料
  11. **matlab subs函数**
  12. java 百度网盘上传_[Java教程]使用pcs api往免费的百度网盘上传下载文件
  13. 股票学习-量柱和k线-第三天
  14. 蓝牙Ibeacon室内定位和微信摇一摇周边原理分析
  15. VMware虚拟机中使用usb设备
  16. 元岛屋日式烤肉,这个夏天你怎可错过!
  17. 毕业后升级打怪程序人生
  18. 华为最新全面屏手机鸿蒙系统,华为P50pro最新确认:麒麟1020+立体全面屏+鸿蒙系统,这才是华为...
  19. application.yml图标不是绿色小叶子,文件格式不对,,没有Spring环境问题
  20. 【Java】动态模拟时钟

热门文章

  1. 机器学习中的聚类算法(1):k-means算法
  2. OpenCV中minAreaRect()最小外接矩形 cvBoxPoints()计算矩形顶点 RotatedRect和CvBox2D详解
  3. mysql 集群操作系统_高性能MySQL集群详解(二)
  4. Qt控件如何随着界面自适应变化
  5. 剑指offer:面试题34. 二叉树中和为某一值的路径
  6. Educational Codeforces Round 54
  7. R语言实战 - 基本统计分析(2)- 频数表和列联表
  8. [Mac] mac linux 多线程下载利器 axel
  9. [bzoj1064][Noi2008]假面舞会
  10. CSS里总算是有了一种简单的垂直居中布局的方法了