PyTorch之逻辑回归模型实现与函数介绍

文章目录

    • 一、逻辑回归简介和完整代码
      • 基本原理
      • 损失函数
      • 优化算法
      • 多分类问题
      • 应用场景
      • 代码实现
    • 二、逻辑回归模型构建
      • 1.导入库
      • 2.设置超参数
      • 3.加载数据集
      • 4.创建数据加载器
      • 5.定义模型
      • 6.定义损失函数和优化器
      • 7.训练模型
      • 8.测试模型
      • 9.保存模型
    • 三、常用函数解析

一、逻辑回归简介和完整代码

逻辑回归(Logistic Regression)是一种广泛应用于二分类问题的统计模型,尽管它的名字中有“回归”二字,但实际上它用于分类任务。逻辑回归通过使用逻辑函数将输入特征转换为0和1之间的值,从而预测一个事件发生的概率。

基本原理

逻辑回归使用的是Sigmoid函数,其数学表达式为:
[ \sigma(z) = \frac{1}{1 + e^{-z}} ]
其中,( z ) 是线性组合 ( z = w^Tx + b ),这里 ( w ) 是权重向量,( x ) 是特征向量,( b ) 是偏置项。

Sigmoid函数的输出范围在0和1之间,这使得它非常适合用作概率的估计。在二分类问题中,我们可以将Sigmoid函数的输出解释为属于正类(通常标记为1)的概率。

损失函数

逻辑回归使用的损失函数是二元交叉熵损失(Binary Cross-Entropy Loss)。对于单个样本,损失函数定义为:
[ \text{Loss} = -\left( y \cdot \log(\sigma(z)) + (1 - y) \cdot \log(1 - \sigma(z)) \right) ]
其中,( y ) 是真实标签(0或1),( \sigma(z) ) 是模型预测为正类的概率。

对于整个数据集,损失函数通常是所有样本损失的均值。

优化算法

逻辑回归通常使用梯度下降(Gradient Descent)或其变种(如随机梯度下降SGD、小批量梯度下降MBGD等)来优化损失函数,从而学习权重 ( w ) 和偏置 ( b )。

多分类问题

逻辑回归也可以扩展到多分类问题,这通常通过“一对余”(One-vs-Rest)或“一对一”(One-vs-One)策略来实现。在PyTorch中,nn.CrossEntropyLoss已经内置了对多分类的支持,它接受一个分类的 logits 向量和对应的标签,内部自动应用了softmax函数来进行多分类的概率估计。

应用场景

逻辑回归适用于以下场景:

  • 二分类问题,如垃圾邮件检测、疾病诊断等。
  • 需要输出概率预测的问题。
  • 数据集特征和标签是线性可分的。

逻辑回归简单、易于实现,并且计算效率高,但它也有一些局限性,比如对于非线性问题,它可能无法很好地工作,此时可能需要更复杂的模型,如神经网络。

代码实现

在PyTorch中,逻辑回归可以通过nn.Linear层来实现,其中最后一层的输出维度是2(对于二分类问题)。然后使用nn.Sigmoidnn.BCEWithLogitsLoss(它结合了Sigmoid和BCELoss,更稳定)来进行概率估计和损失计算。

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms


# Hyper-parameters 
input_size = 28 * 28    # 784
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001

# MNIST dataset (images and labels)
train_dataset = torchvision.datasets.MNIST(root='../../data', 
                                           train=True, 
                                           transform=transforms.ToTensor(),
                                           download=True)

test_dataset = torchvision.datasets.MNIST(root='../../data', 
                                          train=False, 
                                          transform=transforms.ToTensor())

# Data loader (input pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset, 
                                          batch_size=batch_size, 
                                          shuffle=False)

# Logistic regression model
model = nn.Linear(input_size, num_classes)

# Loss and optimizer
# nn.CrossEntropyLoss() computes softmax internally
criterion = nn.CrossEntropyLoss()  
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)  

# Train the model
total_step = len(train_loader)
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # Reshape images to (batch_size, input_size)
        images = images.reshape(-1, input_size)
        
        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if (i+1) % 100 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' 
                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

# Test the model
# In test phase, we don't need to compute gradients (for memory efficiency)
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.reshape(-1, input_size)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()

    print('Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))

# Save the model checkpoint
torch.save(model.state_dict(), 'model.ckpt')

二、逻辑回归模型构建

1.导入库

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms

这部分代码导入了所需的PyTorch库,包括基础的torch模块、神经网络模块torch.nntorchvision用于加载数据集,以及transforms用于图像预处理。

2.设置超参数

# Hyper-parameters 
input_size = 28 * 28    # 784
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001

这里定义了模型训练的超参数,包括输入数据的维度、类别数、训练轮数、批次大小和学习率。

3.加载数据集

# MNIST dataset (images and labels)
train_dataset = torchvision.datasets.MNIST(root='../../data', 
                                           train=True, 
                                           transform=transforms.ToTensor(),
                                           download=True)

test_dataset = torchvision.datasets.MNIST(root='../../data', 
                                          train=False, 
                                          transform=transforms.ToTensor())

加载MNIST数据集,包括训练集和测试集。使用transforms.ToTensor()将图像转换为PyTorch张量。

4.创建数据加载器

# Data loader (input pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset, 
                                          batch_size=batch_size, 
                                          shuffle=False)

创建数据加载器,用于批量加载数据,并在训练时打乱数据顺序。

5.定义模型

# Logistic regression model
model = nn.Linear(input_size, num_classes)

定义一个线性模型,用于逻辑回归。

6.定义损失函数和优化器

# Loss and optimizer
# nn.CrossEntropyLoss() computes softmax internally
criterion = nn.CrossEntropyLoss()  
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)  

使用交叉熵损失函数和随机梯度下降优化器。

7.训练模型

# Train the model
total_step = len(train_loader)
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # Reshape images to (batch_size, input_size)
        images = images.reshape(-1, input_size)
        
        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if (i+1) % 100 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' 
                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

训练循环,包括前向传播、损失计算、反向传播和参数更新。

8.测试模型

# Test the model
# In test phase, we don't need to compute gradients (for memory efficiency)
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.reshape(-1, input_size)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()

    print('Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))

测试循环,计算模型在测试集上的准确率。

9.保存模型

# Save the model checkpoint
torch.save(model.state_dict(), 'model.ckpt')

保存模型参数。

三、常用函数解析

以下是代码中使用的PyTorch函数和类,包括它们的格式、参数意义、函数意义以及在代码中的用法:

  1. torchvision.datasets.MNIST(root, train, transform, download)

    • 格式:torchvision.datasets.MNIST(root, train, transform, download)
    • 参数:
      • root:数据集存放的根目录。
      • train:布尔值,指示是否加载训练集。
      • transform:一个变换,比如transforms.ToTensor(),用于对数据集进行预处理。
      • download:布尔值,指示是否下载数据集。
    • 意义:加载MNIST数据集。
    • 用法:
      train_dataset = torchvision.datasets.MNIST(root='../../data', train=True, transform=transforms.ToTensor(), download=True)
      
  2. torch.utils.data.DataLoader(dataset, batch_size, shuffle)

    • 格式:torch.utils.data.DataLoader(dataset, batch_size, shuffle)
    • 参数:
      • dataset:要加载的数据集。
      • batch_size:每个批次的样本数量。
      • shuffle:布尔值,指示在每个epoch开始时是否打乱数据。
    • 意义:创建一个数据加载器,用于批量加载数据。
    • 用法:
      train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
      
  3. nn.Linear(in_features, out_features)

    • 格式:nn.Linear(in_features, out_features)
    • 参数:
      • in_features:输入特征的数量。
      • out_features:输出特征的数量。
    • 意义:创建一个线性层。
    • 用法:
      model = nn.Linear(input_size, num_classes)
      
  4. nn.CrossEntropyLoss()

    • 格式:nn.CrossEntropyLoss()
    • 参数:无默认参数。
    • 意义:创建一个计算交叉熵损失的模块,内部计算softmax。
    • 用法:
      criterion = nn.CrossEntropyLoss()
      
  5. torch.optim.SGD(params, lr)

    • 格式:torch.optim.SGD(params, lr)
    • 参数:
      • params:模型参数的迭代器。
      • lr:学习率。
    • 意义:创建随机梯度下降优化器。
    • 用法:
      optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
      
  6. loss.backward()

    • 格式:loss.backward()
    • 参数:无。
    • 意义:计算损失相对于模型参数的梯度。
    • 用法:
      loss.backward()
      
  7. optimizer.step()

    • 格式:optimizer.step()
    • 参数:无。
    • 意义:根据计算得到的梯度更新模型参数。
    • 用法:
      optimizer.step()
      
  8. optimizer.zero_grad()

    • 格式:optimizer.zero_grad()
    • 参数:无。
    • 意义:清除(重置)过往梯度。
    • 用法:
      optimizer.zero_grad()
      
  9. torch.no_grad()

    • 格式:torch.no_grad()
    • 参数:无。
    • 意义:上下文管理器,用于在测试或推理阶段禁用梯度计算以节省内存。
    • 用法:
      with torch.no_grad():
          # 测试模型的代码
      
  10. torch.save(obj, f)

    • 格式:torch.save(obj, f)
    • 参数:
      • obj:要保存的对象。
      • f:文件路径或文件对象。
    • 意义:将对象保存到文件。
    • 用法:
      torch.save(model.state_dict(), 'model.ckpt')
      
  11. images.reshape(-1, input_size)

    • 格式:images.reshape(shape)
    • 参数:
      • shape:期望的新形状。
    • 意义:重塑张量的形状。
    • 用法:
      images = images.reshape(-1, input_size)
      
  12. _, predicted = torch.max(outputs.data, 1)

    • 格式:torch.max(input, dim, keepdim=False)
    • 参数:
      • input:输入张量。
      • dim:要计算最大值的维度。
    • 意义:计算张量在指定维度上的最大值和索引。
    • 用法:
      _, predicted = torch.max(outputs.data, 1)
      
PyTorch是一个开源的深度学习框架,可以用于构建和训练神经网络模型。逻辑回归是一种二分类模型,可以用于解决分类问题。下面是使用PyTorch调用逻辑回归模型的一般步骤: 1. 导入必要的库和模块: ```python import torch import torch.nn as nn import torch.optim as optim ``` 2. 定义逻辑回归模型类: ```python class LogisticRegression(nn.Module): def __init__(self, input_size, output_size): super(LogisticRegression, self).__init__() self.linear = nn.Linear(input_size, output_size) self.sigmoid = nn.Sigmoid() def forward(self, x): out = self.linear(x) out = self.sigmoid(out) return out ``` 在这个例子中,我们使用了一个线性层和一个Sigmoid激活函数。 3. 实例化模型: ```python input_size = 10 # 输入特征的维度 output_size = 1 # 输出的类别数(二分类问题) model = LogisticRegression(input_size, output_size) ``` 4. 定义损失函数和优化器: ```python criterion = nn.BCELoss() # 二分类交叉熵损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01) # 随机梯度下降优化器 ``` 5. 准备数据: ```python # 假设有训练数据X和对应的标签y X = torch.tensor([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]]) y = torch.tensor([[0.0]]) # 标签为0或1 # 数据预处理 X = X.t() # 转置X,使得每一行代表一个样本 y = y.t() # 转置y,使得每一行代表一个样本 ``` 6. 训练模型: ```python num_epochs = 100 # 迭代次数 for epoch in range(num_epochs): # 前向传播 outputs = model(X) loss = criterion(outputs, y) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 打印训练信息 if (epoch+1) % 10 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) ``` 7. 使用模型进行预测: ```python # 假设有测试数据X_test X_test = torch.tensor([[11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]]) X_test = X_test.t() # 转置X_test,使得每一行代表一个样本 # 使用模型进行预测 predicted = model(X_test) predicted_class = predicted.round() # 四舍五入为0或1 print('Predicted Class:', predicted_class.item()) ``` 这就是使用PyTorch调用逻辑回归模型的一般步骤。你可以根据自己的数据和需求进行相应的修改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值