尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PyTorch逻辑斯蒂回归:从二分类到多分类的深度学习入门实践

PyTorch逻辑斯蒂回归:从二分类到多分类的深度学习入门实践 1. 从“分类”到“回归”逻辑斯蒂回归的本质探析如果你刚开始接触深度学习看到“逻辑斯蒂回归”这个名字可能会有点困惑。它明明叫“回归”为什么几乎所有教程都把它放在分类问题里讲我第一次学的时候也卡在这里后来才明白这个名字其实是个“历史遗留问题”。它的核心任务确实是做分类尤其是二分类。那“回归”体现在哪呢它回归的是“概率”。简单来说逻辑斯蒂回归模型并不直接输出“是”或“否”的标签而是输出一个介于0和1之间的概率值这个概率值表示样本属于正类比如“是狗”的可能性。然后我们再设定一个阈值通常是0.5当概率大于阈值时判定为正类反之则为负类。这个将线性模型的输出“映射”到概率区间的过程就是它被称为“回归”的原因——它是对概率的回归预测。在PyTorch的生态里逻辑斯蒂回归常常是我们告别“Hello World”级别的全连接网络后遇到的第一个有明确应用场景、且能直观理解其数学美的模型。它结构极其简单一个线性层nn.Linear加上一个Sigmoid激活函数nn.Sigmoid。但千万别小看它这个简单的组合是理解更复杂神经网络比如多层感知机MLP的基石。线性层负责学习特征与目标之间的线性关系而Sigmoid函数则充当了“概率压缩器”把线性层输出的任意实数“挤压”到(0,1)区间内完美符合概率的定义。为什么从它开始学PyTorch深度学习特别合适第一它的损失函数——二元交叉熵损失nn.BCELoss——是分类任务中最核心、最常用的损失函数之一理解它对于后续学习多分类交叉熵损失至关重要。第二它的训练流程准备数据、定义模型、计算损失、反向传播、更新参数是所有深度学习模型的通用范式。在这个简单的模型上把流程跑通、理解透以后再面对ResNet、Transformer这些“庞然大物”时你就不会发怵因为训练的内核逻辑是一样的。第三它的可解释性相对较强你可以清晰地看到每个输入特征前的权重系数大致理解模型是如何做出判断的这对于建立对模型的直觉非常有帮助。2. 核心组件拆解线性层、Sigmoid与损失函数要亲手实现逻辑斯蒂回归我们必须吃透它的三个核心部件线性变换、Sigmoid函数和二元交叉熵损失。这就像搭积木每一块是什么形状、起什么作用必须门儿清。2.1 线性层特征的加权求和在PyTorch中线性层由torch.nn.Linear(in_features, out_features)实现。对于逻辑斯蒂回归这个二分类任务out_features就是1因为我们只需要输出一个标量值通常称为logits即未归一化的分数。假设我们的输入数据是一个特征向量有n个特征那么线性层做的就是最基础的线性加权求和z w1*x1 w2*x2 ... wn*xn b这里w1, w2, ..., wn是模型要学习的权重Weightb是偏置Bias。z就是线性层的输出。这个操作的本质是在特征空间里寻找一个最优的“分割超平面”。对于二维数据就是找一条最优的直线对于三维数据就是找一个最优的平面。所有z 0的点模型初步判断它可能属于正类所有z 0的点则初步判断属于负类。在实际编码时我们通常不会手动计算这个加权和。定义一个线性层后直接像函数一样调用它即可import torch.nn as nn linear_layer nn.Linear(in_features10, out_features1) # 假设输入有10个特征 input_tensor torch.randn(32, 10) # 一个批次batch有32个样本每个样本10维 output_z linear_layer(input_tensor) # output_z 的形状是 [32, 1]这里有一个新手容易忽略的细节nn.Linear在初始化时其权重w和偏置b已经被自动赋予了随机初始值通常是均匀分布或正态分布。我们的训练过程就是通过梯度下降不断调整这些w和b使得模型的预测越来越准。2.2 Sigmoid函数将分数压缩为概率线性层输出的z可以是任意实数从负无穷到正无穷这显然不符合概率在[0,1]之间的要求。Sigmoid函数就是用来解决这个问题的“激活函数”。它的数学表达式是σ(z) 1 / (1 e^{-z})它的图像是一条光滑的、从0增长到1的S型曲线。无论输入z多大或多小输出都会被“挤压”到(0,1)之间。当z0时σ(z)0.5z趋向正无穷时σ(z)无限接近1z趋向负无穷时σ(z)无限接近0。这个特性完美地将线性模型的输出解释成了“属于正类的概率”。在PyTorch中我们可以直接使用nn.Sigmoid()模块。sigmoid nn.Sigmoid() probabilities sigmoid(output_z) # probabilities 形状也是 [32, 1]每个值在(0,1)之间现在probabilities里的每一个值就代表了对应样本属于正类的预测概率。例如probabilities[0] 0.8意味着模型认为第一个样本有80%的可能性是正类。注意Sigmoid函数在z的绝对值很大时曲线会变得非常平缓这会导致其梯度导数接近于0这个问题被称为“梯度饱和”或“梯度消失”。虽然在简单的逻辑斯蒂回归中这个问题不突出但它是理解更深度网络中梯度问题的重要起点。在深层网络中我们通常会使用ReLU等函数来缓解此问题。2.3 二元交叉熵损失衡量概率预测的差距模型给出了预测概率我们如何衡量它预测得好不好呢这就需要损失函数Loss Function。对于二分类概率预测最标准、最常用的就是二元交叉熵损失Binary Cross-Entropy Loss, BCELoss。它的思想很直观对于真实标签为1正类的样本如果模型预测的概率ŷ也接近1那么损失就很小如果ŷ接近0损失就会非常大。反之对于真实标签为0负类的样本ŷ越接近0损失越小越接近1损失越大。其数学公式为BCELoss - [y * log(ŷ) (1 - y) * log(1 - ŷ)]其中y是真实标签0或1ŷ是预测概率。PyTorch中对应的类是nn.BCELoss。使用时有一个至关重要的细节nn.BCELoss的输入ŷ必须是经过了Sigmoid激活后的概率值范围必须在(0,1)内。如果你把线性层输出的logits未经过Sigmoid直接扔给BCELoss程序会报错或者得到错误的结果。criterion nn.BCELoss() # 定义损失函数 # 假设 labels 是形状为 [32, 1] 的真实标签值为0或1 loss criterion(probabilities, labels) # 计算损失为了编程方便PyTorch还提供了nn.BCEWithLogitsLoss。这个损失函数内部集成了Sigmoid激活。这意味着你可以直接把线性层输出的logits传给它它会在计算损失前自动进行Sigmoid变换。这样做在数值计算上更稳定避免了可能出现的log(0)问题是更推荐的做法。criterion_with_logits nn.BCEWithLogitsLoss() loss criterion_with_logits(output_z, labels) # 直接使用线性层的输出无需手动Sigmoid我个人的经验是在绝大多数二分类场景下直接使用BCEWithLogitsLoss是更优的选择代码更简洁且数值稳定性更好。3. 实战构建从数据准备到模型训练全流程理论清楚了我们来看一个完整的实战例子。假设我们要根据花瓣长度和宽度这两个特征来预测一朵花是否为鸢尾花中的Setosa品种这是一个经典的二分类问题简化版。我们将使用PyTorch完成从数据到训练的所有步骤。3.1 数据准备与Dataset构建深度学习的第一步永远是处理数据。PyTorch提供了torch.utils.data.Dataset和DataLoader这两个强大的工具来帮我们高效地组织和管理数据。首先我们需要一个自定义的Dataset类来加载和封装我们的数据。这个类必须实现__len__和__getitem__两个方法。import torch from torch.utils.data import Dataset, DataLoader import numpy as np from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split class IrisBinaryDataset(Dataset): def __init__(self, features, labels): 初始化函数。 Args: features: 特征数据numpy数组或PyTorch张量。 labels: 标签数据0或1。 # 将数据转换为PyTorch张量并指定浮点类型模型参数通常是float32 self.features torch.tensor(features, dtypetorch.float32) self.labels torch.tensor(labels, dtypetorch.float32).view(-1, 1) # 将标签从 [N] 变为 [N, 1]与模型输出对齐 def __len__(self): # 返回数据集的样本总数 return len(self.labels) def __getitem__(self, idx): # 根据索引返回一个样本特征标签 return self.features[idx], self.labels[idx] # 使用sklearn加载鸢尾花数据集并构造一个二分类问题Setosa vs 非Setosa iris load_iris() X iris.data[:, :2] # 只取前两个特征花瓣长度和宽度以便可视化 y (iris.target 0).astype(np.float32) # 将Setosa类target0标记为1其他标记为0 # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 创建Dataset实例 train_dataset IrisBinaryDataset(X_train, y_train) test_dataset IrisBinaryDataset(X_test, y_test) # 创建DataLoader它负责在训练时按批次提供数据并支持打乱shuffle等操作 train_loader DataLoader(train_dataset, batch_size16, shuffleTrue) test_loader DataLoader(test_dataset, batch_size16, shuffleFalse)这里有几个关键点数据类型务必确保特征和标签都是torch.float32类型。模型参数默认是float32如果数据类型不匹配会导致错误。标签形状逻辑斯蒂回归模型的输出是[batch_size, 1]因此标签也最好处理成相同的形状[batch_size, 1]使用.view(-1, 1)可以轻松实现。DataLoader的shuffle训练时一定要shuffleTrue这能防止模型因为数据顺序而产生偏见有助于提升训练效果和泛化能力。测试时则设为False保证评估的一致性。3.2 模型定义与训练循环数据准备好了接下来定义模型。逻辑斯蒂回归模型在PyTorch中就是一个简单的nn.Module子类。import torch.nn as nn class LogisticRegressionModel(nn.Module): def __init__(self, input_dim): super(LogisticRegressionModel, self).__init__() # 定义一个线性层输出维度为1 self.linear nn.Linear(input_dim, 1) # 注意我们不再显式定义Sigmoid层因为将使用BCEWithLogitsLoss def forward(self, x): # 前向传播输入x - 线性层 - 输出logits logits self.linear(x) return logits # 返回的是未经过Sigmoid的分数 # 初始化模型、损失函数和优化器 input_dim X_train.shape[1] # 输入特征维度这里是2 model LogisticRegressionModel(input_dim) criterion nn.BCEWithLogitsLoss() # 使用带Logits的损失函数 optimizer torch.optim.SGD(model.parameters(), lr0.1) # 随机梯度下降优化器学习率设为0.1现在进入最核心的训练循环。这个过程体现了深度学习训练的标准范式num_epochs 100 # 整个数据集遍历100次 train_losses [] # 记录每个epoch的训练损失 for epoch in range(num_epochs): model.train() # 将模型设置为训练模式影响某些层如Dropout、BatchNorm本例中无影响但习惯要好 epoch_loss 0.0 # 按批次遍历训练数据 for batch_features, batch_labels in train_loader: # 1. 梯度清零PyTorch会累积梯度每次计算新批次前必须清零 optimizer.zero_grad() # 2. 前向传播计算预测值logits logits model(batch_features) # 3. 计算损失 loss criterion(logits, batch_labels) # 4. 反向传播计算损失关于模型参数的梯度 loss.backward() # 5. 优化器更新参数根据梯度调整权重w和偏置b optimizer.step() # 累加本批次的损失 epoch_loss loss.item() * batch_features.size(0) # loss.item()是标量乘以batch大小得到总损失 # 计算本epoch的平均损失 avg_epoch_loss epoch_loss / len(train_dataset) train_losses.append(avg_epoch_loss) # 每10个epoch打印一次损失 if (epoch 1) % 10 0: print(fEpoch [{epoch1}/{num_epochs}], Loss: {avg_epoch_loss:.4f})这个循环是深度学习的“心脏”。zero_grad()、forward、loss、backward()、step()这五个步骤在训练任何神经网络时都会反复出现。理解每一步的作用至关重要zero_grad()清空上一轮计算留下的梯度。如果不清理梯度会不断累积导致更新方向错误。forward调用模型的forward方法计算预测值。loss用预测值和真实标签计算损失衡量模型当前的表现。backward()自动微分引擎Autograd开始工作从损失值开始反向计算模型中每一个可训练参数w和b的梯度。这是PyTorch的核心魔法。step()优化器这里是SGD根据计算出的梯度和我们设定的学习率lr按照w w - lr * gradient的规则更新所有参数。3.3 模型评估与预测训练完成后我们需要评估模型在未见过的测试集上的表现并学会如何使用它进行预测。def evaluate_model(model, data_loader): model.eval() # 将模型设置为评估模式 correct 0 total 0 with torch.no_grad(): # 关闭梯度计算节省内存和计算资源 for features, labels in data_loader: logits model(features) # 使用torch.sigmoid将logits转换为概率 probabilities torch.sigmoid(logits) # 将概率转换为预测类别0.5为正类否则为负类 predictions (probabilities 0.5).float() total labels.size(0) correct (predictions labels).sum().item() accuracy 100 * correct / total return accuracy test_accuracy evaluate_model(model, test_loader) print(fTest Accuracy: {test_accuracy:.2f}%) # 进行单个样本的预测 sample_feature torch.tensor([[5.1, 3.5]], dtypetorch.float32) # 一个样本两个特征 model.eval() with torch.no_grad(): logit model(sample_feature) probability torch.sigmoid(logit).item() # 获取概率标量值 predicted_class 1 if probability 0.5 else 0 print(f预测概率: {probability:.4f}, 预测类别: {predicted_class})在评估和预测阶段有两点必须注意model.eval()这会通知模型中的某些特定层如Dropout、BatchNorm切换到推理模式。对于我们的逻辑斯蒂回归虽然没有这些层但养成这个习惯非常重要。with torch.no_grad():这个上下文管理器会禁用梯度跟踪。在评估和预测时我们不需要计算梯度禁用它可以显著减少内存消耗并加速计算。4. 关键参数解析与调优经验逻辑斯蒂回归虽然简单但训练过程中几个关键参数的选择会直接影响模型的收敛速度和最终性能。这里结合我的经验详细拆解一下。4.1 学习率训练过程的“油门”与“刹车”学习率Learning Ratelr可能是最重要的超参数。它决定了每次参数更新的步长。你可以把它想象成下山时的步幅步幅太大学习率太高你可能会在谷底最优点两侧来回跳跃甚至无法收敛步幅太小学习率太低下山速度会非常慢需要很久才能到达谷底甚至可能卡在某个小坑局部最优点里出不来。对于逻辑斯蒂回归这种简单的凸优化问题我们通常可以使用一个固定的、相对较大的学习率。在上面的例子中我设置了lr0.1。这是一个经验值对于许多使用SGD优化器的简单任务来说0.01到0.1是一个常见的试探范围。如何判断学习率是否合适学习率过高训练损失曲线会剧烈震荡甚至随着训练进行损失不降反增发散。你会看到Loss值上蹿下跳无法稳定下降。学习率过低训练损失下降得非常缓慢可能训练了很多个epoch损失几乎没变化收敛速度让人无法接受。一个实用的技巧是使用学习率调度器Learning Rate Scheduler。PyTorch的torch.optim.lr_scheduler模块提供了多种策略。例如StepLR可以在每训练一定步数后将学习率乘以一个衰减因子gamma。optimizer torch.optim.SGD(model.parameters(), lr0.1) scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_size30, gamma0.1) # 在训练循环的每个epoch结束后调用 for epoch in range(num_epochs): # ... 训练步骤 ... scheduler.step() # 更新学习率这样模型在初期可以用较大的学习率快速逼近最优解后期用较小的学习率精细调整有助于获得更好的性能。对于新手我建议先从固定学习率开始等对训练过程有感觉后再尝试加入调度器。4.2 优化器选择SGD与Adam之争我们例子中使用了最经典的随机梯度下降SGD。它简单直接但有时收敛较慢且对学习率比较敏感。在更复杂的场景下人们更倾向于使用自适应优化器如Adam。Adam优化器结合了动量Momentum和自适应学习率的思想。动量可以帮助“冲过”一些局部最优点或平坦区域而自适应学习率可以为每个参数单独调整更新步长。对于逻辑斯蒂回归SGD通常足够好但了解Adam很有必要因为它是当前深度学习领域的默认优化器之一。# 使用Adam优化器 optimizer_adam torch.optim.Adam(model.parameters(), lr0.001) # Adam的初始学习率通常设得更小如0.001Adam的优点在于它往往对初始学习率不那么敏感在很多任务上能更快收敛。但它的缺点是有时可能在训练集上收敛得很好在测试集上的泛化性能却略逊于精心调参的SGD。我的经验法则是对于新任务可以先从Adamlr0.001或0.0001开始它能提供一个不错的基线。如果追求极致的性能或者模型非常简单如逻辑回归可以再尝试调优SGD。4.3 权重初始化与正则化的考量对于逻辑斯蒂回归我们通常不需要担心权重初始化问题因为nn.Linear默认的初始化方式如Kaiming均匀分布对于这种浅层网络已经足够好。但在构建更深网络时初始化就变得至关重要。另一个相关的概念是正则化Regularization它的目的是防止模型过拟合在训练集上表现太好在测试集上表现差。逻辑斯蒂回归最常用的正则化是L2正则化在PyTorch的优化器中可以通过weight_decay参数轻松实现。optimizer torch.optim.SGD(model.parameters(), lr0.1, weight_decay1e-4)weight_decay参数本质上就是在损失函数中增加了一项λ * ||w||^2L2范数的平方λ就是weight_decay的值。这会惩罚过大的权重鼓励模型学习到更简单、更平滑的决策边界从而提升泛化能力。当你的模型在训练集上准确率很高但在测试集上明显下降时可以尝试加入一个较小的weight_decay如1e-4, 1e-5。5. 从二分类到多分类Softmax回归的自然延伸逻辑斯蒂回归解决了二分类问题那如果有三个或更多的类别呢比如鸢尾花数据集本身就有Setosa, Versicolor, Virginica三个类别。这时逻辑斯蒂回归的扩展——Softmax回归或称多项逻辑斯蒂回归就登场了。Softmax回归的核心变化在于输出层和损失函数输出层线性层的输出维度out_features变为类别数C例如3。现在模型为每个类别都输出一个logit分数。激活函数使用Softmax函数代替Sigmoid。Softmax函数将C个logits转换成一个概率分布确保所有类别的概率之和为1。Softmax(z_i) e^{z_i} / Σ_{j1}^{C} e^{z_j}损失函数使用交叉熵损失nn.CrossEntropyLoss。请注意PyTorch的CrossEntropyLoss已经内部集成了Softmax计算。这意味着在定义模型时输出层之后不需要再手动添加nn.Softmax。损失函数会先对输入的logits做Softmax再计算交叉熵损失。import torch.nn as nn import torch.nn.functional as F class SoftmaxRegressionModel(nn.Module): def __init__(self, input_dim, num_classes): super(SoftmaxRegressionModel, self).__init__() self.linear nn.Linear(input_dim, num_classes) # 输出维度等于类别数 def forward(self, x): logits self.linear(x) return logits # 直接返回logits不进行Softmax # 对于3分类的鸢尾花问题 model_multi SoftmaxRegressionModel(input_dim4, num_classes3) # 使用全部4个特征 criterion_multi nn.CrossEntropyLoss() # 使用交叉熵损失 # 训练时标签应该是LongTensor类型并且是类别的索引0, 1, 2而不是one-hot编码 # 假设 labels 是形状为 [batch_size] 的LongTensor值为0, 1, 2 # logits 形状为 [batch_size, 3] loss criterion_multi(logits, labels) # 预测时需要手动对logits应用Softmax以得到概率 model_multi.eval() with torch.no_grad(): logits model_multi(some_features) probabilities F.softmax(logits, dim1) # 在类别维度dim1上应用Softmax predicted_class torch.argmax(probabilities, dim1) # 取概率最大的类别索引这里的关键区别和易错点标签格式对于CrossEntropyLoss标签必须是torch.LongTensor类型并且是类别的索引例如012不能是one-hot编码。损失函数内部会处理。模型输出模型forward方法直接返回logits不要在最后加nn.Softmax层。因为CrossEntropyLoss内部包含了更数值稳定的Softmax计算。预测阶段在模型评估或预测时如果需要概率值则要显式调用F.softmax(logits, dim1)。dim1表示在第二个维度类别维度上进行Softmax计算。从二分类的逻辑斯蒂回归过渡到多分类的Softmax回归是理解神经网络分类任务的一个关键阶梯。你会发现后续的复杂神经网络如CNN、RNN在做分类时其最后一层和损失函数的使用方式与Softmax回归是完全一致的。掌握了这个你就掌握了深度学习分类模型的“标准接口”。6. 常见问题排查与调试技巧即使流程看起来很简单实际编码时也难免会遇到各种问题。下面我总结几个在实现逻辑斯蒂回归时最常见的问题和调试方法。6.1 损失不下降或输出为NaN这是新手最常遇到的问题。损失值在第一轮迭代后就变成NaN或者始终在一个很高的值附近波动不下降。可能原因及解决方案学习率过高这是首要怀疑对象。尝试将学习率大幅降低比如从0.1降到0.01甚至0.001。数据未归一化/标准化如果输入特征的尺度差异巨大比如一个特征范围是[0,1]另一个是[100,1000]会导致梯度更新不稳定。解决方案是对每个特征进行标准化处理使其均值为0标准差为1。from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 注意使用训练集的均值和标准差来转换测试集损失函数使用错误这是最经典的坑。错误使用nn.BCELoss但传入的是线性层的logits未经过Sigmoid。正确要么使用nn.BCELoss并手动对模型输出做Sigmoid要么直接使用nn.BCEWithLogitsLoss并传入logits。务必仔细检查。标签格式错误对于二分类使用BCEWithLogitsLoss时标签应该是float32或float64类型且形状与模型输出匹配如[batch_size, 1]。如果标签是整型如torch.LongTensor的0和1需要转换为浮点型.float()。6.2 模型过拟合与欠拟合的判断欠拟合Underfitting模型在训练集和测试集上的表现都很差例如准确率都低于60%。这说明模型太简单无法捕捉数据中的规律。对于逻辑斯蒂回归这可能意味着特征与目标之间并非简单的线性关系。解决方案可以考虑1增加更多有效的特征2使用更复杂的模型如神经网络。过拟合Overfitting模型在训练集上表现非常好例如准确率95%但在测试集上表现显著变差。这说明模型“死记硬背”了训练数据包括其中的噪声而缺乏泛化能力。解决方案1收集更多训练数据2使用正则化如设置优化器的weight_decay参数3如果特征很多可以尝试特征选择。一个简单的诊断方法是绘制训练损失和验证损失随epoch变化的曲线。如果训练损失持续下降但验证损失在某个点后开始上升那就是典型的过拟合信号。6.3 梯度消失与数值稳定性虽然逻辑斯蒂回归层数浅不易出现深度网络中的梯度消失问题但了解其原理有益无害。Sigmoid函数在输入值很大或很小时梯度会趋近于0。如果线性层初始化的权重过大导致logits绝对值很大经过Sigmoid后梯度就会很小从而使得参数更新缓慢。使用BCEWithLogitsLoss而不是BCELoss Sigmoid的一个主要原因就是PyTorch在实现BCEWithLogitsLoss时采用了数值稳定的计算方式将Sigmoid和交叉熵的计算合并避免了在极端概率值接近0或1下计算log(0)导致的数值问题。这再次印证了使用BCEWithLogitsLoss是最佳实践。7. 超越基础逻辑斯蒂回归的现代应用与思考你可能觉得逻辑斯蒂回归太“古老”了在深度学习时代是否已经过时恰恰相反它不仅在很多场景下仍是有效的基线模型Baseline其思想更是渗透在深度学习的各个角落。1. 作为深度网络的“最后一公里”在图像分类、语音识别、自然语言处理等任务中复杂的深度神经网络如CNN、Transformer通常负责从原始数据中提取高层次的特征。而这些特征最终被送入一个全连接层本质就是线性层再接上一个Softmax多分类或Sigmoid多标签分类函数来产生最终的类别概率。这个“最后一层”的结构就是逻辑斯蒂回归/Softmax回归。所以学好它是理解任何现代分类模型输出部分的基石。2. 可解释性与特征重要性相比于“黑箱”般的深度神经网络逻辑斯蒂回归的权重向量w具有直观的解释性。w中每个元素的绝对值大小可以近似看作对应特征对预测结果的重要性。虽然深度网络中间层的权重难以解释但通过一些方法如集成梯度、LIME对模型决策进行归因时其思想也部分源于此。3. 处理不平衡数据的技巧在实际项目中正负样本数量可能极度不平衡例如欺诈检测中欺诈交易远少于正常交易。这时标准的交叉熵损失可能会被多数类主导。一个常见的技巧是为BCEWithLogitsLoss或CrossEntropyLoss设置pos_weight参数给予少数类样本更高的权重让模型更关注它们。# 假设正类样本数量是负类的10倍我们希望平衡其影响 pos_weight torch.tensor([10.0]) # 对于二分类pos_weight是一个标量或形状为[1]的张量 criterion nn.BCEWithLogitsLoss(pos_weightpos_weight)逻辑斯蒂回归就像一把精密的瑞士军刀它简单、可靠、易于理解。在开始构建更炫酷的深度学习模型之前花时间彻底掌握它确保训练流程的每个环节都了然于胸这份扎实的基础会让你在后续的学习中事半功倍。当你能够不假思索地写出一个逻辑斯蒂回归的训练循环并清楚地解释每一行代码的作用时你就已经拿到了打开深度学习大门的钥匙。
返回列表