PyTorch 学习笔记 (4): 逻辑回归
2025-10-05·10 min read
#PyTorch#Deep Learning#Machine Learning
逻辑回归用于分类问题(不是回归!)。
与线性回归的区别:
- 线性回归:预测连续值
y = wx + b - 逻辑回归:预测概率
y = sigmoid(wx + b),然后分类
Sigmoid 函数
Sigmoid 函数将任意实数映射到 (0, 1) 区间:
text
sigmoid(x) = 1 / (1 + e^(-x))
输出可以解释为"属于正类的概率"。
python
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
# Sigmoid 函数可视化
x_sig = torch.linspace(-10, 10, 100)
y_sig = torch.sigmoid(x_sig)
Sigmoid 函数的特点:
- 输出范围:(0, 1),可以解释为概率
- 当 x=0 时,sigmoid(0) = 0.5
- 当 x 大于 0 时,sigmoid(x) 大于 0.5,预测为正类
- 当 x 小于 0 时,sigmoid(x) 小于 0.5,预测为负类
准备分类数据
python
torch.manual_seed(42)
# 生成两类数据点
# 类别0:以 (2, 2) 为中心
class0_x = torch.randn(100, 2) + torch.tensor([2, 2])
class0_y = torch.zeros(100, 1) # 标签 0
# 类别1:以 (-2, -2) 为中心
class1_x = torch.randn(100, 2) + torch.tensor([-2, -2])
class1_y = torch.ones(100, 1) # 标签 1
# 合并数据
X = torch.cat([class0_x, class1_x], dim=0) # shape: (200, 2)
y = torch.cat([class0_y, class1_y], dim=0) # shape: (200, 1)
# 打乱数据
indices = torch.randperm(X.shape[0])
X = X[indices]
y = y[indices]
print(f"数据形状: X={X.shape}, y={y.shape}")
print(f"类别0样本数: {(y == 0).sum().item()}")
print(f"类别1样本数: {(y == 1).sum().item()}")
定义逻辑回归模型
python
class LogisticRegression(nn.Module):
def __init__(self, input_dim):
super().__init__()
self.linear = nn.Linear(input_dim, 1) # 输入2维,输出1维
def forward(self, x):
# 线性变换后接 sigmoid
return torch.sigmoid(self.linear(x))
model = LogisticRegression(input_dim=2)
print(f"模型结构:\n{model}")
损失函数:二元交叉熵
python
# 损失函数:二元交叉熵
criterion = nn.BCELoss()
# 优化器
optimizer = optim.SGD(model.parameters(), lr=0.1)
print("损失函数: BCE Loss (二元交叉熵)")
print("公式: -[y*log(p) + (1-y)*log(1-p)]")
训练模型
python
epochs = 1000
loss_history = []
accuracy_history = []
for epoch in range(epochs):
# 五步法
optimizer.zero_grad()
y_pred = model(X)
loss = criterion(y_pred, y)
loss.backward()
optimizer.step()
# 计算准确率
predictions = (y_pred >= 0.5).float() # 概率>=0.5 预测为1,否则为0
accuracy = (predictions == y).float().mean()
loss_history.append(loss.item())
accuracy_history.append(accuracy.item())
if (epoch + 1) % 100 == 0:
print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}, Accuracy: {accuracy.item()*100:.2f}%")
决策边界
训练完成后,可以可视化决策边界:
python
def plot_decision_boundary(model, X, y):
"""绘制决策边界"""
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100),
np.linspace(y_min, y_max, 100))
# 预测网格上每个点的类别
grid = torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype=torch.float32)
with torch.no_grad():
probs = model(grid).reshape(xx.shape)
# 绘制决策边界
# 黑线为分界线(概率=0.5)
contour = plt.contourf(xx, yy, probs.numpy(), levels=20, cmap='RdBu', alpha=0.7)
plt.contour(xx, yy, probs.numpy(), levels=[0.5], colors='black', linewidths=2)
线性回归 vs 逻辑回归
| 特性 | 线性回归 | 逻辑回归 |
|---|---|---|
| 任务类型 | 回归(连续值) | 分类(离散值) |
| 激活函数 | 无 | Sigmoid |
| 输出范围 | (-∞, +∞) | (0, 1) |
| 损失函数 | MSE | BCE |
| 输出含义 | 预测值 | 属于正类的概率 |
关键公式
text
Sigmoid: σ(x) = 1 / (1 + e^(-x))
BCE Loss: -[y*log(p) + (1-y)*log(1-p)]
决策规则
text
p >= 0.5 → 预测为正类(1)
p < 0.5 → 预测为负类(0)
总结
逻辑回归是神经网络的基础:
- Sigmoid 将线性输出转为概率
- BCE Loss 衡量概率预测的质量
- 决策边界 是一条直线(线性分类器)
掌握逻辑回归后,就可以开始学习多层神经网络了!