【转载】深度学习笔记——详解损失函数

原文链接: https://blog.csdn.net/weixin_53765658/article/details/136360033
CSDN账号: Purepisces
github账号: purepisces
希望大家可以Star Machine Learning Blog https://github.com/purepisces/Wenqing-Machine_Learning_Blog

损失函数

根据您使用的神经网络类型和数据类型,不同的损失函数可能会变得有用,例如分类问题的交叉熵损失,回归问题的均方误差。了解这些损失函数是如何计算的,以及它们将如何用于更新您的网络是很重要的。

损失类

类属性:

  • A A A:存储模型预测以计算反向传播。
  • Y Y Y:存储期望输出以计算反向传播。

类方法:

  • f o r w a r d forward forward

    • 参数: A A A(模型预测), Y Y Y(期望输出)
    • 返回值:损失值 L L L
    • 描述:计算并返回标量损失值 L L L,量化网络输出和期望输出之间的不匹配。
  • b a c k w a r d backward backward

    • 返回值: d L d A dLdA dLdA(模型输出变化如何影响损失 L L L
    • 描述:计算并返回 d L d A dLdA dLdA,表示模型输出 A A A 的变化如何影响损失 L L L。它使得可以进行反向传播的下游计算。

请考虑以下类结构:

class Loss:def forward(self, A, Y):self.A = Aself.Y = Yself.    # todo(根据需要存储额外的属性)N      = # todo,这是 A 和 Y 的第一维度C      = # todo,这是 A 和 Y 的第二维度# todoreturn Ldef backward(self):dLdA = # 待办事项return dLdA
代码名称数学符号类型形状含义
N N N N标量-批量大小
C C C C标量-类别数目
A A A A矩阵 N × C N \times C N×C模型输出
Y Y Y Y矩阵 N × C N \times C N×C真实值
L L L L标量-损失值
dLdA ∂ L ∂ A \frac{\partial L}{\partial A} AL矩阵 N × C N \times C N×C模型输出变化如何影响损失

注意:在回归任务的上下文中,对应于类别数目的维度 C C C 简化为 1。这是因为回归问题涉及预测单个连续变量,而不是从多个类别中选择。相反,在分类场景中, C C C 代表每个输入可以被分类的不同类别或类别的总数,因此可以根据具体问题而变化。

损失函数拓扑在下图中可视化:

在这里插入图片描述

示例

在此示例中,我们将演示如何在具有3个类别的分类任务中使用 L o s s Loss Loss 类。假设我们的批量大小( N N N)为2,这意味着我们一次处理两个示例。

模型输出(Logits)

模型输出,表示为 A A A,是每个类别的logits。对于我们的示例,批量大小为2且有3个类别, A A A 可能如下所示:

A = [ 5 1 − 1 − 2 6 0 ] A = \begin{bmatrix} 5 & 1 & -1\\ -2 & 6 & 0 \end{bmatrix} A=[521610]

这些logits代表每个类别的原始分数,在应用softmax函数之前。

真实值(Y)

真实值 Y Y Y 以独热编码(one-hot encoded)格式表示:

Y = [ 1 0 0 0 0 1 ] Y = \begin{bmatrix} 1 & 0 & 0\\ 0 & 0 & 1 \end{bmatrix} Y=[100001]

这里,第一行 [ 1 , 0 , 0 ] [1, 0, 0] [1,0,0] 表示第一个示例属于第1类,第二行 [ 0 , 0 , 1 ] [0, 0, 1] [0,0,1] 表示第二个示例属于第3类。

在损失计算中使用 A A A Y Y Y

损失函数使用logits A A A 和真实值 Y Y Y 来计算损失值 L L L。例如,使用交叉熵损失函数会首先对logits应用softmax函数以获得概率,然后通过将这些预测概率与 Y Y Y 中的实际标签进行比较来计算每个单独示例的损失。随后,这些单独的损失在批次中的所有示例上平均,以产生损失的单一标量值, L L L

L o s s Loss Loss 类中的 f o r w a r d forward forward 方法负责使用 A A A(作为logits)和 Y Y Y 来计算这个标量损失值 L L L。接着, b a c k w a r d backward backward 方法计算损失对于logits的梯度,表示为 ∂ L ∂ A \frac{\partial L}{\partial A} AL。这个梯度对于反向传播过程至关重要,使得在训练期间可以更新模型参数。

详解均方误差损失函数:

均方误差(MSE,Mean Squared Error)是回归问题中评估预测误差的一种广泛使用的指标。在回归中,目标是预测连续值,例如根据房屋的特征(如面积、位置、卧室数量等)估计房屋的价格。

MSE 损失前向方程

计算从计算模型预测( A A A)与实际真值( Y Y Y)之间的平方误差( S E SE SE)开始:

S E ( A , Y ) = ( A − Y ) ⊙ ( A − Y ) SE(A, Y) = (A - Y) \odot (A - Y) SE(A,Y)=(AY)(AY)

接下来,我们确定平方误差之和( S S E SSE SSE)。这里, ι N \iota_N ιN ι C \iota_C ιC 分别表示大小为 N N N C C C 的、填充有 1 的列向量:

S S E ( A , Y ) = ι N T ⋅ S E ( A , Y ) ⋅ ι C SSE(A,Y) = \iota_{N}^{T} \cdot SE(A,Y) \cdot \iota_{C} SSE(A,Y)=ιNTSE(A,Y)ιC

这个操作将 S E ( A , Y ) SE(A, Y) SE(A,Y) 矩阵中的所有元素求和,该矩阵的维度为 N × C N \times C N×C。通过 ι N T \iota_{N}^{T} ιNT 的乘法在行间聚合错误,随后通过 ι C \iota_{C} ιC 的乘法将这些在列间求和,产生一个单一标量的总误差。

然后计算每个组件的均方误差( M S E MSE MSE)损失:

M S E L o s s ( A , Y ) = S S E ( A , Y ) N ⋅ C MSELoss(A, Y) = \frac{SSE(A, Y)}{N \cdot C} MSELoss(A,Y)=NCSSE(A,Y)

MSE 损失反向方程

在反向传播过程中,需要计算 MSE 损失相对于模型输出( A A A)的梯度,以更新模型参数:

M S E L o s s . b a c k w a r d ( ) = 2 ⋅ ( A − Y ) N ⋅ C MSELoss.backward() = 2 \cdot \frac{(A - Y)}{N \cdot C} MSELoss.backward()=2NC(AY)

MSE 损失的导数

MSE 损失函数定义为:

M S E L o s s ( A , Y ) = 1 N ⋅ C ∑ i = 1 N ∑ j = 1 C ( A i j − Y i j ) 2 MSELoss(A, Y) = \frac{1}{N \cdot C} \sum\limits_{i=1}^{N} \sum\limits_{j=1}^{C} (A_{ij} - Y_{ij})^2 MSELoss(A,Y)=NC1i=1Nj=1C(AijYij)2

其中:

A A A:模型预测值。

Y Y Y:真实值。

N N N:批次中的样本数量。

C C C:每个样本的输出维度,回归任务中通常为 1。

为了更新模型参数(在这个例子中,通过反向传播),我们需要知道 A A A 的变化如何影响损失。这由损失函数相对于 A A A 的导数给出,表示为 ∂ M S E L o s s ∂ A \frac{\partial MSELoss}{\partial A} AMSELoss

∂ M S E L o s s ∂ A = 2 ⋅ ( A − Y ) N ⋅ C \frac{\partial MSELoss}{\partial A} = 2 \cdot \frac{(A - Y)}{N \cdot C} AMSELoss=2NC(AY)

梯度 ∂ M S E L o s s ∂ A \frac{\partial MSELoss}{\partial A} AMSELoss 指向损失函数最陡增加的方向。通过向相反方向移动(即,从预测 A A A 中减去这个梯度),我们可以减少损失,这是训练模型的目标。

总之, M S E L o s s . b a c k w a r d ( ) MSELoss.backward() MSELoss.backward() 2 ⋅ ( A − Y ) N ⋅ C 2 \cdot \frac{(A - Y)}{N \cdot C} 2NC(AY) 公式是通过对预测 A A A 求 MSE 损失函数的导数得到的,考虑了平方误差和平均操作。这个梯度在优化过程中被用来调整模型参数,以最小化损失。

import numpy as npclass MSELoss:def forward(self, A, Y):# 为反向计算存储预测值(A)和真实值(Y)self.A = Aself.Y = Y# 计算预测值和真实值之间的平方误差se = (A - Y) ** 2# 对平方误差求和以得到总的平方误差sse = np.sum(se)# 通过将总的平方误差除以元素数量来计算均方误差mse = sse / (A.shape[0] * A.shape[1])return msedef backward(self):# 计算损失相对于预测值(A)的梯度dLdA = 2 * (self.A - self.Y) / (self.A.shape[0] * self.A.shape[1])return dLdA

示例

让我们通过一个具体的例子来了解在回归场景中如何应用均方误差(MSE)损失。假设我们正试图基于一些特征来预测房屋价格。为了简单起见,我们将考虑一个案例,其中我们的模型基于多个特征(例如平方英尺面积和卧室数量)来预测两栋房屋的价格,因此我们的批量大小 N N N 为 2,特征数量 C C C 也为 2。

给定数据:

  • 模型输出 ( A A A):预测的两栋房屋的价格和卧室数量。假设模型对每栋房屋的预测如下(价格以美元计,卧室以数量计)。这可以表示为一个 2x2 矩阵(因为 N = 2 N=2 N=2 C = 2 C=2 C=2):

A = [ 300 , 000 3 500 , 000 4 ] A = \begin{bmatrix} 300,000 & 3 \\ 500,000 & 4 \end{bmatrix} A=[300,000500,00034]

这里,第一列代表两栋房屋的预测价格,第二列代表预测的卧室数量。

  • 真实值 ( Y Y Y):两栋房屋的实际价格和卧室数量。这也是一个 2x2 矩阵:

Y = [ 350 , 000 4 450 , 000 3 ] Y = \begin{bmatrix} 350,000 & 4 \\ 450,000 & 3 \end{bmatrix} Y=[350,000450,00043]

正向传播(计算 MSE 损失):

  1. 计算平方误差 ( S E SE SE):

S E ( A , Y ) = ( A − Y ) ⊙ ( A − Y ) = [ ( 300 , 000 − 350 , 000 ) 2 ( 3 − 4 ) 2 ( 500 , 000 − 450 , 000 ) 2 ( 4 − 3 ) 2 ] = [ 2500 × 1 0 6 1 2500 × 1 0 6 1 ] \begin{align} SE(A, Y) &= (A - Y) \odot (A - Y) \\ &= \begin{bmatrix} (300,000 - 350,000)^2 & (3 - 4)^2 \\ (500,000 - 450,000)^2 & (4 - 3)^2 \end{bmatrix} \\ &= \begin{bmatrix} 2500 \times 10^6 & 1 \\ 2500 \times 10^6 & 1 \end{bmatrix} \end{align} SE(A,Y)=(AY)(AY)=[(300,000350,000)2(500,000450,000)2(34)2(43)2]=[2500×1062500×10611]

  1. 平方误差之和 ( S S E SSE SSE):
    S E SE SE 中的所有元素相加:

S S E ( A , Y ) = ∑ S E ( A , Y ) = 2 × ( 2500 × 1 0 6 ) + 2 × 1 = 5000 × 1 0 6 + 2 SSE(A, Y) = \sum SE(A, Y) = 2 \times (2500 \times 10^6) + 2 \times 1 = 5000 \times 10^6 + 2 SSE(A,Y)=SE(A,Y)=2×(2500×106)+2×1=5000×106+2

  1. 均方误差 ( M S E MSE MSE):

M S E L o s s ( A , Y ) = S S E ( A , Y ) N ⋅ C = 5000 × 1 0 6 + 2 2 × 2 = 2500 × 1 0 6 + 1 2 MSELoss(A, Y) = \frac{SSE(A, Y)}{N \cdot C} = \frac{5000 \times 10^6 + 2}{2 \times 2} = \frac{2500 \times 10^6 + 1}{2} MSELoss(A,Y)=NCSSE(A,Y)=2×25000×106+2=22500×106+1

反向传播(计算梯度):

可以计算损失相对于预测值 ( A A A) 的梯度:

∂ M S E L o s s ∂ A = 2 ⋅ ( A − Y ) N ⋅ C = 2 ⋅ [ 300 , 000 − 350 , 000 3 − 4 500 , 000 − 450 , 000 4 − 3 ] 2 × 2 = 1 2 [ − 50 , 000 − 1 50 , 000 1 ] \begin{align} \frac{\partial MSELoss}{\partial A} &= 2 \cdot \frac{(A - Y)}{N \cdot C} \\ &= 2 \cdot \frac{\begin{bmatrix} 300,000 - 350,000 & 3 - 4 \\ 500,000 - 450,000 & 4 - 3 \end{bmatrix}}{2 \times 2} \\ &= \frac{1}{2} \begin{bmatrix} -50,000 & -1 \\ 50,000 & 1 \end{bmatrix} \end{align} AMSELoss=2NC(AY)=22×2[300,000350,000500,000450,0003443]=21[50,00050,00011]

这个梯度矩阵提供了如何调整每个预测(价格和卧室数量)以最小化损失的指导。负值表示需要增加预测值,正值表明需要减少预测值以减少误差。

详解交叉熵损失函数:

交叉熵损失是用于基于概率的分类问题最常用的损失函数之一。

交叉熵损失前向方程

首先,我们使用softmax函数将原始模型输出 A A A转换成由输入数值的指数决定的 C C C类的概率分布。

ι N \iota_N ιN ι C \iota_C ιC是大小为 N N N C C C的列向量,包含全部为1的值。

softmax ( A ) = σ ( A ) = exp ⁡ ( A ) ∑ j = 1 C exp ⁡ ( A i j ) \text{softmax}(A) = \sigma(A) = \frac{\exp(A)}{\sum\limits_{j=1}^{C} \exp(A_{ij})} softmax(A)=σ(A)=j=1Cexp(Aij)exp(A)

现在,A的每一行代表模型对概率分布的预测,而Y的每一行代表一个输入的目标分布。
然后,我们计算分布Ai相对于目标分布Yi的交叉熵H(A,Y),对于i = 1,…,N:

crossentropy = H ( A , Y ) = ( − Y ⊙ log ⁡ ( σ ( A ) ) ) ⋅ ι C \text{crossentropy} = H(A, Y) = (-Y \odot \log(\sigma(A))) \cdot \mathbf{\iota}_C crossentropy=H(A,Y)=(Ylog(σ(A)))ιC

记住,损失函数的输出是一个标量,但现在我们有一个大小为N的列矩阵。要将其转换为标量,我们可以使用所有交叉熵的和或平均值。

这里,我们选择使用平均交叉熵作为交叉熵损失,这也是PyTorch的默认设置:

sumcrossentropyloss : = ι N T ⋅ H ( A , Y ) = S C E ( A , Y ) \text{sumcrossentropyloss} := \mathbf{\iota}_N^T \cdot H(A, Y) = SCE(A, Y) sumcrossentropyloss:=ιNTH(A,Y)=SCE(A,Y)

meancrossentropyloss : = S C E ( A , Y ) N \text{meancrossentropyloss} := \frac{SCE(A, Y)}{N} meancrossentropyloss:=NSCE(A,Y)
在这里插入图片描述

交叉熵损失反向方程

xent.backward ( ) = σ ( A ) − Y N \text{xent.backward}() = \frac{\sigma(A) - Y}{N} xent.backward()=Nσ(A)Y

梯度的推导(我的证明)

要找到交叉熵损失相对于对数几率 A i A_i Ai的梯度,我们需要计算导数 ∂ H ∂ A i \frac{\partial H}{\partial A_i} AiH。这涉及到应用链式法则到对数和softmax函数的复合中。

注意对于一个对数几率 A i c A_{ic} Aic,softmax函数定义为:

σ ( A i c ) = e A i c ∑ j = 1 C e A i j \sigma(A_{ic}) = \frac{e^{A_{ic}}}{\sum\limits_{j=1}^{C} e^{A_{ij}}} σ(Aic)=j=1CeAijeAic

步骤1:应用链式法则

首先,注意我们需要对一个复合函数的导数应用链式法则,这个复合函数是softmax输出的对数:

H ( A i , Y i ) = − ∑ c = 1 C Y i c log ⁡ ( σ ( A i c ) ) H(A_i, Y_i) = -\sum_{c=1}^{C} Y_{ic} \log(\sigma(A_{ic})) H(Ai,Yi)=c=1CYiclog(σ(Aic))

∂ H ∂ A i c = ∂ ( − Y i 1 log ⁡ ( σ ( A i 1 ) ) − Y i 2 log ⁡ ( σ ( A i 2 ) ) − . . . − Y i C log ⁡ ( σ ( A i C ) ) ) ∂ A i c = ∂ ( − Y i 1 log ⁡ ( σ ( A i 1 ) ) ) ∂ A i c + ∂ ( − Y i 2 log ⁡ ( σ ( A i 2 ) ) ) ∂ A i c + . . . + ∂ ( − Y i C log ⁡ ( σ ( A i C ) ) ) ∂ A i c = − Y i 1 ∂ log ⁡ ( σ ( A i 1 ) ) ∂ A i c − Y i 2 ∂ log ⁡ ( σ ( A i 2 ) ) ∂ A i c − . . . − Y i C ∂ log ⁡ ( σ ( A i C ) ) ∂ A i c = − ∑ k = 1 C Y i k ∂ log ⁡ ( σ ( A i k ) ) ∂ A i c \begin{align*} \frac{\partial H}{\partial A_{ic}} &= \frac{\partial (-Y_{i1}\log(\sigma(A_{i1})) -Y_{i2}\log(\sigma(A_{i2}))-...-Y_{iC}\log(\sigma(A_{iC})))}{\partial A_{ic}} \\ &= \frac{\partial (-Y_{i1}\log(\sigma(A_{i1})))}{\partial A_{ic}} + \frac{\partial (-Y_{i2}\log(\sigma(A_{i2})))}{\partial A_{ic}} + ...+ \frac{\partial (-Y_{iC}\log(\sigma(A_{iC})))}{\partial A_{ic}} \\ &=-Y_{i1}\frac{\partial \log(\sigma(A_{i1}))}{\partial A_{ic}} -Y_{i2}\frac{\partial \log(\sigma(A_{i2}))}{\partial A_{ic}} -...-Y_{iC}\frac{\partial \log(\sigma(A_{iC}))}{\partial A_{ic}} \\ &=- \sum_{k=1}^{C} Y_{ik} \frac{\partial \log(\sigma(A_{ik}))}{\partial A_{ic}}\\ \end{align*} AicH=Aic(Yi1log(σ(Ai1))Yi2log(σ(Ai2))...YiClog(σ(AiC)))=Aic(Yi1log(σ(Ai1)))+Aic(Yi2log(σ(Ai2)))+...+Aic(YiClog(σ(AiC)))=Yi1Aiclog(σ(Ai1))Yi2Aiclog(σ(Ai2))...YiCAiclog(σ(AiC))=k=1CYikAiclog(σ(Aik))

∂ H ∂ A i c = − ∑ k = 1 C Y i k ∂ log ⁡ ( σ ( A i k ) ) ∂ A i c \frac{\partial H}{\partial A_{ic}} = - \sum_{k=1}^{C} Y_{ik} \frac{\partial \log(\sigma(A_{ik}))}{\partial A_{ic}} AicH=k=1CYikAiclog(σ(Aik))

步骤2:Softmax的对数的导数

log ⁡ ( σ ( A i k ) ) \log(\sigma(A_{ik})) log(σ(Aik))关于 A i c A_{ic} Aic的导数涉及两种情况:当 k = c k=c k=c和当 k ≠ c k \neq c k=c时。

k = c k=c k=c时,使用对数的导数 ∂ log ⁡ ( x ) ∂ x = 1 x \frac{\partial \log(x)}{\partial x} = \frac{1}{x} xlog(x)=x1和softmax的定义,我们得到:

∂ log ⁡ ( σ ( A i k ) ) ∂ A i c = ∂ log ⁡ ( σ ( A i c ) ) ∂ σ ( A i c ) ⋅ ∂ σ ( A i c ) ∂ A i c = 1 σ ( A i c ) ⋅ σ ( A i c ) ⋅ ( 1 − σ ( A i c ) ) = 1 − σ ( A i c ) \begin{align*} \frac{\partial \log(\sigma(A_{ik}))}{\partial A_{ic}} &= \frac{\partial \log(\sigma(A_{ic}))}{\partial \sigma(A_{ic})} \cdot \frac{\partial \sigma(A_{ic})}{\partial A_{ic}} \\ &= \frac{1}{\sigma(A_{ic})} \cdot \sigma(A_{ic}) \cdot (1 - \sigma(A_{ic})) \\ &= 1 - \sigma(A_{ic}) \end{align*} Aiclog(σ(Aik))=σ(Aic)log(σ(Aic))Aicσ(Aic)=σ(Aic)1σ(Aic)(1σ(Aic))=1σ(Aic)

k ≠ c k\neq c k=c时,导数涉及不同类的softmax函数,结果是:

∂ log ⁡ ( σ ( A i k ) ) ∂ A i c = ∂ log ⁡ ( σ ( A i k ) ) ∂ σ ( A i c ) ⋅ ∂ σ ( A i c ) ∂ A i c = 1 σ ( A i k ) ⋅ − σ ( A i k ) ⋅ σ ( A i c ) = − σ ( A i c ) \begin{align*} \frac{\partial \log(\sigma(A_{ik}))}{\partial A_{ic}} &= \frac{\partial \log(\sigma(A_{ik}))}{\partial \sigma(A_{ic})} \cdot \frac{\partial \sigma(A_{ic})}{\partial A_{ic}} \\ &= \frac{1}{\sigma(A_{ik})} \cdot -\sigma(A_{ik}) \cdot \sigma(A_{ic}) \\ &= -\sigma(A_{ic}) \end{align*} Aiclog(σ(Aik))=σ(Aic)log(σ(Aik))Aicσ(Aic)=σ(Aik)1σ(Aik)σ(Aic)=σ(Aic)

步骤3:合并情况

由于 Y i Y_i Yi对于真实类别只能为1,否则为0,这简化为:

∂ H ∂ A i c = − ∑ k = 1 C Y i k ∂ log ⁡ ( σ ( A i k ) ) ∂ A i c = o r { − 1 ( 1 − σ ( A i c ) ) = σ ( A i c ) − 1 , for  Y i c = 0 − 1 ( − σ ( A i c ) ) = σ ( A i c ) − 0 , for  Y i c = 1 = σ ( A i c ) − Y i c \begin{align*} \frac{\partial H}{\partial A_{ic}} &= - \sum_{k=1}^{C} Y_{ik} \frac{\partial \log(\sigma(A_{ik}))}{\partial A_{ic}} \\ &= or\begin{cases} -1 (1 - \sigma(A_{ic})) = \sigma(A_{ic}) - 1, & \text{for } Y_{ic} = 0 \\ -1(-\sigma(A_{ic})) = \sigma(A_{ic}) - 0, & \text{for } Y_{ic} = 1 \end{cases} \\ &= \sigma(A_{ic}) - Y_{ic} \end{align*} AicH=k=1CYikAiclog(σ(Aik))=or{1(1σ(Aic))=σ(Aic)1,1(σ(Aic))=σ(Aic)0,for Yic=0for Yic=1=σ(Aic)Yic

示例

让我给出一个具体的例子来说明它:

示例 1

考虑这个案例 Y = [ 1 , 0 , 0 ] Y = [1,0,0] Y=[1,0,0] A = [ 2 , 1 , − 1 ] A = [2, 1, -1] A=[2,1,1]

Y 11 = 1 , Y 12 = 0 , Y 13 = 0 Y_{11} = 1, Y_{12} = 0, Y_{13} = 0 Y11=1,Y12=0,Y13=0
A 11 = 2 , A 12 = 1 , A 13 = − 1 A_{11} = 2, A_{12} = 1, A_{13} = -1 A11=2,A12=1,A13=1

然后当计算

∂ H ∂ A 13 = − ∑ k = 1 C Y 1 k ∂ log ⁡ ( σ ( A 1 k ) ) ∂ A 13 = − Y 11 ∂ log ⁡ ( σ ( A 11 ) ) ∂ A 13 − Y 12 ∂ log ⁡ ( σ ( A 12 ) ) ∂ A 13 − Y 13 ∂ log ⁡ ( σ ( A 13 ) ) ∂ A 13 = − 1 ( − σ ( A 13 ) ) − 0 − 0 = σ ( A 13 ) − 0 = σ ( A 13 ) − Y 13 \begin{align*} \frac{\partial H}{\partial A_{13}} &= - \sum\limits_{k=1}^{C} Y_{1k} \frac{\partial \log(\sigma(A_{1k}))}{\partial A_{13}}\\ &=-Y_{11}\frac{\partial \log(\sigma(A_{11}))}{\partial A_{13}}-Y_{12}\frac{\partial \log(\sigma(A_{12}))}{\partial A_{13}}-Y_{13}\frac{\partial \log(\sigma(A_{13}))}{\partial A_{13}}\\ &= -1(-\sigma(A_{13}))-0-0 \\ &= \sigma(A_{13}) - 0 \\ &= \sigma(A_{13}) - Y _{13}\\ \end{align*} A13H=k=1CY1kA13log(σ(A1k))=Y11A13log(σ(A11))Y12A13log(σ(A12))Y13A13log(σ(A13))=1(σ(A13))00=σ(A13)0=σ(A13)Y13

示例 2

考虑这个案例 Y = [ 0 , 0 , 1 ] Y = [0,0,1] Y=[0,0,1] A = [ 2 , 1 , − 1 ] A = [2, 1, -1] A=[2,1,1]

Y 11 = 0 , Y 12 = 0 , Y 13 = 1 Y_{11} = 0, Y_{12} = 0, Y_{13} = 1 Y11=0,Y12=0,Y13=1
A 11 = 2 , A 12 = 1 , A 13 = − 1 A_{11} = 2, A_{12} = 1, A_{13} = -1 A11=2,A12=1,A13=1

然后当计算

∂ H ∂ A 13 = − ∑ k = 1 C Y 1 k ∂ log ⁡ ( σ ( A 1 k ) ) ∂ A 13 = − Y 11 ∂ log ⁡ ( σ ( A 11 ) ) ∂ A 13 − Y 12 ∂ log ⁡ ( σ ( A 12 ) ) ∂ A 13 − Y 13 ∂ log ⁡ ( σ ( A 13 ) ) ∂ A 13 = − 0 − 0 − 1 ( 1 − σ ( A 13 ) ) = σ ( A 13 ) − 1 = σ ( A 13 ) − Y 13 \begin{align*} \frac{\partial H}{\partial A_{13}} &= - \sum\limits_{k=1}^{C} Y_{1k} \frac{\partial \log(\sigma(A_{1k}))}{\partial A_{13}}\\ &=-Y_{11}\frac{\partial \log(\sigma(A_{11}))}{\partial A_{13}}-Y_{12}\frac{\partial \log(\sigma(A_{12}))}{\partial A_{13}}-Y_{13}\frac{\partial \log(\sigma(A_{13}))}{\partial A_{13}}\\ &= -0-0-1(1 - \sigma(A_{13})) \\ &= \sigma(A_{13}) - 1 \\ &= \sigma(A_{13}) - Y _{13}\\ \end{align*} A13H=k=1CY1kA13log(σ(A1k))=Y11A13log(σ(A11))Y12A13log(σ(A12))Y13A13log(σ(A13))=001(1σ(A13))=σ(A13)1=σ(A13)Y13

梯度的推导(YouTube的证明)
  • Softmax函数是一个向量。
  • 每个元素 e z k ∑ c = 1 C e z c \frac{e^{z_k}}{\sum\limits_{c=1}^{C} e^{z_c}} c=1Cezcezk由于分母的原因依赖于所有输入元素。
  • 向量关于向量的梯度是一个矩阵。
  • 为了简化和巩固这个概念,让我们通过查看一个大小为 3 3 3的向量来使其更具体:

( z 1 z 2 z 3 ) → ( e z 1 e z 1 + e z 2 + e z 3 e z 2 e z 1 + e z 2 + e z 3 e z 3 e z 1 + e z 2 + e z 3 ) = ( a 1 a 2 a 3 ) = ( y 1 ^ y 2 ^ y 3 ^ ) \begin{pmatrix} z_1\\ z_2\\ z_3 \end{pmatrix} \rightarrow \begin{pmatrix} \frac{e^{z_1}}{e^{z_1} + e^{z_2} + e^{z_3}}\\ \frac{e^{z_2}}{e^{z_1} + e^{z_2} + e^{z_3}}\\ \frac{e^{z_3}}{e^{z_1} + e^{z_2} + e^{z_3}} \end{pmatrix} = \begin{pmatrix} a_1\\ a_2\\ a_3 \end{pmatrix} = \begin{pmatrix} \hat{y_1}\\ \hat{y_2}\\ \hat{y_3} \end{pmatrix} z1z2z3 ez1+ez2+ez3ez1ez1+ez2+ez3ez2ez1+ez2+ez3ez3 = a1a2a3 = y1^y2^y3^

矩阵的对角元素会发生什么?我们有导数关于分子中相同元素。例如,对于 ∂ a 1 ∂ z 1 \frac{\partial a_1}{\partial z_1} z1a1我们得到:

∂ a 1 ∂ z 1 = e z 1 ( e z 1 + e z 2 + e z 3 ) − e z 1 e z 1 ( e z 1 + e z 2 + e z 3 ) ( e z 1 + e z 2 + e z 3 ) = e z 1 e z 1 + e z 2 + e z 3 ⋅ e z 1 + e z 2 + e z 3 − e z 1 e z 1 + e z 2 + e z 3 = a 1 ( 1 − a 1 ) \frac{\partial a_1}{\partial z_1} = \frac{e^{z_1}(e^{z_1} + e^{z_2} + e^{z_3}) - e^{z_1}e^{z_1}}{(e^{z_1} + e^{z_2} + e^{z_3})(e^{z_1} + e^{z_2} + e^{z_3})} = \frac{e^{z_1}}{e^{z_1} + e^{z_2} + e^{z_3}} \cdot \frac{e^{z_1}+e^{z_2}+e^{z_3}-e^{z_1}}{e^{z_1} + e^{z_2} + e^{z_3}} = a_1(1 - a_1) z1a1=(ez1+ez2+ez3)(ez1+ez2+ez3)ez1(ez1+ez2+ez3)ez1ez1=ez1+ez2+ez3ez1ez1+ez2+ez3ez1+ez2+ez3ez1=a1(1a1)

所以我们得到了非常接近于sigmoid导数的东西。

对角线元素以外的元素会发生什么?例如,对于 ∂ a 1 ∂ z 2 \frac{\partial a_1}{\partial z_2} z2a1我们得到:

∂ a 1 ∂ z 2 = 0 ⋅ ( e z 1 + e z 2 + e z 3 ) − e z 1 e z 2 ( e z 1 + e z 2 + e z 3 ) 2 = − e z 1 e z 1 + e z 2 + e z 3 ⋅ e z 2 e z 1 + e z 2 + e z 3 = − a 1 a 2 \frac{\partial a_1}{\partial z_2} = \frac{0 \cdot (e^{z_1} + e^{z_2} + e^{z_3}) - e^{z_1}e^{z_2}}{(e^{z_1} + e^{z_2} + e^{z_3})^2} = -\frac{e^{z_1}}{e^{z_1} + e^{z_2} + e^{z_3}} \cdot \frac{e^{z_2}}{e^{z_1} + e^{z_2} + e^{z_3}} = -a_1a_2 z2a1=(ez1+ez2+ez3)20(ez1+ez2+ez3)ez1ez2=ez1+ez2+ez3ez1ez1+ez2+ez3ez2=a1a2

对于我们的3x3矩阵,我们将得到:

∂ a ∂ z = ( a 1 ( 1 − a 1 ) − a 1 a 2 − a 1 a 3 − a 2 a 1 a 2 ( 1 − a 2 ) − a 2 a 3 − a 3 a 1 − a 3 a 2 a 3 ( 1 − a 3 ) ) \frac{\partial \mathbf{a}}{\partial \mathbf{z}} = \begin{pmatrix} a_1(1 - a_1) & -a_1a_2 & -a_1a_3 \\ -a_2a_1 & a_2(1 - a_2) & -a_2a_3 \\ -a_3a_1 & -a_3a_2 & a_3(1 - a_3) \end{pmatrix} za= a1(1a1)a2a1a3a1a1a2a2(1a2)a3a2a1a3a2a3a3(1a3)

对于损失相对于最终输出的导数 - 我们有一个标量相对于向量的导数,所以结果也将是一个向量:

∂ L ∂ a L = [ ∂ ∂ a L 1 ( − ∑ c = 1 C y c log ⁡ a L c ) ⋮ ∂ ∂ a L C ( − ∑ c = 1 C y c log ⁡ a L c ) ] = − [ y 1 a L 1 ⋮ y C a L C ] \frac{\partial \mathcal{L}}{\partial a_L} = \begin{bmatrix} \frac{\partial}{\partial a_{L1}} \left(-\sum\limits_{c=1}^{C} y_c \log a_{Lc}\right) \\ \vdots \\ \frac{\partial}{\partial a_{LC}} \left(-\sum\limits_{c=1}^{C} y_c \log a_{Lc}\right) \end{bmatrix} = - \begin{bmatrix} \frac{y_1}{a_{L1}} \\ \vdots \\ \frac{y_C}{a_{LC}} \end{bmatrix} aLL= aL1(c=1CyclogaLc)aLC(c=1CyclogaLc) = aL1y1aLCyC

记住对于每个1-hot向量 y y y,我们只有一个元素等于1,其余都是0。

回到我们具体的 3 × 3 3 \times 3 3×3例子,并把所有东西放在一起,我们得到:

∂ L ∂ z L = ∂ L ∂ a L ∂ a L ∂ z L = − [ y 1 a 1 y 2 a 2 y 3 a 3 ] ( a 1 ( 1 − a 1 ) − a 1 a 2 − a 1 a 3 − a 2 a 1 a 2 ( 1 − a 2 ) − a 2 a 3 − a 3 a 1 − a 3 a 2 a 3 ( 1 − a 3 ) ) = − [ y 1 − a 1 ( y 1 + y 2 + y 3 ) y 2 − a 2 ( y 1 + y 2 + y 3 ) y 3 − a 3 ( y 1 + y 2 + y 3 ) ] = a − y \begin{align} \frac{\partial \mathcal{L}}{\partial z_L} &= \frac{\partial \mathcal{L}}{\partial a_L} \frac{\partial a_L}{\partial z_L} \\ &= -\begin{bmatrix} \frac{y_1}{a_1} \\ \frac{y_2}{a_2} \\ \frac{y_3}{a_3} \end{bmatrix} \begin{pmatrix} a_1(1 - a_1) & -a_1a_2 & -a_1a_3 \\ -a_2a_1 & a_2(1 - a_2) & -a_2a_3 \\ -a_3a_1 & -a_3a_2 & a_3(1 - a_3) \end{pmatrix} \\ &= -\begin{bmatrix} y_1 - a_1(y_1 + y_2 + y_3) & y_2 - a_2(y_1 + y_2 + y_3) & y_3 - a_3(y_1 + y_2 + y_3) \end{bmatrix} \\ &= \mathbf{a} - \mathbf{y} \end{align} zLL=aLLzLaL= a1y1a2y2a3y3 a1(1a1)a2a1a3a1a1a2a2(1a2)a3a2a1a3a2a3a3(1a3) =[y1a1(y1+y2+y3)y2a2(y1+y2+y3)y3a3(y1+y2+y3)]=ay

注意这里的 a \mathbf{a} a y \mathbf{y} y是向量,而不是标量。

交叉熵损失的示例

为了说明交叉熵损失,让我们考虑一个具体的例子,用一个小数据集。假设我们有一个简单的分类问题,有三个类别(C=3),我们正在处理两个样本的批次( N = 2 N=2 N=2)。这两个样本的模型原始输出分数( A A A)和相应的真实标签( Y Y Y)可能如下所示:

  • 两个样本的原始模型输出( A A A):

    • 样本 1: [ 2.0 , 1.0 , 0.1 ] [2.0, 1.0, 0.1] [2.0,1.0,0.1]
    • 样本 2: [ 0.1 , 2.0 , 1.9 ] [0.1, 2.0, 1.9] [0.1,2.0,1.9]
  • 真实类别分布( Y Y Y,独热编码):

    • 样本 1: [ 0 , 1 , 0 ] [0, 1, 0] [0,1,0] (类别 2 是真实类别)
    • 样本 2: [ 1 , 0 , 0 ] [1, 0, 0] [1,0,0] (类别 1 是真实类别)

让我们逐步计算这个例子的交叉熵损失:

1. 应用 Softmax

首先,我们对原始输出应用 softmax 函数,以获得每个类别的预测概率。

对于样本 1,softmax 计算如下:
σ ( A 1 ) = [ e 2.0 e 2.0 + e 1.0 + e 0.1 , e 1.0 e 2.0 + e 1.0 + e 0.1 , e 0.1 e 2.0 + e 1.0 + e 0.1 ] \sigma(A_1) = \left[\frac{e^{2.0}}{e^{2.0} + e^{1.0} + e^{0.1}}, \frac{e^{1.0}}{e^{2.0} + e^{1.0} + e^{0.1}}, \frac{e^{0.1}}{e^{2.0} + e^{1.0} + e^{0.1}}\right] σ(A1)=[e2.0+e1.0+e0.1e2.0,e2.0+e1.0+e0.1e1.0,e2.0+e1.0+e0.1e0.1]

对于样本 2,类似地:
σ ( A 2 ) = [ e 0.1 e 0.1 + e 2.0 + e 1.9 , e 2.0 e 0.1 + e 2.0 + e 1.9 , e 1.9 e 0.1 + e 2.0 + e 1.9 ] \sigma(A_2) = \left[\frac{e^{0.1}}{e^{0.1} + e^{2.0} + e^{1.9}}, \frac{e^{2.0}}{e^{0.1} + e^{2.0} + e^{1.9}}, \frac{e^{1.9}}{e^{0.1} + e^{2.0} + e^{1.9}}\right] σ(A2)=[e0.1+e2.0+e1.9e0.1,e0.1+e2.0+e1.9e2.0,e0.1+e2.0+e1.9e1.9]

2. 计算交叉熵损失

接下来,我们计算每个样本的交叉熵损失。单个样本的损失由下式给出:
H ( A i , Y i ) = − ∑ c = 1 C Y i c log ⁡ ( σ ( A i c ) ) H(A_i, Y_i) = -\sum_{c=1}^{C} Y_{ic} \log(\sigma(A_{ic})) H(Ai,Yi)=c=1CYiclog(σ(Aic))

对于样本 1:
H ( A 1 , Y 1 ) = − [ 0 × log ⁡ ( σ ( A 11 ) ) + 1 × log ⁡ ( σ ( A 12 ) ) + 0 × log ⁡ ( σ ( A 13 ) ) ] H(A_1, Y_1) = -[0 \times \log(\sigma(A_{11})) + 1 \times \log(\sigma(A_{12})) + 0 \times \log(\sigma(A_{13}))] H(A1,Y1)=[0×log(σ(A11))+1×log(σ(A12))+0×log(σ(A13))]

对于样本 2:
H ( A 2 , Y 2 ) = − [ 1 × log ⁡ ( σ ( A 21 ) ) + 0 × log ⁡ ( σ ( A 22 ) ) + 0 × log ⁡ ( σ ( A 23 ) ) ] H(A_2, Y_2) = -[1 \times \log(\sigma(A_{21})) + 0 \times \log(\sigma(A_{22})) + 0 \times \log(\sigma(A_{23}))] H(A2,Y2)=[1×log(σ(A21))+0×log(σ(A22))+0×log(σ(A23))]

3. 计算平均交叉熵损失

最后,我们计算这些损失的平均值,以得到批次的平均交叉熵损失:
meancrossentropyloss = H ( A 1 , Y 1 ) + H ( A 2 , Y 2 ) 2 \text{meancrossentropyloss} = \frac{H(A_1, Y_1) + H(A_2, Y_2)}{2} meancrossentropyloss=2H(A1,Y1)+H(A2,Y2)

4. 交叉熵损失的反向传播

对于反向传播,交叉熵损失相对于应用 softmax 之前的原始模型输出的梯度由下式给出:
∂ Loss ∂ A = σ ( A ) − Y N \frac{\partial \text{Loss}}{\partial A} = \frac{\sigma(A) - Y}{N} ALoss=Nσ(A)Y

对于批次中的每个样本,我们计算:

  • 对于样本 1: σ ( A 1 ) − Y 1 2 \frac{\sigma(A_1) - Y_1}{2} 2σ(A1)Y1
  • 对于样本 2: σ ( A 2 ) − Y 2 2 \frac{\sigma(A_2) - Y_2}{2} 2σ(A2)Y2

这给了我们需要通过网络反向传播的梯度。

基于计算:

  • 两个样本的 softmax 概率大约为:

    • 样本 1: [ 0.659 , 0.242 , 0.099 ] [0.659, 0.242, 0.099] [0.659,0.242,0.099]
    • 样本 2: [ 0.073 , 0.487 , 0.440 ] [0.073, 0.487, 0.440] [0.073,0.487,0.440]
  • 两个样本的交叉熵损失为:

    • 样本 1: 1.417
    • 样本 2: 2.620
  • 这个批次的平均交叉熵损失大约为 2.019。

  • 损失相对于原始模型输出( A A A)的梯度为:

    • 对于样本 1: [ 0.330 , − 0.379 , 0.049 ] [0.330, -0.379, 0.049] [0.330,0.379,0.049]
    • 对于样本 2: [ − 0.464 , 0.243 , 0.220 ] [-0.464, 0.243, 0.220] [0.464,0.243,0.220]

这些结果给出了我们使用 softmax 函数得到的每个类别的预测概率,每个样本的个别交叉熵损失,批次的整体平均交叉熵损失,以及反向传播所需的梯度。梯度中的负值指示了我们应该调整模型参数以减少损失的方向,而正值则建议相反的方向。

class CrossEntropyLoss:def softmax(self, x):# 通过在每个输入向量中减去最大值来改善 softmax 的数值稳定性。# 这通过指数化大的正数来防止潜在的溢出。e_x = np.exp(x - np.max(x, axis=1, keepdims=True))return e_x / e_x.sum(axis=1, keepdims=True)def forward(self, A, Y):self.A = Aself.Y = Yself.softmax = self.softmax(A)crossentropy = -Y * np.log(self.softmax)# 在批次上平均损失L = np.sum(crossentropy) / A.shape[0]return Ldef backward(self):# 计算损失相对于对数(预 softmax 激活)A的梯度# 这个梯度还包括在批次上的平均dLdA = (self.softmax - self.Y) / self.A.shape[0]return dLdA

参考资料:

  • 在YouTube上观看视频
  • CMU_11785_深度学习导论

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

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

相关文章

第四十七回 一丈青单捉王矮虎 宋公明二打祝家庄-强大而灵活的python装饰器

四面全是埋伏,宋江和众人一直绕圈跑不出去。正在慌乱之时,石秀及时赶到,教大家碰到白杨树就转弯走。走了一段时间,发现围的人越来越多,原来祝家庄以灯笼指挥号令。花荣一箭射下来红灯龙,伏兵自己就乱起来了…

Northwestern University-844计算机科学与技术/软件工程-复试注意事项【考研复习】

本文提到的西北大学是位于密歇根湖泊畔的西北大学。西北大学(英语:Northwestern University,简称:NU)是美国的一所著名私立研究型大学。它由九人于1851年创立,目标是建立一所为西北领地地区的人服务的大学。…

【力扣白嫖日记】550.游戏玩法分析IV

前言 练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。 今日题目: 550.游戏玩法分析IV 表:Activity 列名类型player_idintdevice_idintevent_datedategames_played…

从 iOS 设备恢复数据的 20 个iOS 数据恢复工具

作为 iPhone、iPad 或 iPod 用户,您可能普遍担心自己可能会丢失存储在珍贵 iOS 设备中的所有宝贵数据。数据丢失的原因多种多样,这里列出了一些常见原因: 1. iOS 软件更新 2. 恢复出厂设置 3. 越狱 4. 误操作删除数据 5. iOS 设备崩溃 …

C++笔记(五)--- 虚函数(virtual)

目录 虚函数介绍 虚函数、覆盖和重载区别 虚函数介绍 C的虚函数是多态性的表现 1.构造函数不能为虚函数2.子类继承时虚函数仍为虚函数3.虚函数类外实现时,不需要加virtual4.有虚函数的类,析构函数一定要写成虚函数(否则可能会造成内存泄漏&…

【代码随想录python笔记整理】第十六课 · 出现频率最高的字母

前言:本笔记仅仅只是对内容的整理和自行消化,并不是完整内容,如有侵权,联系立删。 一、哈希表初步 在之前的学习中,我们使用数组、字符串、链表等等,假如需要找到某个节点,则都要从头开始,逐一比较,直到找到为止。为了能够直接通过要查找的记录找到其存储位置,我们选…

、JMETER与它的组件们

os进程取样器 这个取样器可以让jmeter直接调用python写的测试数据 这样就可以调用python写的测试数据给到jmeter进行调用 注意:1建议python返回转json格式dumps一下;2py文件中需要把结果打印出来,可以不用函数直接编写 传到jmeter之后可以用…

你真的了解C语言中的【柔性数组】吗~

柔性数组 1. 什么是柔性数组2. 柔性数组的特点3. 柔性数组的使用4. 柔性数组的优势 1. 什么是柔性数组 也许你从来没有听说过柔性数组这个概念,但是它确实是存在的。 C99中,结构体中的最后⼀个元素允许是未知大小的数组,这就叫做柔性数组成员…

MyBatis 学习(五)之 高级映射

目录 1 association 和 collection 介绍 2 案例分析 3 一对一关联和一对多关联 4 参考文档 1 association 和 collection 介绍 在之前的 SQL 映射文件中提及了 resultMap 元素的 association 和 collection 标签,这两个标签是用来关联查询的,它们的属…

算法--时空复杂度分析以及各个数据量对应的可使用的算法(C++;1s内)

这里写目录标题 由数据范围反推算法时间复杂度以及算法内容分析时间复杂度看循环实例1实例2 固定时间复杂度快排和归并排序二分高精度算法双指针算法单链表插入删除操作栈和队列的操作单调栈和单调队列KMPTire并查集堆哈希表BFS、DFS图的深度优先、宽度优先遍历dijkstra算法朴素…

瑞_Redis_Redis的Java客户端

文章目录 1 Redis的Java客户端1.1 Jedis快速入门1.1.1 入门案例1.1.1.1 项目构建1.1.1.2 引入依赖1.1.1.3 建立连接1.1.1.4 释放资源1.1.1.5 测试1.1.1.6 完整测试类代码 1.1.2 Jedis连接池1.1.2.1 连接池工具类1.1.2.2 改造原始代码 🙊 前言:本文章为瑞…

常用sql语句及其优化

文章目录 介绍常用sql语句1. 数据查询1.1 SELECT 语句1.2 DISTINCT 关键字1.3 WHERE 子句1.4 ORDER BY 子句1.5 LIMIT 关键字 2. 数据更新2.1 INSERT INTO 语句2.2 UPDATE 语句2.3 DELETE FROM 语句 3. 数据管理3.1 CREATE TABLE 语句3.2 ALTER TABLE 语句3.3 DROP TABLE 语句 …

批量自动加好友神器!微信快速扩友秘籍!

对于一些个人或者企业来说,传统的人工添加好友方式往往会出现效率低下,费时费力的问题。那么,有没有一种快速、便捷、安全的方式来解决这个问题呢?答案当然是肯定的,那就是通过使用微信管理系统来解决这一问题。 在微…

基于java+springboot景区行李寄存管理系统设计和实现

基于javaspringboot景区行李寄存管理系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取…

5GC SBA架构

协议标准:Directory Listing /ftp/Specs/archive/23_series/23.501/ (3gpp.org) NF描述说明NSSFNetwork Slice Selection Function网络切片选择,根据UE的切片选择辅助信息、签约信息等确定UE允许接入的网络切片实例。NEF Network Exposure Function网络开…

疾控中心的污水采样瓶用的是什么材质

疾控中心的污水采样瓶采用的材质是聚乙烯或聚丙烯塑料。这种材质的污水采样瓶具有耐腐蚀、耐高压、无毒无味、重量轻、易于携带等优点。此外,这种材质的污水采样瓶还可以在高温下消毒,不会变形或破裂。 疾控中心的污水采样瓶通常有不同的容积和形状&…

Harbor高可用(haproxy和keepalived)

Harbor高可用(haproxy和keepalived) 文章目录 Harbor高可用(haproxy和keepalived)1.Harbor高可用集群部署架构1.1 主机初始化1.1.1 设置网卡名和ip地址1.1.2 设置主机名1.1.3 配置镜像源1.1.4 关闭防火墙1.1.5 禁用SELinux1.1.6 设…

SpringBoot 自定义映射规则resultMap association一对一

介绍 例:学生表,班级表,希望在查询学生的时候一起返回该学生的班级,而一个实体类封装的是一个表,如需要多表查询就需要自定义映射。 表结构 班级表 学生表 SQL语句 SELECT a.id,a.name,a.classes,b.id classes…

Charles抓包 - 安装、激活、证书配置

最近刚好又遇到了抓包的需求,之前一直使用 Fiddler 抓包,这几年一直听大家都在用 Charles 抓包,正好一起了解下(一般建议掌握一种抓包方式即可,都可以解决同种需求场景) 抓包 Fiddler抓包 Charles 下载、安…

2024年新提出的算法|LEA爱情进化算法(Love Evolution Algorithm)

Love Evolution Algorithm: a stimulus–value–role theory-inspired evolutionary algorithm for global optimization 爱情进化算法Love Evolution Algorithm,LEA,于2024年2月发表在中科院3区SCI期刊 The Journal of Supercomputing。 1、简介 本文提…