文章目录
-
- 一、逻辑回归简介和完整代码
-
- 基本原理
- 损失函数
- 优化算法
- 多分类问题
- 应用场景
- 代码实现
- 二、逻辑回归模型构建
-
- 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.Sigmoid
或nn.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.nn
、torchvision
用于加载数据集,以及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函数和类,包括它们的格式、参数意义、函数意义以及在代码中的用法:
-
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)
- 格式:
-
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)
- 格式:
-
nn.Linear(in_features, out_features)
- 格式:
nn.Linear(in_features, out_features)
- 参数:
in_features
:输入特征的数量。out_features
:输出特征的数量。
- 意义:创建一个线性层。
- 用法:
model = nn.Linear(input_size, num_classes)
- 格式:
-
nn.CrossEntropyLoss()
- 格式:
nn.CrossEntropyLoss()
- 参数:无默认参数。
- 意义:创建一个计算交叉熵损失的模块,内部计算softmax。
- 用法:
criterion = nn.CrossEntropyLoss()
- 格式:
-
torch.optim.SGD(params, lr)
- 格式:
torch.optim.SGD(params, lr)
- 参数:
params
:模型参数的迭代器。lr
:学习率。
- 意义:创建随机梯度下降优化器。
- 用法:
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
- 格式:
-
loss.backward()
- 格式:
loss.backward()
- 参数:无。
- 意义:计算损失相对于模型参数的梯度。
- 用法:
loss.backward()
- 格式:
-
optimizer.step()
- 格式:
optimizer.step()
- 参数:无。
- 意义:根据计算得到的梯度更新模型参数。
- 用法:
optimizer.step()
- 格式:
-
optimizer.zero_grad()
- 格式:
optimizer.zero_grad()
- 参数:无。
- 意义:清除(重置)过往梯度。
- 用法:
optimizer.zero_grad()
- 格式:
-
torch.no_grad()
- 格式:
torch.no_grad()
- 参数:无。
- 意义:上下文管理器,用于在测试或推理阶段禁用梯度计算以节省内存。
- 用法:
with torch.no_grad(): # 测试模型的代码
- 格式:
-
torch.save(obj, f)
- 格式:
torch.save(obj, f)
- 参数:
obj
:要保存的对象。f
:文件路径或文件对象。
- 意义:将对象保存到文件。
- 用法:
torch.save(model.state_dict(), 'model.ckpt')
- 格式:
-
images.reshape(-1, input_size)
- 格式:
images.reshape(shape)
- 参数:
shape
:期望的新形状。
- 意义:重塑张量的形状。
- 用法:
images = images.reshape(-1, input_size)
- 格式:
-
_, predicted = torch.max(outputs.data, 1)
- 格式:
torch.max(input, dim, keepdim=False)
- 参数:
input
:输入张量。dim
:要计算最大值的维度。
- 意义:计算张量在指定维度上的最大值和索引。
- 用法:
_, predicted = torch.max(outputs.data, 1)
- 格式: