softmax 回归的简洁实现
通过深度学习框架的高级 API 能够使实现
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
# 数据加载和预处理
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# 定义Softmax回归模型
class SoftmaxRegression(nn.Module):
def __init__(self):
super(SoftmaxRegression, self).__init__()
self.fc = nn.Linear(28 * 28, 10) # 输入特征是28*28像素的图像,输出是10个类别
def forward(self, x):
x = x.view(-1, 28 * 28) # 将输入展平成一维 向量
x = self.fc(x) # 使用线性层
return x
# 创建模型和优化器
model = SoftmaxRegression()
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss() # 交叉熵损失函数
# 训练模型
num_epochs = 5
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
optimizer.zero_grad() # 清除之前的梯度
outputs = model(images) # 前向传播
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
print('Training Finished')
# 测试模型
model.eval() # 切换模型为评估模式
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy on the test set: {100 * correct / total}%')
Epoch [1/5], Step [100/938], Loss: 1.0045 Epoch [1/5], Step [200/938], Loss: 0.6642 Epoch [1/5], Step [300/938], Loss: 0.5915 Epoch [1/5], Step [400/938], Loss: 0.5362 Epoch [1/5], Step [500/938], Loss: 0.4746 Epoch [1/5], Step [600/938], Loss: 0.3930 Epoch [1/5], Step [700/938], Loss: 0.4142 Epoch [1/5], Step [800/938], Loss: 0.4082 Epoch [1/5], Step [900/938], Loss: 0.4129 Epoch [2/5], Step [100/938], Loss: 0.4121 Epoch [2/5], Step [200/938], Loss: 0.4446 Epoch [2/5], Step [300/938], Loss: 0.3830 Epoch [2/5], Step [400/938], Loss: 0.3551 Epoch [2/5], Step [500/938], Loss: 0.3684 Epoch [2/5], Step [600/938], Loss: 0.2859 Epoch [2/5], Step [700/938], Loss: 0.3386 Epoch [2/5], Step [800/938], Loss: 0.3887 Epoch [2/5], Step [900/938], Loss: 0.2877 Epoch [3/5], Step [100/938], Loss: 0.2778 Epoch [3/5], Step [200/938], Loss: 0.3154 Epoch [3/5], Step [300/938], Loss: 0.4098 Epoch [3/5], Step [400/938], Loss: 0.2843 Epoch [3/5], Step [500/938], Loss: 0.4791 Epoch [3/5], Step [600/938], Loss: 0.3504 Epoch [3/5], Step [700/938], Loss: 0.3379 Epoch [3/5], Step [800/938], Loss: 0.3590 Epoch [3/5], Step [900/938], Loss: 0.3365 Epoch [4/5], Step [100/938], Loss: 0.3937 Epoch [4/5], Step [200/938], Loss: 0.3342 Epoch [4/5], Step [300/938], Loss: 0.3880 Epoch [4/5], Step [400/938], Loss: 0.2986 Epoch [4/5], Step [500/938], Loss: 0.4192 Epoch [4/5], Step [600/938], Loss: 0.2791 Epoch [4/5], Step [700/938], Loss: 0.4487 Epoch [4/5], Step [800/938], Loss: 0.2977 Epoch [4/5], Step [900/938], Loss: 0.3608 Epoch [5/5], Step [100/938], Loss: 0.4532 Epoch [5/5], Step [200/938], Loss: 0.3125 Epoch [5/5], Step [300/938], Loss: 0.2227 Epoch [5/5], Step [400/938], Loss: 0.1872 Epoch [5/5], Step [500/938], Loss: 0.1746 Epoch [5/5], Step [600/938], Loss: 0.4230 Epoch [5/5], Step [700/938], Loss: 0.2674 Epoch [5/5], Step [800/938], Loss: 0.2835 Epoch [5/5], Step [900/938], Loss: 0.3205 Training Finished Accuracy on the test set: 91.4%
在上述 Softmax 回归的示例中,我们使用了经典的 MNIST 数据集,它是一个常用于测试机器学习和深度学习模型性能的数据集之一。
MNIST 数据集包含了大约6万张手写数字(0到9)的灰度图像,每张图像的尺寸为 28x28 像素。这些图像已经被预处理和标准化,以使其适合于训练和测试机器学习模型。
数据集通常分为两部分:
-
训练集(Training Set): 包含大部分数据,用于训练模型。在示例中,我们使用了
train=True参数来加载训练集。 -
测试集(Test Set): 包含一小部分数据,用于评估模型的性能。测试集独立于训练集,以确保模型的泛化性能。在示例中,我们使用了
train=False参数来加载测试集。
MNIST 数据集中的每个样本都包括一张手写数字图像和相应的标签(表示图像中的数字)。训练集和测试集中的图像和标签已经准备好,可以直接用于训练和测试机器学习模型。
需要注意的是,示例中的数据加载和预处理部分使用了 PyTorch 的torchvision库,它提供了方便的工具来加载和处理常见的计算机视觉数据集,包括MNIST。数据加载器(DataLoader)用于批量加载和迭代数据,而数据预处理(transforms)用于将图像转换为张量并进行标准化。