交叉熵损失函数的使用

交叉熵损失函数

交叉熵损失函数(Cross-Entropy Loss),也称为对数损失(Log Loss),是机器学习和深度学习中常用的损失函数之一,尤其在分类问题中。它衡量的是模型预测的概率分布与真实标签的概率分布之间的差异。

为什么要写一期交叉熵损失函数,是因为在基于pytorch本地部署微调bert模型(yelp文本分类数据集)-优快云博客这个项目的coding过程中,错误的使用了pytorch的CrossEntropyLoss这个函数,在一周多的时间内自我怀疑Bert的微调是否能够成功,最后发现是损失函数使用错误的问题


计算公式

L=\sum_{i}^{n} (y(i)\times log(P(i)))

代码实现

import torch
import torch.nn as nn

# 假设模型输出的logits
logits = torch.tensor([[2.0, 1.0, 0.5]])  # 形状为 [1, 3]
# 真实标签,类别为2
labels = torch.tensor([2])  # 形状为 [1]

# 定义损失函数
criterion = nn.CrossEntropyLoss()

# 计算损失
loss = criterion(logits, labels)

print(loss.item())  # 输出损失值

千万注意,函数中的两个参数是不同的维度,label会在函数内部自行进行one-hot编码,而logits(一般认为是模型的输出值)是一维的向量,每一个批次输出分类数量的向量表示,所以对于logits是不需要进行处理的!


<think>嗯,用户想知道在使用交叉熵损失函数时如何进行初始设置,包括参数配置和适用场景的最佳实践。首先,我需要回忆交叉熵损失函数的基本概念和应用场景。交叉熵通常用于分类任务,特别是多分类问题,和Softmax激活函数结合使用。所以,初始化可能需要考虑与Softmax配合的情况。 然后,参数初始化对模型训练的影响很大,比如Xavier和He初始化这些方法。用户提到的引用里有提到Xavier初始化和随机初始化,这些可能是关键点。需要确定不同初始化方法适用的场景,比如Xavier适合Sigmoid和Tanh,而He适合ReLU及其变体。 接下来,交叉熵损失函数本身不涉及参数,所以初始化主要是指网络权重的初始化。需要结合不同的激活函数来推荐初始化方法。比如,如果使用全连接层后接Softmax,那么前面的层应该用哪种初始化? 另外,用户可能想知道具体的代码示例,比如在PyTorch中如何实现这些初始化。引用里的例子用了torch.nn.init.uniform_和normal_,还有提到Xavier初始化,这些需要具体说明。 还要考虑适用场景,比如图像分类、自然语言处理中如何使用不同的初始化方法。可能需要提到不同的网络结构,比如CNN和RNN,适用的初始化可能不同。 另外,防止梯度消失或爆炸也是初始化的重要目标,需要解释为什么某些初始化方法有助于稳定训练。比如,Xavier初始化考虑输入和输出的维度,保持方差一致,避免梯度问题。 可能还需要提到偏置的初始化,通常初始化为0或小的常数,比如0.01,尤其是在ReLU之前,避免神经元死亡。 最后,总结最佳实践,比如结合激活函数选择初始化方法,数据预处理的重要性,以及监控训练过程来调整初始化参数。还要确保引用正确,用户提供的引用中有三个,需要对应到相关内容。</think>在使用交叉熵损失函数时,参数初始化的核心目标是使神经网络在前向传播时保持激活值的合理分布,避免梯度消失或爆炸。以下是具体步骤和最佳实践: --- ### 一、参数初始化方法选择 1. **全连接层初始化** - **Xavier/Glorot初始化**:适用于$tanh$、$sigmoid$等饱和激活函数 $$W \sim \mathcal{U}\left(-\sqrt{\frac{6}{n_{in}+n_{out}}}, \sqrt{\frac{6}{n_{in}+n_{out}}}\right)$$ ```python torch.nn.init.xavier_uniform_(layer.weight) ``` - **He/Kaiming初始化**:更适合$ReLU$及其变体(如交叉熵常配合的最后一层前激活) $$W \sim \mathcal{N}\left(0, \sqrt{\frac{2}{n_{in}}}\right)$$ ```python torch.nn.init.kaiming_normal_(layer.weight, mode='fan_in', nonlinearity='relu') ``` 2. **卷积层初始化** 推荐使用He初始化,因其能处理局部连接特性: ```python torch.nn.init.kaiming_normal_(conv.weight, mode='fan_out', nonlinearity='relu') ``` 3. **偏置项初始化** 通常设为0或微小常数(如$0.01$),避免初始阶段激活值全为负: ```python torch.nn.init.constant_(layer.bias, 0.01) ``` --- ### 二、与Softmax的协同配置 当交叉熵损失配合Softmax使用时,需注意: 1. **最后一层权重初始化**应适当缩小范围(如标准差$0.01$的正态分布),避免Softmax饱和 ```python torch.nn.init.normal_(last_layer.weight, mean=0, std=0.01) ``` 2. **避免最后一层使用ReLU**,推荐线性激活或低温度参数设置[^1] --- ### 三、适用场景最佳实践 | 场景 | 推荐初始化 | 理论依据 | |------|------------|----------| | 图像分类(CNN) | He初始化 | 处理ReLU的负半轴抑制特性[^3] | | 自然语言处理(RNN) | 正交初始化 | 保持时间步间梯度稳定性 | | 浅层网络 | Xavier初始化 | 平衡输入输出方差[^2] | | 残差网络 | Zero-Centered初始化 | 保持跳跃连接有效性 | --- ### 四、代码实现示例(PyTorch) ```python import torch.nn as nn class Classifier(nn.Module): def __init__(self, input_dim=784, num_classes=10): super().__init__() self.fc1 = nn.Linear(input_dim, 512) self.fc2 = nn.Linear(512, num_classes) # 初始化配置 nn.init.kaiming_normal_(self.fc1.weight, nonlinearity='relu') nn.init.constant_(self.fc1.bias, 0.01) nn.init.normal_(self.fc2.weight, std=0.01) # 最后一层缩小初始化范围 nn.init.zeros_(self.fc2.bias) # 分类层偏置可置零 self.relu = nn.ReLU() def forward(self, x): x = self.relu(self.fc1(x)) return self.fc2(x) ``` --- ### 五、验证与调试 1. **激活值监测**:使用TensorBoard等工具观察第一层激活值的均值和方差,理想范围: - 均值接近$0$(绝对值$<0.5$) - 方差保持在$0.8-1.2$之间 2. **梯度检查**:反向传播后梯度范数不应出现指数级增长/衰减 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值