神经网络—参数初始化、激活函数、损失函数及反向传播算法

news2024/11/16 6:53:48

基础知识点

神经网络NN(Neural Netwarks)

深度学习(Deep Learning)

神经元(Neuron)

深层神经网络(Deep Neural Networks,DNNs)

神经网络有下面三个基础层(Layer)构建而成:

  • 输入层(Input): 神经网络的第一层,负责接收外部数据,不进行计算。

  • 隐藏层(Hidden): 位于输入层和输出层之间,进行特征提取和转换。隐藏层一般有多层,每一层有多个神经元。

  • 输出层(Output): 网络的最后一层,产生最终的预测结果或分类结果

全连接(Fully Connected,FC)神经网络

是前馈神经网络的一种,每一层的神经元与上一层的所有神经元全连接,常用于图像分类、文本分类等任务。所有相邻神经元之间通过权重和偏置连接的网络也称之为全连接神经网络。

特点

  • 全连接层: 层与层之间的每个神经元都与前一层的所有神经元相连。

  • 权重数量: 由于全连接的特点,权重的数量较大,容易导致计算量大、模型复杂度高。

  • 学习能力: 能够学习输入数据的全局特征,但对于高维数据却不擅长捕捉局部特征。

计算步骤

  1. 数据传递: 输入数据经过每一层的计算,逐层传递到输出层。

  2. 激活函数: 每一层的输出通过激活函数处理。

  3. 损失计算: 在输出层计算预测值与真实值之间的差距,即损失函数值。

  4. 反向传播(Back Propagation): 通过反向传播算法计算损失函数对每个权重的梯度,并更新权重以最小化损失。

人工神经元(Artificial Neuron)

——组成部分:输入(Inputs)、权重(Weights)、偏置(Bias)、加权求和、激活函数(Activation Function)

  • 输入(Inputs): 代表输入数据,通常用向量表示,每个输入值对应一个权重。

  • 权重(Weights): 每个输入数据都有一个权重,表示该输入对最终结果的重要性。

  • 偏置(Bias): 一个额外的可调参数,作用类似于线性方程中的截距,帮助调整模型的输出。

  • 加权求和: 神经元将输入乘以对应的权重后求和,再加上偏置。

  • 激活函数(Activation Function): 用于将加权求和后的结果转换为输出结果,引入非线性特性,使神经网络能够处理复杂的任务。常见的激活函数有Sigmoid、ReLU(Rectified Linear Unit)、Tanh等。

箭头上带有两个信息:权重w和偏置b;权重和神经元的值相乘再加上偏置,经过某个激活函数后的值作为下个神经元的输入

参数初始化

神经网络的参数初始化是训练深度学习模型的关键步骤之一。初始化参数(通常是权重和偏置)会对模型的训练速度、收敛性以及最终的性能产生重要影响。

固定值初始化

固定值初始化是指在神经网络训练开始时,将所有权重或偏置初始化为一个特定的常数值。(不推荐)

1.全零初始化

将神经网络中的所有权重参数初始化为0

方法:将所有权重初始化为零。

缺点:导致对称性破坏,每个神经元在每一层中都会执行相同的计算,模型无法学习。

应用场景:通常不用来初始化权重,但可以用来初始化偏置

import torch
import torch.nn as nn

def test():
    #全0参数初始化
    linear =nn.Linear(in_features=6,out_features=4)
    #初始化权重参数
    nn.init.zeros_(linear.weight)
    
    print(linear.weight)
    pass 
if __name__=="__main__":
    test()

2.全1初始化

全1初始化会导致网络中每个神经元接收到相同的输入信号,进而输出相同的值,这就无法进行学习和收敛。(不适用)

import torch
import torch.nn as nn

def test():
    #全1参数初始化
    linear =nn.Linear(in_features=5,out_features=3)
    #初始化权重参数
    nn.init.ones_(linear.weight)
    
    print(linear.weight)
    pass 
if __name__=="__main__":
    test()

3.任意常数初始化

不能避免对称性破坏的问题

import torch
import torch.nn as nn

def test():
    #固定值参数初始化
    linear =nn.Linear(in_features=5,out_features=3)
    #初始化权重参数
    nn.init.constant_(linear.weight,0.8)
    
    print(linear.weight)
    pass 
if __name__=="__main__":
    test()

随机初始化

这是最基本的初始化方法,通过随机初始化避免对称性破坏.

方法:将权重初始化为随机的小值,通常从正态分布或均匀分布中采样

import torch 
import torch.nn as nn

def test():
    #均匀分布随机初始化
    linear=nn.Linear(in_features=2,out_features=3)
    #初始化权重参数
    nn.init.uniform_(linear.weight,0,0.5)

    print(linear.weight)

    pass

if __name__ == "__main__":
    test()  

import torch 
import torch.nn as nn

def test():
    #正态分布随机初始化
    linear=nn.Linear(in_features=2,out_features=3)
    #初始化权重参数
    nn.init.normal_(linear.weight,mean=0,std=1)
    
    print(linear.weight)

    pass

if __name__ == "__main__":
    test()  

Xavier 初始化

也叫做Glorot初始化

方法:根据输入和输出神经元的数量来选择权重的初始值。权重从以下分布中采样:

其中 n_{in} 是当前层的输入神经元数量,n_{out}是输出神经元数量。

优点:平衡了输入和输出的方差,适合Sigmoid和 Tanh激活函数。

应用场景:常用于浅层网络或使用Sigmoid 、Tanh 激活函数的网络。

import torch 
import torch.nn as nn

def test():
    #Xavier初始化:正态分布
    linear = nn.Linear(in_features=2,out_features=3)
    nn.init.xavier_normal_(linear.weight)
    print(linear.weight)

    #Xavier初始化:均匀分布
    linear = nn.Linear(in_features=2,out_features=3)
    nn.init.xavier_uniform_(linear.weight)
    print(linear.weight)
    pass

if __name__ == "__main__":
    test()  

He初始化

也叫kaiming 初始化

方法:专门为 ReLU 激活函数设计。权重从以下分布中采样:

其中n_{in}是当前层的输入神经元数量。

优点:适用于ReLU和Leaky ReLU激活函数。

应用场景:深度网络,尤其是使用 ReLU 激活函数时。

import torch 
import torch.nn as nn

def test():
    #He初始化:正态分布
    linear = nn.Linear(in_features=2,out_features=3)
    nn.init.kaiming_normal_(linear.weight,nonlinearity='relu')
    print(linear.weight)

    #He初始化:均匀分布
    linear = nn.Linear(in_features=2,out_features=3)
    nn.init.kaiming_uniform_(linear.weight,nonlinearity='relu')
    print(linear.weight)
    pass

if __name__ == "__main__":
    test()  

常见的初始化方法

  • Zeros:生成初始化为0的张量的初始化器。

  • Ones:生成初始化为1的张量的初始化器。

  • Constant:生成初始化为常量值的张量的初始化器。

  • RandomNormal:生成具有正态分布的张量的初始化器。

  • RandomUniform:生成具有均匀分布的张量的初始化器。

  • TruncatedNormal:生成截断正态分布的初始化器。

  • VarianceScaling:能够根据权重的形状调整其缩放比例的初始化器。

  • Orthogonal:生成随机正交矩阵的初始化器。

  • Identity:生成单位矩阵的初始化器。

  • lecun_uniform:LeCun uniform initializer。

  • glorot_normal:Glorot normal initializer,也称为Xavier normal initializer。

  • glorot_uniform:Glorot uniform initializer,也称为Xavier uniform initializer。

  • he_normal:He normal initializer。

  • lecun_normal:LeCun normal initializer。

  • he_uniform:He uniform variance scaling initializer。

在使用Torch构建网络模型时,每个网络层的参数都有默认的初始化方法,同时还可以通过以上方法来对网络参数进行初始化

激活函数(Activation Function)

激活函数的作用是在隐藏层引入非线性,使得神经网络能够学习和表示复杂的函数关系,使网络具备非线性能力,增强其表达能力。

如果没有激活函数,神经网络的每一层都是线性变换,整个网络就相当于一个线性模型,无论网络的深度如何,都只能解决线性可分问题,无法解决复杂的非线性问题。

如何选择激活函数

隐藏层

  1. 优先选ReLU;

  2. 如果ReLU效果不咋地,那么尝试其他激活,如Leaky ReLU等;

  3. 使用ReLU时注意神经元死亡问题, 避免出现过多神经元死亡;

  4. 不使用sigmoid,尝试使用tanh;

输出层

  1. 二分类问题选择sigmoid激活函数;

  2. 多分类问题选择softmax激活函数

1.sigmoid

Sigmoid激活函数是一种常见的非线性激活函数,特别是在早期神经网络中应用广泛。它将输入映射到0到1之间的值,因此非常适合处理概率问题。

Sigmoid函数的数学表达式为:

  1. 将任意实数输入映射到 (0, 1)之间,因此非常适合处理概率场景。

  2. sigmoid函数一般只用于二分类的输出层。

  3. 微分性质: 导数计算比较方便,可以用自身表达式来表示:

缺点:

  • 梯度消失:

    • 在输入非常大或非常小时,Sigmoid函数的梯度会变得非常小,接近于0。这导致在反向传播过程中,梯度逐渐衰减。

    • 最终使得早期层的权重更新非常缓慢,进而导致训练速度变慢甚至停滞。

  • 信息丢失:输入100和输入10000经过sigmoid的激活值几乎都是等于 1 的,但是输入的数据却相差 100 倍。

  • 计算成本高: 由于涉及指数运算,Sigmoid的计算比ReLU等函数更复杂,尽管差异并不显著。

import torch 
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 用来配置Python中的matplotlib库的图表显示设置,确保在显示中文字符及负号时不会出现问题
#即解决中文乱码问题

def test():
    #1行2列绘制图像
    _,t=plt.subplots(1,2)
    #绘制图像
    x=torch.linspace(0,10,100)
    y=torch.sigmoid(x)
    #网格
    t[0].grid(True)
    t[0].set_title('sigmoid')
    t[0].set_xlabel('x')
    t[0].set_ylabel('y')
    #在第一行第一列绘制函数曲线
    t[0].plot(x,y)

    x=torch.linspace(0,10,100,requires_grad=True)
    # y=torch.sigmoid(x)*(1-torch.sigmoid(x))
    #自动求导
    torch.sigmoid(x).sum().backward()
    t[1].grid(True)
    t[1].set_title("sigmoid 函数导数曲线图", color="red")
    t[1].set_xlabel("x")
    t[1].set_ylabel("y")

    #用自动求导的结果绘制曲线图
    t[1].plot(x.detach().numpy(), x.grad.detach().numpy())
    plt.show()
    pass

if __name__=="__main__":
    test()

2.tanh

tanh(双曲正切)是一种常见的非线性激活函数,常用于神经网络的隐藏层。tanh 函数也是一种S形曲线,输出范围为(−1,1)。

tanh数学表达式为:

  1. 输出范围: 将输入映射到$$(-1, 1)$$之间,因此输出是零中心的。相比于Sigmoid函数,这种零中心化的输出有助于加速收敛。

  2. 对称性: Tanh函数关于原点对称,因此在输入为0时,输出也为0。这种对称性有助于在训练神经网络时使数据更平衡。

  3. 平滑性: Tanh函数在整个输入范围内都是连续且可微的,这使其非常适合于使用梯度下降法进行优化。

                        \frac{d}{dx} \text{tanh}(x) = 1 - \text{tanh}^2(x)

缺点:

  1. 梯度消失: 虽然一定程度上改善了梯度消失问题,但在输入值非常大或非常小时导数还是非常小,这在深层网络中仍然是个问题。

  2. 计算成本: 由于涉及指数运算,Tanh的计算成本还是略高,尽管差异不大。

import torch 
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 用来配置Python中的matplotlib库的图表显示设置,确保在显示中文字符及负号时不会出现问题

def test():
    #1行2列绘制图像
    _,t=plt.subplots(1,2)
    #绘制图像
    x=torch.linspace(0,10,100)
    y=torch.tanh(x)
    #网格
    t[0].grid(True)
    t[0].set_title('tanh 函数曲线图')
    t[0].set_xlabel('x')
    t[0].set_ylabel('y')
    #在第一行第一列绘制函数曲线
    t[0].plot(x,y)

    x=torch.linspace(0,10,100,requires_grad=True)
    # y=torch.tanh(x)*(1-torch.tanh(x))
    #自动求导
    torch.sigmoid(x).sum().backward()
    t[1].grid(True)
    t[1].set_title("sigmoid 函数导数曲线图", color="red")
    t[1].set_xlabel("x")
    t[1].set_ylabel("y")

    #用自动求导的结果绘制曲线图
    t[1].plot(x.detach().numpy(), x.grad.detach().numpy())
    plt.show()
    pass

if __name__=="__main__":
    test()

3.ReLU

ReLU 函数定义如下: \text{ReLU}(x) = \max(0, x)

即ReLU对输入x进行非线性变换:

  1. 计算简单:ReLU 的计算非常简单,只需要对输入进行一次比较运算,这在实际应用中大大加速了神经网络的训练。

  2. ReLU 函数的导数是分段函数:\text{ReLU}'(x)=\begin{cases}1,&\text{if } x>0\\0,&\text{if }x\leq0\end{cases}

  3. 缓解梯度消失问题:相比于 Sigmoid 和 Tanh 激活函数,ReLU 在正半区的导数恒为 1,这使得深度神经网络在训练过程中可以更好地传播梯度,不存在饱和问题。

  4. 稀疏激活:ReLU在输入小于等于 0 时输出为 0,这使得 ReLU 可以在神经网络中引入稀疏性(即一些神经元不被激活),这种稀疏性可以提升网络的泛化能力。

缺点:

如果某个神经元输入值是负,那么该神经元将永远不再激活,成为“死亡”神经元。随着训练的进行,网络中可能会出现大量死亡神经元,从而会降低模型的表达能力。

import torch 
import matplotlib.pyplot as plt
import torch.nn.functional as F

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 用来配置Python中的matplotlib库的图表显示设置,确保在显示中文字符及负号时不会出现问题

def test():
    x=torch.linspace(-100,10,500)
    y=F.relu(x)
    _,t=plt.subplots(1,2)
    t[0].plot(x.numpy(),y.numpy())
    #网格
    t[0].grid()
    t[0].set_title('relu 函数曲线图')
    t[0].set_xlabel('x')
    t[0].set_ylabel('y')

    x=torch.linspace(-100,10,500,requires_grad=True)
    F.relu(x).sum().backward()
    t[1].plot(x.detach().numpy(),x.grad.detach().numpy())
    t[1].grid()
    t[1].set_title("relu 函数导数曲线图", color="red")
    t[1].lines[0].set_color("red")
    t[1].set_xlabel("x")
    t[1].set_ylabel("x.grad")
    plt.show()
    pass

if __name__=="__main__":
    test()

4.LeakyReLU

Leaky ReLU是一种对 ReLU 函数的改进,旨在解决 ReLU 的一些缺点,特别是Dying ReLU 问题。Leaky ReLU 通过在输入为负时引入一个小的负斜率来改善这一问题。

Leaky ReLU 函数的定义如下:

\text{Leaky ReLU}(x)=\begin{cases}x,&\text{if } x>0\\\alpha x,&\text{if } x\leq0\end{cases}

其中, \alpha是一个非常小的常数(如 0.01),它控制负半轴的斜率。这个常数是一个超参数,可以在训练过程中可自行进行调整。

  1. 避免神经元死亡:通过在x\leq 0 区域引入一个小的负斜率,这样即使输入值小于等于零,Leaky ReLU仍然会有梯度,允许神经元继续更新权重,避免神经元在训练过程中完全“死亡”的问题。

  2. 计算简单:Leaky ReLU 的计算与 ReLU 相似,只需简单的比较和线性运算,计算开销低。

缺点:

\alpha是一个需要调整的超参数,选择合适的值可能需要实验和调优。

如果\alpha设定得不当,仍然可能导致激活值过低。

import torch 
import matplotlib.pyplot as plt
import torch.nn.functional as F

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 用来配置Python中的matplotlib库的图表显示设置,确保在显示中文字符及负号时不会出现问题

def test():
    x=torch.linspace(-100,10,500)
    #设置leaky_relu
    slope=0.1#斜率
    y=F.leaky_relu(x,slope)
    #一行两列
    _,t=plt.subplots(1,2)
    t[0].plot(x.numpy(),y.numpy())
    #添加标题和坐标轴标签
    t[0].plot(x,y)
    t[0].set_title('leaky_relu 函数曲线图')
    t[0].set_xlabel('x')
    t[0].set_ylabel('y')
    t[0].grid(True)

    x=torch.linspace(-100,10,500,requires_grad=True)
    F.leaky_relu(x,slope).sum().backward()
    t[1].plot(x.detach().numpy(),x.grad)
    t[1].set_title("leaky_relu 函数导数曲线图", color="red")
    t[1].lines[0].set_color("red")
    t[1].set_xlabel("x")
    t[1].set_ylabel("x.grad")
    t[1].grid(True)

    plt.show()
    pass

if __name__=="__main__":
    test()

5.softmax

Softmax激活函数通常用于分类问题的输出层,它能够将网络的输出转换为概率分布,使得输出的各个类别的概率之和为 1。其本质上是一种归一化函数,可以将一组任意的实数值转化为在[0, 1]之间的概率值,因为softmax将它们转换为0到1之间的值,所以它们可以被解释为概率。如果其中一个输入很小或为负,softmax将其变为小概率,如果输入很大,则将其变为大概率,但它将始终保持在0到1之间。Softmax 特别适合用于多分类问题。

假设神经网络的输出层有n个节点,每个节点的输出为z_i,则 Softmax 函数的定义如下:\mathrm{Softmax}(z_i)=\frac{e^{z_i}}{\sum_{j=1}^ne^{z_j}}

只有当分类是互斥的,才可以在分类器中使用softmax函数,也就是说只能是多元分类(即数据只有一个标签),而不能是多标签分类(即一条数据可能有多个标签)。

import torch 
def test():
    x=torch.tensor([1,2])
    softmax=torch.exp(x)/torch.sum(torch.exp(x))
    print(softmax)#tensor([0.2689, 0.7311])
    pass
if __name__=="__main__":
    test()
import torch
import torch.nn as nn
import torch.nn.functional as F

# 关闭科学计数法打印
torch.set_printoptions(sci_mode=False)

def test():
    y1 = torch.tensor([-1.0, 1.0, -3.0, 3000000000.0])
    print(torch.max(y1))
    x = torch.tensor([[-1.0, 1.0, -3.0, 300000.0], [-2, 3, -3, 9]])

    y = F.softmax(x, dim=1)
    print(y)
    pass

if __name__ == "__main__":
    test()

损失函数

  • 当输出层使用softmax多分类时,使用交叉熵损失函数;

  • 当输出层使用sigmoid二分类时,使用二分类交叉熵损失函数, 比如在逻辑回归中使用;

  • 当功能为线性回归时,使用smooth L1损失函数或均方差损失-L2 loss

线性回归损失函数

1.MAE损失

MAE(Mean Absolute Error,平均绝对误差)通常也被称为 L1-Loss,通过对预测值和真实值之间的绝对差取平均值来衡量他们之间的差异

\text{MAE} = \frac{1}{n} \sum_{i=1}^{n} \left| y_i - \hat{y}_i \right|

  • n是样本的总数。

  • y_i 是第 i 个样本的真实值。

  • \hat{y}_i是第i个样本的预测值。

  • \left| y_i - \hat{y}_i \right|是真实值和预测值之间的绝对误差。

特点:

1. 鲁棒性:与均方误差(MSE)相比,MAE对异常值(outliers)更为鲁棒,因为它不会像MSE那样对较大误差平方敏感。
2. 物理意义直观:MAE以与原始数据相同的单位度量误差,使其易于解释。

应用场景:MAE通常用于需要对误差进行线性度量的情况,尤其是当数据中可能存在异常值时,MAE可以避免对异常值的过度惩罚。

import torch
import torch.nn as nn    

#初始化MAE损失函数
mae_loss = nn.L1Loss()

y_true=torch.tensor([1.0,2.0,3.0,4.0,5.0])
y_pred=torch.tensor([2.0,3.0,4.0,5.0,6.0])

loss=mae_loss(y_true,y_pred)
print(loss,loss.item())#tensor(1.) 1.0

2.MSE损失

MSE(Mean Squared Error,均方误差)通常也被称为 L2-Loss, 通过对预测值和真实值之间的误差平方取平均值,来衡量预测值与真实值之间的差异。

\text{MSE} = \frac{1}{n} \sum_{i=1}^{n} \left( y_i - \hat{y}_i \right)^2

  • n是样本的总数。
  • y_i 是第 i个样本的真实值。
  • \hat{y}_i  是第 i个样本的预测值。
  • \left( y_i - \hat{y}_i \right)^2是真实值和预测值之间的误差平方。

特点:

1. 平方惩罚:因为误差平方,MSE 对较大误差施加更大惩罚,所以 MSE 对异常值更为敏感。
2. 凸性:MSE 是一个凸函数,这意味着它具有一个唯一的全局最小值,有助于优化问题的求解。

import torch
import torch.nn as nn    

#初始化MSE损失函数
mse_loss = nn.MSELoss()

y_true=torch.tensor([1.0,2.0,3.0,4.0,5.0])
y_pred=torch.tensor([2.0,3.0,4.0,5.0,5.5])

loss=mse_loss(y_true,y_pred)
print(loss,loss.item())#tensor(0.8500) 0.8500000238418579

3.SmoothL1Loss

SmoothL1Loss可以做到在损失较小时表现为 L2 损失,而在损失较大时表现为 L1 损失。

\text{SmoothL1Loss}(x) = \begin{cases} 0.5 \cdot x^2, & \text{if } |x| < 1 \\ |x| - 0.5, & \text{otherwise} \end{cases}

x 表示预测值和真实值之间的误差,即x = y_i - \hat{y}_i

所有样本的平均损失为:\\L=\frac{1}{n} \sum_{i=1}^{n} L_{i}

 特点:

1. 平滑过渡:当误差较小时,损失函数表现为 L2 Loss(平方惩罚);当误差较大时,损失函数逐渐向 L1 Loss过渡。这种平滑过渡既能对大误差有所控制,又不会对异常值过度敏感。

2. 稳健性:对于异常值更加稳健,同时在小误差范围内提供了较好的优化效果。

import torch
import torch.nn as nn    

#创建模型的预测值和真实值
predictions = torch.Tensor([1.0,2.0,3.0])
targets=torch.Tensor([1.8,2.0,3.2])

#计算损失方式1 
smooth_loss=nn.SmoothL1Loss()
loss1=smooth_loss(predictions,targets)

#计算损失方式2
loss2=nn.functional.smooth_l1_loss(predictions,targets)

print(loss1,loss2)#tensor(0.1133) tensor(0.1133)

交叉熵损失函数 CrossEntropyLoss

使用在输出层使用softmax激活函数进行多分类时,一般都采用交叉熵损失函数。

\text{CrossEntropyLoss}(y, \hat{y}) = - \sum_{i=1}^{C} y_i \log(\hat{y}_i)

  • C 是类别的总数。
  • y是真实标签的one-hot编码向量,表示真实类别。
  • \hat{y} 是模型的输出(经过 softmax 后的概率分布)。
  • y_i是真实类别的第  i 个元素(0 或 1)。
  • - \hat{y}_i 是预测的类别概率分布中对应类别 i 的概率。

特点:

1. 概率输出:CrossEntropyLoss 通常与 softmax 函数一起使用,使得模型的输出表示为一个概率分布(即所有类别的概率和为 1)。

2. 惩罚错误分类:该损失函数在真实类别的预测概率较低时,会施加较大的惩罚,这样模型在训练时更注重提升正确类别的预测概率。

3. 多分类问题中的标准选择:在大多数多分类问题中,CrossEntropyLoss 是首选的损失函数。

应用场景:

CrossEntropyLoss 广泛应用于各种分类任务,包括图像分类、文本分类等,尤其是在神经网络模型中。

import torch
import torch.nn as nn

# 假设有三个类别,模型输出是未经softmax的logits
logits = torch.tensor([[1.5, 2.0, 0.5], [0.5, 1.0, 1.5]])

# 真实的标签
labels = torch.tensor([1, 2])  # 第一个样本的真实类别为1,第二个样本的真实类别为2

# 初始化CrossEntropyLoss
criterion = nn.CrossEntropyLoss()

# 计算损失
loss = criterion(logits, labels)
print(loss,loss.item())#tensor(0.6422) 0.6422001123428345

在这个例子中,CrossEntropyLoss 直接作用于未经 softmax 处理的 logits 输出和真实标签,PyTorch 内部会自动应用 softmax 激活函数,并计算交叉熵损失。

二分类交叉熵损失函数 BCELoss

CrossEntropyLoss 的简化版本,使用在输出层使用sigmoid激活函数进行二分类时。

\text{BinaryCrossEntropy}(y, \hat{y}) = - \left[ y \log(\hat{y}) + (1 - y) \log(1 - \hat{y}) \right]

log的底数一般默认为e,y是真实类别目标,根据公式可知L是一个分段函数 :

以上损失函数是一个样本的损失值,总样本的损失值是求损失均值即可。

import torch
import torch.nn as nn

# y 是模型的输出,已经被sigmoid处理过,确保其值域在(0,1)
y = torch.tensor([[0.7], [0.2], [0.9], [0.7]])
# targets 是真实的标签,0或1
t = torch.tensor([[1], [0], [1], [0]], dtype=torch.float)

# 计算损失方式一:
bceLoss = nn.BCELoss()
loss1 = bceLoss(y, t)

#计算损失方式二: 两种方式结果相同
loss2 = nn.functional.binary_cross_entropy(y, t)

print(loss1, loss2)#tensor(0.4723) tensor(0.4723)

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

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

相关文章

在线翻译百度,以及这三款实用便捷的翻译工具

嘿&#xff0c;朋友们&#xff0c;今天咱们来聊聊那些在日常生活和工作中不可或缺的在线翻译工具。说到这个&#xff0c;那绝对不能不提百度翻译了。那么&#xff0c;接下来就让我用口语化的方式给大家介绍一下它以及另外几款我推荐的翻译工具吧&#xff1a; 百度翻译推荐&…

CCF编程能力等级认证GESP—C++8级—20240907

CCF编程能力等级认证GESP—C1级真题 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)手套配对美丽路径 单选题&#xff08;每题 2 分&#xff0c;共 30 分&…

猿大师办公助手在线编辑Office/wps网页组件COM加载项启用说明

猿大师办公助手作为国内一款优秀的在线编辑Office插件&#xff0c;越来越受到更多客户的认可并实施了采购&#xff0c;猿大师办公助手与其他的厂商采用弹窗模式实现网页内嵌不同&#xff0c;猿大师办公助手是目前国内唯一真正实现网页内嵌本机Office的方案&#xff0c;效果如下…

怎样将vue项目 部署在ngixn的子目录下

如果同一服务器的80端口下,需要部署两个或以上数量的vue项目,那么就需要将其中一个vue项目部署在根目录下,其他的项目部署在子目录下. 像这样的配置 访问根目录 / 访问灭火器后台管理,访问 /mall/ 访问商城的后台管理 那么商场的vue项目,这样配置,才能在/mall/下正常访问? 1…

华为 HCIP-Datacom H12-821 题库 (10)

有需要题库的可以看主页置顶 V群进行学习交流 1.缺省情况下&#xff0c;BGP 对等体邻接关系的保持时间是多少秒&#xff1f; A、120 秒 B、60 秒 C、10 秒 D、180 秒 答案&#xff1a;D 解析&#xff1a; BGP 存活消息每隔 60 秒发一次&#xff0c;保持时间“180 秒” 2.缺省…

【Unity】简易而又实用的抽卡算法

1.两个数中任选一个&#xff08;抛硬币&#xff09; 基础版本&#xff1a; public int RandomBetweenTwoNumber(int a,int b) {float random Random.Range(0,1f);return radom<0.5f ? a : b ; } 升级版本&#xff08;支持概率调整&#xff09;&#xff1a; /*pa表示“…

MATLAB精美绘图详解

目录 一、常见二维图形绘制 二、常见三维图形绘制 三、图形修饰与处理 四、动画制作 五、常见绘图种类与特点总结 总结 MATLAB提供了非常丰富的绘图功能&#xff0c;不仅可以用于二维、三维的基本图形绘制&#xff0c;还包括特殊图形、动画制作等多种功能。在本文中&#…

Flutter框架——2.状态-路由-包-资源

文章参考了Flutter中国开源项目发起人杜文&#xff08;网名wendux&#xff09;创作的一本系统介绍Flutter技术的中文书籍《Flutter实战第二版》&#xff0c;网址&#xff1a;第二版序 | 《Flutter实战第二版》 https://book.flutterchina.club/#第二版变化 文章目录 一、状态管…

使用MATLAB进行动力学分析与可视化

目录 一、动力学与MATLAB概述 二、动力学系统的建模 1. 简谐振子 2. 单摆 三、动力学系统的仿真 1. 使用ode45求解简谐振子 2. 使用ode45求解单摆 四、动力学结果的可视化 1. 二维曲线图 2. 相空间图 3. 三维曲面图 4. 动画制作 五、复杂动力学系统的建模与仿真 1…

3、Hadoop部署

1、 Hadoop部署 1&#xff09;集群部署规划 注意&#xff1a;NameNode和SecondaryNameNode不要安装在同一台服务器 注意&#xff1a;ResourceManager也很消耗内存&#xff0c;不要和NameNode、SecondaryNameNode配置在同一台机器上。 hadoop102 hadoop103 hadoop104 HDFS…

SSM框架学习(二:SpringFramework实战指南)

目录 一、SpringFramework介绍 1.总体技术体系 &#xff08;1&#xff09;单一架构 &#xff08;2&#xff09; 分布式架构 2.Spring 和 SpringFramework概念 &#xff08;1&#xff09;广义的 Spring&#xff1a;Spring 技术栈&#xff08;全家桶&#xff09; &#xff…

【ARM】如何通过 KeilMDK 查看芯片的硬件信息

【更多软件使用问题请点击亿道电子官方网站】 文档目标&#xff1a;解决在开发过程中对于开发项目所使用的的芯片的参数查看的问题 问题场景&#xff1a;在项目开发过程中&#xff0c;经常需要对于芯片的时钟、寄存器或者一些硬件参数需要进行确认。大多数情况下是需要外部查找…

AI边缘控制器:重塑工业自动化与控制的新篇章

在智能制造和工业4.0的浪潮下&#xff0c;AI边缘控制器作为新一代智能控制设备&#xff0c;正逐步成为推动工业自动化与数字化转型的关键力量。这类基于x86架构的高性能IPC&#xff08;工业个人计算机&#xff09;形态产品&#xff0c;不仅继承了传统PC的可扩展性、开放性和可视…

Android SystemUI组件(06)导航栏创建分析虚拟按键

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节的思维导图&#xff0c;主要关注左侧SystemBars分析中导航栏部分即可。 1 导航栏创建之makeStatusBarView 通过上一篇文章的…

闯关leetcode——9. Palindrome Number

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/palindrome-number/description/ 内容 Given an integer x, return true if x is a palindrome, and false otherwise. Example 1: Input: x 121 Output: true Explanation: 121 reads as 121 f…

Windows 10/11 Raspberry Pi PICO (RP2040) VScode开发环境搭建

Windows 10/11 Raspberry Pi PICO VScode开发环境搭建 概述下载树莓派官方开发环境配置工具安装开发环境 概述 下载树莓派官方开发环境配置工具 pico-setup-windows 点击"Download the lastest release" 下载文件为&#xff1a;《pico-setup-windows-x64-standalo…

Gz会员卡检索不到充值记录的处理方法

会员卡预收款查询报表&#xff08;9508&#xff09;中输入会员卡号后检索不到该卡的充值记录&#xff0c;在MemberCard表中检索到该会员卡&#xff0c;将PriorityID值改为0即可检索。 下图为检索后的结果。

ElasticSearch7.8下载、安装教程

文章目录 前言一、Windows安装ElasticSearch7.8二、Elasticsearch-head安装三、Kibana安装 前言 本文章演示elasticSearch7.8、elasticSearch-head(插件模式)、kibana的Windows下载、安装教程。安装前&#xff0c;请检查电脑是否已经安装好node环境和JDK环境。 一、Windows安装…

【Kubernetes】K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制

K8s 的鉴权管理&#xff08;二&#xff09;&#xff1a;基于属性 / 节点 / Webhook 的访问控制 1.基于属性的访问控制&#xff08;ABAC 鉴权&#xff09;2.基于节点的访问控制&#xff08;node 鉴权&#xff09;2.1 读取操作2.2 写入操作 3.基于 Webhook 的访问控制3.1 基于 We…

tekton pipeline workspaces

tekton pipeline workspace是一种为执行中的管道及其任务提供可用的共享卷的方法。 在pipeline中定义worksapce作为共享卷传递给相关的task。在tekton中定义workspace的用途有以下几点: 存储输入和/或输出在task之间共享数据secret认证的挂载点ConfigMap中保存的配置的挂载点…