损失函数-交叉熵 梯度下降

文章目录

  • 1、交叉熵的简单例子
    • 1.2、Classification Error(分类错误率)
    • 1.3、Mean Squared Error (均方误差)
    • 1.4、交叉熵损失函数
    • 1.5、二分类
  • 2、什么是梯度下降法?
    • 2.2、梯度下降法的运行过程
    • 2.3、二元函数的梯度下降

1、交叉熵的简单例子

参考文章例子

我们希望通过图像轮廓、颜色等特征,来预测动物的类别,有三种可能类别(猫、狗、猪)假设我们现在有两个模型,都是通过sigmoid/softmax的方式得到的对每个类别预测的概率 。

模型1:
预测 真实 是否正确
0.3 0.3 0.4 0 0 1 (猪) 正确
0.3 0.4 0.3 0 1 0 (狗) 正确
0.1 0.2 0.7 1 0 0 (猫) 错误
模型1对于样本1和样本2以非常微弱的优势判断正确,对于样本3的判断则彻底错误。

模型2:
预测 真实 是否正确
0.1 0.2 0.7 0 0 1 (猪) 正确
0.1 0.7 0.2 0 1 0 (狗) 正确
0.3 0.4 0.3 1 0 0 (猫) 错误
模型2对于样本1和样本2判断非常准确,对于样本3判断错误,但是相对来说没有错得太离谱。

有了模型之后,我们可以定义损失函数来对判断模型在当前样本表现

1.2、Classification Error(分类错误率)

在这里插入图片描述
从结果可知,模型1和模型2虽然都是预测错了1个,但是相对来说模型2表现得更好,损失函数值照理来说应该更小,但是,很遗憾的是,classification\ error 并不能判断出来,所以这种损失函数虽然好理解,但表现不太好。

1.3、Mean Squared Error (均方误差)

在这里插入图片描述
我们发现,MSE能够判断出来模型2优于模型1,那为什么不采样这种损失函数呢?主要原因是在分类问题中,使用sigmoid/softmx得到概率,配合MSE损失函数时,采用梯度下降法进行学习时,会出现模型一开始训练时,学习速率非常慢的情况。

1.4、交叉熵损失函数

交叉熵(Cross Entropy)用于衡量一个概率分布与另一个概率分布之间的距离。
交叉熵是机器学习和深度学习中常常用到的一个概念。在分类问题中,我们通常有一个真实的概率分布(通常是专家或训练数据的分布),以及一个模型生成的概率分布,交叉熵可以衡量这两个分布之间的距离。
模型训练时,通过最小化交叉熵损失函数,我们可以使模型预测值的概率分布逐步接近真实的概率分布。

信息熵
熵 是关于不确定性的数学描述。
信息的大小跟随机事件的概率有关。越小概率的事情发生了产生的信息量越大。
所以 信息的量度应该依赖于概率分布 p ( x ) p(x)p(x)
单调性:发生概率越高的事件,其携带的信息量越低;
非负性:信息熵可以看作为一种广度量,非负性是一种合理的必然;
累加性:即多随机事件同时发生存在的总不确定性的量度是可以表示为各事件不确定性的量度的和,这也是广度量的一种体现

在这里插入图片描述
在这里插入图片描述

使用python sklearn库实现

from sklearn.metrics import log_loss 
y_true = [[0, 0, 1], [0, 1, 0], [1, 0, 0]] 
y_pred_1 = [[0.3, 0.3, 0.4], [0.3, 0.4, 0.3], [0.1, 0.2, 0.7]] 
y_pred_2 = [[0.1, 0.2, 0.7], [0.1, 0.7, 0.2], [0.3, 0.4, 0.3]] 
print(log_loss(y_true, y_pred_1)) 
print(log_loss(y_true, y_pred_2)) 
____________ 
1.3783888522474517 
0.6391075640678003 

1.5、二分类

在这里插入图片描述
在这里插入图片描述

回归问题通常用均方差损失函数,可以保证损失函数是个凸函数,即可以得到最优解。而分类问题如果用均方差的话,损失函数的表现不是凸函数,就很难得到最优解。而交叉熵函数可以保证区间内单调。

2、什么是梯度下降法?

参考

梯度下降法在机器学习中常常用来优化损失函数,是一个非常重要的工具。说白了,就是在高中学习过的「极值」的概念,那么什么是极值呢?用非常形象的方式来说极值点,梯度下降法的作用就是寻找一个 「极小值点」,从而让函数的值尽可能地小。相信你也发现了,这么多个极值点,那么梯度下降法找到的是哪一个点呢?关于这个问题就要看运气了,算法的最开始会 「随机」 寻找一个位置然后开始搜索「局部」的最优解,如果运气好的话能够寻找到一个最小值的极值点,运气不好或许找到的就不是最小值的那个极小值点了。

比如说下边儿的这个函数图像 , 可以发现在当前这个区间范围内这个函数有两个极小值点,如果我们想寻找当前函数在这个区间内的最小值点,那么当然是第二个极小值点更合适一些,可是并不一定能够如我们所愿顺利地找到第二个极小值点,这时候只能够通过多次尝试。
在这里插入图片描述

2.2、梯度下降法的运行过程

接下来用一个简单的一元二次函数来阐述算法的运行过程。一元二次函数天生地就只有一个极小值点,方便用来说明问题。函数的表达式是 f(x) = (x-1)^2+1,通过表达式可以知道它的最小值点的坐标是(1,1)
在这里插入图片描述
「梯度的概念」:梯度就是函数对它的各个自变量求偏导后,由偏导数组成的一个向量。
「梯度下降法」:每个自变量方向上的偏导数构成的向量,函数f(x) 的梯度就是f(x)’ = 2x-2

图上有一个小红点,它的坐标是 (6, f(6)), 也就是当x=6的时候二次函数曲线上边儿的点。那么也可以得到f(6)'=10,也就是这个红点的位置的导数是等于10的。现在用导数值的 「正负来表示方向」,如果导数的值是正数,那么就代表x轴的正方向。如果导数的值是负数,那么就代表是x轴的负方向。那么你会发现,知道了这个方向之后也就知道了应该让f(x)往哪个方向变化x的值才会增大。如果想要让f(x)的值减小,那么就让x朝着导数告诉我们的方向的反方向变化就好啦。接下来我用「黄色」箭头代表导数告诉我们的方向,用「黑色」箭头代表导数指向的方向的反方向。
在这里插入图片描述

「梯度下降法」 的目标是搜索出来一个能够让函数的值尽可能小的位置,所以应该让x朝着黑色箭头的方向走,那么怎么完成这个操作呢?
在代码中有一个eta变量,它的专业名词叫 「学习率」。使用数学表达式来表示更新
在这里插入图片描述

表达式的意思就是让x减去eta乘以函数的导数。其中的eta是为了控制x更新的幅度,将eta设置的小一点,那么每一次更新的幅度就会小一点。

初始化

# 变量 x 表示当前所在的位置
# 就随机初始在 6 这个位置好了
x = 6
eta = 0.05

第一次更新x

# 变量 df 存储当前位置的导数值
df = 2*x-2
x = x - eta*df
# 更新后 x 由 6 变成 
# 6-0.05*10 = 5.5

第二次更新x

# 因为 x 的位置发生了变化
# 要重新计算当前位置的导数
df = 2*x-2
x = x - eta*df
# 更新后 x 由 5.5 变成
# 5.5-0.05*9 = 5.05

接下来只要重复刚才的过程就可以了。那么,把刚才的两个步骤画出来。其中红色箭头指向的点是初始时候的点,「黄色」 箭头指向的点是第 1 次更新后的位置,「蓝色」 箭头指向的点是第 2 次更新后的位置。
在这里插入图片描述

只要不停地重复刚才的这个过程,那么最终就会收敛到一个 「局部」 的极值点。那么可以想一下这是为什么?因为随着每一次的更新,曲线都会越来越平缓,相应的导数值也会越来越小,当我们接近极值点的时候导数的值会无限地靠近 「0」。由于导数的绝对值越来越小,那么随后更新的幅度也会越来越小,最终就会停留在极值点的位置了。接下来我将用 Python 来实现这个过程,并让刚才的步骤迭代 1000 次。

import matplotlib.pyplot as plt
import numpy as np

# 初始算法开始之前的坐标 
# cur_x 和 cur_y 
cur_x = 6
cur_y = (cur_x-1)**2 + 1
# 设置学习率 eta 为 0.05
eta = 0.05
# 变量 iter 用于存储迭代次数
# 这次我们迭代 1000 次
# 所以给它赋值 1000
iter = 1000
# 变量 cur_df 用于存储
# 当前位置的导数
# 一开始我给它赋值为 None
# 每一轮循环的时候为它更新值
cur_df = None

# all_x 用于存储
# 算法进行时所有点的横坐标
all_x = []
# all_y 用于存储
# 算法进行时所有点的纵坐标
all_y = []

# 把最一开始的坐标存储到
# all_x 和 all_y 中
all_x.append(cur_x)
all_y.append(cur_y)

# 循环结束也就意味着算法的结束
for i in range(iter):
    # 每一次迭代之前先计算
    # 当前位置的梯度 cur_df
    # cur 是英文单词 current 
    cur_df = 2*cur_x - 2
    # 更新 cur_x 到下一个位置
    cur_x = cur_x - eta*cur_df
    # 更新下一个 cur_x 对应的 cur_y
    cur_y = (cur_x-1)**2 + 1

    # 其实 cur_y 并没有起到实际的计算作用
    # 在这里计算 cur_y 只是为了将每一次的
    # 点的坐标存储到 all_x 和 all_y 中
    # all_x 存储了二维平面上所有点的横坐标
    # all_y 存储了二维平面上所欲点的纵坐标
    # 使用 list 的 append 方法添加元素
    all_x.append(cur_x)
    all_y.append(cur_y)

# 这里的 x, y 值为了绘制二次函数
# 的那根曲线用的,和算法没有关系
# linspace 将会从区间 [-5, 7] 中
# 等距离分割出 100 个点并返回一个
# np.array 类型的对象给 x
x = np.linspace(-5, 7, 100)
# 计算出 x 中每一个横坐标对应的纵坐标
y = (x-1)**2 + 1
# plot 函数会把传入的 x, y
# 组成的每一个点依次连接成一个平滑的曲线
# 这样就是我们看到的二次函数的曲线了
plt.plot(x, y)
# axis 函数用来指定坐标系的横轴纵轴的范围
# 这样就表示了 
# 横轴为 [-7, 9]
# 纵轴为 [0, 50]
plt.axis([-7, 9, 0, 50])
# scatter 函数是用来绘制散点图的
# scatter 和 plot 函数不同
# scatter 并不会将每个点依次连接
# 而是直接将它们以点的形式绘制出来
plt.scatter(np.array(all_x), np.array(all_y), color='red')
plt.show()

在这里插入图片描述

通过最终的效果图可以发现,「梯度下降」在一步一步地收敛到二次函数的极小值点,同时也是二次函数的最小值点。仔细看一下,可以发现,就像刚才提到的,随着算法的运行,红色的点和点之间的距离越来越小了,也就是每一次更新的幅度越来越小了。这可不关「学习率」 的事儿,因为在这里用到的学习率是一个固定的值,这只是因为随着接近极值点的过程中「导数的绝对值」越来越小。
同时,我们还可以把 all_x 和 all_y 中最后一个位置存储的值打印出来看一下,如果没错的话,all_x 的最后一个位置的值是接近于 1 的,同时对应的函数值 all_y 最后一个位置的值也应该是接近于 1 的。

2.3、二元函数的梯度下降

在多元函数中拥有多个自变量,在这里就用二元的函数来举例子好了,二元函数的图像是在三维坐标系中的。下边儿就是一个多元函数的图像例子。在这里纵坐标我使用 「y」 表示,底面的两个坐标分别使用 「x1」 和 「x2」 来表示。不用太纠结底面到底哪个轴是 x1 哪个轴是 x2,这里只是为了说明问题。

在这里插入图片描述
通过上面的二元函数凸显可以发现想要让 「y」 的值尽可能地小就要寻找极值点(同样地这个极值点也不一定是最小值点)。梯度是一个由各个自变量的偏导数所组成的一个「向量」。用数学表达式看上去就是下边儿这样的。
在这里插入图片描述
同样地,一开始随机初始一个位置,随后让当前位置的坐标值减去学习率乘以当前位置的偏导数。更新自变量 x1 就让 x1 减去学习率乘以 y 对 x1 的偏导数,更新自变量 x2 就让 x2 减去学习率乘以 y 对 x2 的偏导数。

发挥想象力再思考一下,既然梯度是一个向量,那么它就代表了一个方向。x1 的偏导数的反方向告诉我们在 x1 这个轴上朝向哪个方向变化可以使得函数值 y 减小,x2 的偏导数的反方向告诉我们在 x2 这个轴上朝向哪个方向变化可以使得函数值 y 减小。那么,由偏导数组成的向量就告诉了我们在底面朝向哪个方向走就可以使得函数 y 减小。
在下边儿的图中,我使用红色箭头表示我们当前所在的位置,随后我使用 「黑色」 箭头代表其中一个轴上的坐标朝向哪个方向变化可以使得函数值 「y」 减小,并使用 「黄色」 箭头代表另外一个轴上的坐标朝向哪个方向变化可以使得函数值 「y」 减小。根据平行色变形法则有了 「黑色」 向量和 「黄色」 向量,就可以知道这两个向量最终达到的效果就是 「蓝色」 向量所达到的效果。
在这里插入图片描述
最终,对于二元函数梯度下降的理解,就可以理解为求出的梯度的反方向在底面给了我们一个方向,只要朝着这个方向变化底面的坐标就可以使得函数值 「y」 变小。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多模态小记:CLIP、BLIP与BLIP2

CLIP 使用网络上爬取得到的大量图文对进行对比学习,图文匹配的是正样本,图文不匹配的是负样本,使匹配样本的embedding之间的距离尽可能小,不匹配样本间的距离尽可能大。 缺点:网上爬的数据质量差,不能进行…

SOCKS代理是如何提高网络性能和兼容性的?

SOCKS代理作为一种网络协议中间件,不仅在提升网络隐私和安全性方面发挥着重要作用,也在提高网络性能和兼容性方面有着不容忽视的影响🚀。本文将深入探讨SOCKS代理如何通过减少网络延迟🚀、优化数据传输🔄、提高跨平台兼…

十进制,二进制,八进制,十六进制之间转换

一. 十进制转二进制 二. 二进制转十进制 三. 十进制转八进制 四. 八进制转十进制 五. 十进制转十六进制

数字档案馆升级改造的意义

数字档案馆升级改造的意义在于提升档案管理的效率和质量,更好地满足各方面的需求,并为数字时代的档案管理提供更好的支持和保障。具体意义包括: 1. 提高档案存储、检索和利用效率:玖拓智能数字化档案馆可以实现电子存储和快速检索…

el-tree如何修改节点点击颜色

el-tree修改点击节点颜色三大步 使用elementui库时,有时候我们会对里面提供的组件做一些样式修改。如果我们想要修改el-tree组件点击节点时的颜色,可以使用下面这种方式实现:

最新国产中文版官网chatGPT镜像网站

分享5个国产中文版chatGPT镜像网站,希望可以帮助到您! 1️⃣ HiClaude3基于国外原版GPT模型、Claude模型开发,是资源丰富的全能镜像,适合各行各业的工作者。不仅有gpt,而且还支持图片对话、文件对话,轻松解…

项目存放在git上,在jenkins使用docker打包并推送到Ubuntu上运行

项目添加dockerfile 在需要打包的工程的根目录添加Dockerfile文件,文件内容: # 设置JAVA版本 FROM openjdk:8 # 指定存储卷,任何向/tmp写入的信息都不会记录到容器存储层 VOLUME /tmp# 拷贝运行JAR包 ARG JAR_FILE COPY ${JAR_FILE} app.jar…

08 - 镜像管理之:镜像仓库harbor介绍

本文参考:原文1 1 Harbor仓库介绍 Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署我们私有环境内的Registry 也是非常必要的。 之前介绍了Docker私有仓…

适用于W波段GaAs开关设计的可扩展p-i-n二极管建模与参数提取技术

来源:Scalable p-i-n Diode Modeling and Parameter Extraction for Use in the Design of W-Band GaAs Switch(TIE 21年) 摘要 本文介绍了一种针对W波段开关设计的基于毫米波GaAs的p-i-n二极管的可扩展建模与参数提取方法。采用基于晶圆上…

创新指南|战略衡量的增长组织:用人工智能增强关键绩效指标(KPI)

传统的关键绩效指标 (KPI)越来越无法提供领导者取得成功所需的信息和见解。他们在跟踪进展、协调人员和流程、确定资源优先级以及推进问责制方面存在不足。本文是 2024 年第一份麻省理工学院 SMR - BCG 人工智能和商业战略全球高管学习和研究项目的调查结果——人工智能和业务战…

鸿蒙开发学习笔记第一篇--TypeScript基础语法

目录 前言 一、ArkTS 二、基础语法 1.基础类型 1.布尔值 2.数字 3.字符串 4.数组 5.元组 6.枚举 7.unkown 8.void 9.null和undefined 10.联合类型 2.条件语句 1.if语句 1.最简单的if语句 2.if...else语句 3.if...else if....else 语句 2.switch语句 5.函数…

上位机图像处理和嵌入式模块部署(qmacvisual动态插件卸载)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们讨论过,qmacvisual虽然提供了很多的功能,包括的种类很多,但是总有一些功能是客户希望定制的。这些都是…

抖音小店无货源爆发期过了吗?现在还能做吗?

大家好,我是电商花花。 抖音小店爆发期过了吗? 我并不觉得,反而抖音小店的流量越来越大了,今年抖音小店日活跃用户已经突破到了9亿,有更大的市场和流量了,且现在做店越来越多了,再加上平台的支…

django 模板js文件为什么最后引入

<!-- 引入Bootstrap JS --> <script src"https://cdn.jsdelivr.net/npm/bootstrap5.3.0/dist/js/bootstrap.bundle.min.js"></script> 为什么最后引入例子 <!-- templates/inspection_records.html --><!DOCTYPE html> <html lang…

zookeeper解析

目录 zookeeper定义 zookeeper定义 Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目 Zookeeper工作机制 zookeeper从设计模式角度来理解&#xff1a; 是一个基于观察者模式设计的分布式服务管理框架&#xff0c;它负责存储和管理大家都关心…

arm内核驱动-中断

先介绍个东西 ctags 这个工具可以像keil一样在工程里查找跳转&#xff0c;帮我们找到我们想要的东西。 安装教程可以找到&#xff0c;这里只讲怎么用。 在工程目录&#xff08;包含所有你会用到的头文件等&#xff09;下&#xff0c;先加载这个命令&#xff0c;可能要等待…

VSCode中调试C++程序

目录 一、准备工作&#xff1a;安装插件 1、C/C插件 ​编辑 2、CMake插件 3、CMake tool插件 二、调试过程 1、debug 2、打断点 3、调C/C文件 每次重新调试的时候都忘了具体步骤&#xff0c;直接给自己写个备忘录好了。 一、准备工作&#xff1a;安装插件 1、C/C插件…

李沐29_残差网络ResNet——自学笔记

残差网络 残差网络的核心思想是&#xff1a;每个附加层都应该更容易地包含原始函数作为其元素之一。 残差块 串联一个层改变函数类&#xff0c;我们希望扩大函数类&#xff0c;残差块加入快速通道来得到f(x)xg(x)的结果 ResNet块 1.高宽减半的ResNet块&#xff08;步幅2&a…

Android开发之移除权限

Android开发之移除权限 在Android开发结束后&#xff0c;我们将build好的App Bundle上传至Google Play。这时Google可能会提示一些需要解决的错误&#xff0c;比如xx权限需要限制&#xff0c;需要解释为什么需要这些权限&#xff0c;需要添加文字描述和视频链接&#xff0c;但…

MicroCinema与CCEdit:让文生视频兼具创造性与可控性

编者按&#xff1a;随着视频生成技术的飞速进步&#xff0c;我们见证了人工智能技术在视频清晰度、长视频连贯性以及对物理变化理解和镜头转换处理能力方面的显著提升。不过&#xff0c;这些高质量的生成结果是否完全符合我们的需求呢&#xff1f;显然&#xff0c;并非总是如此…