逻辑回归模型

二分类逻辑回归(Logistic Regression)是一种广泛应用于二分类问题的统计模型。尽管名字中带有“回归”二字,但它实际上是一种分类算法。逻辑回归通过拟合一个 S 形曲线(Sigmoid 函数)来预测样本属于某一类别的概率。

逻辑回归(Logistic Regression)是一种广泛应用于二分类问题的统计模型。尽管名字中带有“回归”二字,但它实际上是一种分类算法。逻辑回归通过拟合一个 S 形曲线(Sigmoid 函数)来预测样本属于某一类别的概率。

逻辑回归的基本原理

  1. 线性组合

    逻辑回归首先计算输入特征的线性组合。假设输入特征向量为x=[x1,x2,…,xn]\mathbf{x} = [x_1, x_2, \ldots, x_n]x=[x1,x2,,xn],权重向量为w=[w1,w2,…,wn\mathbf{w} = [w_1, w_2, \ldots, w_nw=[w1,w2,,wn],偏置为bbb,则线性组合可以表示为:

    z=w⊤x+b z = \mathbf{w}^\top \mathbf{x} + b z=wx+b

  2. Sigmoid 函数

    线性组合zzz 通过 Sigmoid 函数(也称为 Logistic 函数)转换为一个概率值。Sigmoid 函数的公式为:

    σ(z)=11+e−z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+ez1

    Sigmoid 函数将任意实数映射到 (0, 1) 区间内,表示样本属于某一类别的概率。

  3. 预测

    模型的预测输出为:

    y^=σ(w⊤x+b) \hat{y} = \sigma(\mathbf{w}^\top \mathbf{x} + b) y^=σ(wx+b)

    通常,如果y^>0.5\hat{y} > 0.5y^>0.5,则预测样本属于正类(1);否则,预测样本属于负类(0)。

损失函数

逻辑回归通常使用二元交叉熵损失函数(Binary Cross Entropy Loss)来衡量模型预测值与真实标签之间的差异。二元交叉熵损失函数的公式为:

其中,(y 是真实标签(0 或 1),(y^\hat{y}y^ 是模型的预测概率。
BCE(y,y^)=−[ylog⁡(y^)+(1−y)log⁡(1−y^)] \text{BCE}(y, \hat{y}) = -\left[ y \log(\hat{y}) + (1 - y) \log(1 - \hat{y}) \right] BCE(y,y^)=[ylog(y^)+(1y)log(1y^)]
其中,(y 是真实标签(0 或 1),(y^\hat{y}y^ 是模型的预测概率。

优化

逻辑回归模型的训练过程通常使用梯度下降法(或其变种,如随机梯度下降、小批量梯度下降等)来最小化损失函数。具体步骤如下:

  1. 前向传播

    • 计算线性组合z=w⊤x+bz = \mathbf{w}^\top \mathbf{x} + bz=wx+b
    • 通过 Sigmoid 函数计算预测概率\hat{y} = \sigma(z)。
  2. 计算损失

    • 使用二元交叉熵损失函数计算损失值。
  3. 反向传播

    • 计算损失对模型参数的梯度。
    • 更新模型参数,通常使用优化器(如 SGD、Adam 等)。

代码

import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 生成模拟数据
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32).view(-1, 1)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_test = torch.tensor(y_test, dtype=torch.float32).view(-1, 1)

# 定义逻辑回归模型
class LogisticRegression(nn.Module):
    def __init__(self, input_dim):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(input_dim, 1)

    def forward(self, x):
        return torch.sigmoid(self.linear(x))

input_dim = X_train.shape[1]
model = LogisticRegression(input_dim)
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()
    outputs = model(X_train)
    loss = criterion(outputs, y_train)
    loss.backward()
    optimizer.step()

    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# 评估模型
model.eval()
with torch.no_grad():
    y_pred = model(X_test)
    y_pred_class = (y_pred > 0.5).float()
    accuracy = (y_pred_class == y_test).float().mean()
    print(f'Test Accuracy: {accuracy:.4f}')

对代码的解释

数据生成
  • 这段代码中使用了哪些库来生成和处理数据?
    • 主要使用的库有 sklearntorchsklearn 用于生成和处理数据,torch 用于构建和训练模型。
  • make_classification函数的作用是什么?它的主要参数有哪些?
    • make_classificationsklearn.datasets 模块中的一个函数,用于生成模拟的分类数据集。主要参数包括:
      • n_samples:生成的样本数。
      • n_features:每个样本的特征数。
      • n_classes:类别数。
      • random_state:随机种子,确保每次生成的数据相同。

数据预处理

  • train_test_split函数的作用是什么?它的主要参数有哪些?
    • train_test_splitsklearn.model_selection 模块中的一个函数,用于将数据集划分为训练集和测试集。主要参数包括:
      • test_size:测试集的比例。
      • random_state:随机种子,确保每次划分的结果相同。
  • StandardScaler的作用是什么?为什么需要对数据进行标准化处理?
    • StandardScalersklearn.preprocessing 模块中的一个类,用于对数据进行标准化处理,即将数据缩放到零均值和单位方差。标准化处理可以加速模型的收敛速度,提高模型的性能,特别是对于基于梯度的优化算法。
    • 之所以只对训练数据标准化是因为,实际生活中,未来应用在模型上的数据一般是不可见的,这些数据不应该贸然标准化,所以在测试模型时,也不应该标准化测试数据集。
数据转换
  • 为什么需要将数据从NumPy数组转换为PyTorch张量?
    • PyTorch 是一个深度学习框架,它使用张量(Tensor)作为其主要数据结构。将数据从NumPy数组转换为PyTorch张量是为了能够在PyTorch的模型中直接使用这些数据。
  • dtype=torch.float32.view(-1, 1)的作用分别是什么?
    • dtype=torch.float32:指定张量的数据类型为32位浮点数,这是大多数深度学习模型的标准数据类型。
    • .view(-1, 1):改变张量的形状。-1 表示自动计算该维度的大小,1 表示将张量的第二个维度设置为1。
    • y_trainy_test 都是通过 torch.tensor 创建的张量,初始形状是一维的。原因是因为y_train与模型的输出形状匹配,通常需要将它 reshape 成二维张量,而 y_test因为在BECloss函数中需要模型输出和标签真实值进行匹配的计算,所以 y_test也得变成更 y_train一样的形状。而模型之所以输出的形状是二维的是因为nn.Linear`的输出是二维的。
模型定义

LogisticRegression类继承自哪个基类?为什么需要继承这个基类?

  • LogisticRegression 类继承自 nn.Modulenn.Module 是 PyTorch 中所有神经网络模块的基类,继承自 nn.Module 可以方便地定义和管理模型的参数、前向传播过程等。

nn.Lineartorch.sigmoid的作用分别是什么?

  • nn.Linear:定义一个全连接层,用于线性变换。参数 input_dim1 分别表示输入特征的维度和输出特征的维度。此全连接层的目的是将一个矩阵线性变化变成 y = XW + b,其中W是权重矩阵,b是偏置矩阵,权重矩阵 W 和偏置向量 b 就是模型训练中的参数
  • torch.sigmoid:激活函数,将线性变换的结果映射到 (0, 1) 区间,常用于二分类问题。sigmoid(z)=1/(1+exp(−z))sigmoid(z) = 1 / (1 + exp(-z))sigmoid(z)=1/(1+exp(z))

模型的示意图

损失函数和优化器
  • model.parameters():需要优化的模型参数。

    • 深度学习的参数是指模型在训练过程中需要学习和优化的变量。这些参数通常包括线性层的权重和偏置、卷积层的滤波器权重等。通过优化这些参数,模型可以逐渐拟合训练数据,从而在测试数据上表现更好。,通过保留这些参数可以简易的保存模型。
    • model.parameters() 返回一个生成器,生成器可以迭代访问模型中所有需要优化的参数。而这些参数通常是以 torch.Tensor 对象的形式存在,每个张量包含一组参数值。
    • 使用场景
      • 优化器:在定义优化器时,需要传入模型的参数,以便优化器知道哪些参数需要更新。
      • 梯度计算:在反向传播过程中,计算梯度时需要访问这些参数。
      • 参数初始化:在模型初始化时,可以对这些参数进行初始化。
  • nn.BCELoss是什么?它适用于哪种类型的任务?

    • nn.BCELoss 是二元交叉熵损失函数,适用于二分类问题。它计算预测值和真实值之间的平均二元交叉熵损失。
  • optim.SGD是什么?它的主要参数有哪些?

    • optim.SGD 是随机梯度下降优化器,用于更新模型参数以最小化损失函数。主要参数包括:

      • model.parameters():需要优化的模型参数。

      • lr:学习率,控制参数更新的步长。

        • 学习率的基本概念

          • 学习率是一个正数,通常表示为 lr。在每次参数更新时,学习率决定了参数调整的幅度。

          • 更新规则通常如下:
            θnew=θold−lr×∂L∂θ \theta_{\text{new}} = \theta_{\text{old}} - \text{lr} \times \frac{\partial L}{\partial \theta} θnew=θoldlr×θL

            ∂L∂θ\frac{\partial L}{\partial \theta}θL 是损失函数对参数的梯度。

          • 作用控制更新步长:学习率越大,参数更新的步长越大,模型可能更快地收敛,但也可能跳过最优解。影响收敛速度:学习率适中时,模型可以稳定地收敛到最优解;学习率太小时,模型收敛速度慢;学习率太大时,模型可能无法收敛,甚至发散。

          • 学习率可以甚至为固定的值,也可以动态变化。固定值的设置可以通过多次实验的结果进行设置

模型训练
  • model.train()model.eval()的区别是什么?
    • model.train():将模型设置为训练模式,启用如Dropout和BatchNorm等在训练过程中需要的行为。
    • model.eval():将模型设置为评估模式,禁用如Dropout和BatchNorm等在训练过程中需要的行为。
  • optimizer.zero_grad()optimizer.step()的作用分别是什么?
    • optimizer.zero_grad():清零梯度,防止梯度累积。梯度清零的原因是因为每个批次的梯度应该独立计算,反映当前批次数据对模型参数的贡献。不清零梯度会导致不同批次之间的梯度相互影响,破坏每个批次的独立性。而且不清零梯度会导致梯度值不断累积,存在梯度爆炸的风险,占用越来越多的内存。
    • optimizer.step():根据计算出的梯度更新模型参数。
前向传播和反向传播
  • outputs = model(X_train)这行代码做了什么?
    • 调用模型的 forward 方法,计算输入 X_train 的前向传播结果,即模型的预测输出。
  • loss.backward()的作用是什么?
    • 计算损失函数相对于模型参数的梯度,并将梯度存储在参数的 grad 属性中。

训练过程中的输出

  • if (epoch+1) % 10 == 0:这行代码的作用是什么?
    • 每10个epoch输出一次当前的损失值,用于监控训练过程。
  • print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')这行代码的格式化字符串中,{loss.item():.4f}表示什么?
    • {loss.item():.4f}:将 loss 张量转换为标量,并保留四位小数,用于输出当前的损失值。
模型评估
  • with torch.no_grad():的作用是什么?

    • with torch.no_grad(): 临时禁用梯度计算,用于评估模型时节省内存和计算资源。
  • (y_pred > 0.5).float()这行代码做了什么?

    • 比较操作y_pred > 0.5
      • y_pred:这是模型的预测输出,通常是一个包含概率值的张量,每个元素的值在 0 到 1 之间。
      • y_pred > 0.5:这是一个布尔操作,将 y_pred 中的每个元素与 0.5 进行比较。如果某个元素大于 0.5,则返回 True;否则返回 False
    • 类型转换.float()
      • TrueFalse 的结果是一个布尔张量,.float() 方法将布尔张量转换为浮点张量。在 PyTorch 中,布尔值 True 被转换为 1.0,布尔值 False 被转换为 0.0
  • accuracy = (y_pred_class == y_test).float().mean()这行代码计算的是什么?

    • 计算模型在测试集上的准确率。(y_pred_class == y_test).float() 生成一个布尔张量,表示预测结果与真实标签是否一致,将其转换为浮点数(True为1,False为0),然后计算平均值,得到准确率。
  • 为什么使用mean()来计算准确率?

    • mean() 计算张量中所有元素的平均值。在这里,张量中的每个元素表示一个样本的预测是否正确,因此平均值就是正确预测的样本比例,即准确率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值