pytorch逻辑回归实现步骤详解

1. 什么是逻辑回归

逻辑回归是一种广泛使用的分类器。分类器是一个算法,它使用特征向量(通常称为x)将将数据点 分类为不同的类,例如1、2或3。通常,我们在使用分类器时用y表示我们想要预测的类。

逻辑回归的目标是根据给定的一些特征,将数据点分为2个类

逻辑回归算法使用函数来将输入特征和预测的输出值联系起来。这些函数称为“激活函数”或“sigmoid函数”。Sigmoid函数本身非常简单。该函数由以下公式给出:

def sigmoid(x):

return 1 / (1 + torch.exp(-x))

sigmoid函数将任何实数映射到区间[0, 1]中的一个值,这样我们就可以将输出解释为概率。例如,如果我们要判断一张照片里的物品是不是一只猫,逻辑回归可以输出一个概率值,如果这个概率值大于0.5,我们就认为这张照片里看到的是一只猫。

2. 数据预处理

2.1 数据集加载

我们将使用pytorch的自带手写数字数据集MNIST。MNIST数据集包含60,000个用于训练和10,000个用于测试的手写数字示例。我们可以使用以下代码将数据集载入PyTorch,并定义一些转换以标准化输入图像:

import torch

from torch.utils.data import DataLoader

from torchvision import datasets, transforms

# 数据转换

transform = transforms.Compose([

transforms.ToTensor(), # 将数据转换成torch张量

transforms.Normalize((0.5, ), (0.5, )) # 归一化

])

# 加载训练数据

trainset = datasets.MNIST(

root='data/',

train=True,

download=True,

transform=transform

)

trainloader = DataLoader(

trainset,

batch_size=64,

shuffle=True

)

# 加载测试数据

testset = datasets.MNIST(

root='data/',

train=False,

download=True,

transform=transform

)

testloader = DataLoader(

testset,

batch_size=64,

shuffle=True

)

2.2 数据可视化

数据集可以使用Matplotlib进行可视化。

import matplotlib.pyplot as plt 

images, labels = next(iter(trainloader))

plt.imshow(images[0].numpy().squeeze(), cmap='gray_r')

plt.title(str(labels[0].item()))

plt.show()

根据结果可以看到,我们得到了一个手写数字图像和该图像对应的标签。

3. 构建模型

要使用PyTorch构建逻辑回归模型,需要创建继承自nn.Module的模型,并在__init__函数中定义隐藏层的大小(输入维数和输出维数)和Sigmoid层:

from torch import nn

class LogisticRegression(nn.Module):

def __init__(self):

super(LogisticRegression, self).__init__()

self.linear1 = nn.Linear(784, 512) # 输入维度为28*28=784,输出维度为512

self.linear2 = nn.Linear(512, 128) # 输出维度为128

self.linear3 = nn.Linear(128, 10) # 输出维度为10

self.sigmoid = nn.Sigmoid()

def forward(self, x):

x = self.sigmoid(self.linear1(x)) # 隐藏层1:Sigmoid(x * weight + bias)

x = self.sigmoid(self.linear2(x)) # 隐藏层2:Sigmoid(x * weight + bias)

x = self.linear3(x) # 输出层:x * weight + bias

return x

模型架构如下:

LogisticRegression(

(linear1): Linear(in_features=784, out_features=512, bias=True)

(linear2): Linear(in_features=512, out_features=128, bias=True)

(linear3): Linear(in_features=128, out_features=10, bias=True)

(sigmoid): Sigmoid()

)

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

要定义损失函数,我们使用交叉熵作为目标函数。在PyTorch中,有一个功能称为“nn.CrossEntropyLoss()”,它可以在模型输出和期望输出之间计算交叉熵。

有几个优化器可以在PyTorch中使用,包括SGD、Adam和Adagrad等。我们将使用Adam优化器:

learning_rate = 0.001

# 定义损失函数和优化器

criterion = nn.CrossEntropyLoss()

optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

5. 训练模型

现在我们终于准备好训练我们的模型了。我们将在训练数据集上使用模型进行训练,然后在测试数据集上进行评估。PyTorch使训练和评估非常容易。

import torch.nn.functional as F

total_step = len(trainloader)

num_epochs = 10

for epoch in range(num_epochs):

for i, (images, labels) in enumerate(trainloader):

# 将张量调整为784维的向量并将0-1的图像转换为-1到1之间的值

images = images.view(-1, 28*28)

images = (images - 0.5) * 2

# 向模型传递输入

outputs = model(images)

# 计算损失值

loss = criterion(outputs, labels)

# 清空梯度

optimizer.zero_grad()

# 反向传播和优化

loss.backward()

optimizer.step()

# 每100个batch打印一次训练状态

if (i+1) % 100 == 0:

print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'

.format(epoch+1, num_epochs, i+1, total_step, loss.item()))

运行结果如下:

Epoch [1/10], Step [100/938], Loss: 0.4734

Epoch [1/10], Step [200/938], Loss: 0.2864

Epoch [1/10], Step [300/938], Loss: 0.3573

Epoch [1/10], Step [400/938], Loss: 0.4332

Epoch [1/10], Step [500/938], Loss: 0.2347

Epoch [1/10], Step [600/938], Loss: 0.3576

Epoch [1/10], Step [700/938], Loss: 0.1910

Epoch [1/10], Step [800/938], Loss: 0.2556

Epoch [1/10], Step [900/938], Loss: 0.2741

Epoch [2/10], Step [100/938], Loss: 0.1974

Epoch [2/10], Step [200/938], Loss: 0.2118

Epoch [2/10], Step [300/938], Loss: 0.2906

Epoch [2/10], Step [400/938], Loss: 0.2006

Epoch [2/10], Step [500/938], Loss: 0.3036

Epoch [2/10], Step [600/938], Loss: 0.2008

Epoch [2/10], Step [700/938], Loss: 0.1561

Epoch [2/10], Step [800/938], Loss: 0.1506

Epoch [2/10], Step [900/938], Loss: 0.2447

Epoch [3/10], Step [100/938], Loss: 0.2022

Epoch [3/10], Step [200/938], Loss: 0.2669

Epoch [3/10], Step [300/938], Loss: 0.0517

Epoch [3/10], Step [400/938], Loss: 0.1444

Epoch [3/10], Step [500/938], Loss: 0.1569

Epoch [3/10], Step [600/938], Loss: 0.1654

Epoch [3/10], Step [700/938], Loss: 0.2206

Epoch [3/10], Step [800/938], Loss: 0.1651

Epoch [3/10], Step [900/938], Loss: 0.1248

Epoch [4/10], Step [100/938], Loss: 0.1171

Epoch [4/10], Step [200/938], Loss: 0.2148

Epoch [4/10], Step [300/938], Loss: 0.2085

Epoch [4/10], Step [400/938], Loss: 0.1758

Epoch [4/10], Step [500/938], Loss: 0.2142

Epoch [4/10], Step [600/938], Loss: 0.1893

Epoch [4/10], Step [700/938], Loss: 0.1438

Epoch [4/10], Step [800/938], Loss: 0.1558

Epoch [4/10], Step [900/938], Loss: 0.1655

Epoch [5/10], Step [100/938], Loss: 0.1676

Epoch [5/10], Step [200/938], Loss: 0.1935

Epoch [5/10], Step [300/938], Loss: 0.1319

Epoch [5/10], Step [400/938], Loss: 0.1198

Epoch [5/10], Step [500/938], Loss: 0.1087

Epoch [5/10], Step [600/938], Loss: 0.1734

Epoch [5/10], Step [700/938], Loss: 0.0975

Epoch [5/10], Step [800/938], Loss: 0.0986

Epoch [5/10], Step [900/938], Loss: 0.1509

Epoch [6/10], Step [100/938], Loss: 0.1663

Epoch [6/10], Step [200/938], Loss: 0.1157

Epoch [6/10], Step [300/938], Loss: 0.0542

Epoch [6/10], Step [400/938], Loss: 0.1429

Epoch [6/10], Step [500/938], Loss: 0.1428

Epoch [6/10], Step [600/938], Loss: 0.1166

Epoch [6/10], Step [700/938], Loss: 0.1500

Epoch [6/10], Step [800/938], Loss: 0.1614

Epoch [6/10], Step [900/938], Loss: 0.1257

Epoch [7/10], Step [100/938], Loss: 0.0780

Epoch [7/10], Step [200/938], Loss: 0.1527

Epoch [7/10], Step [300/938], Loss: 0.0767

Epoch [7/10], Step [400/938], Loss: 0.1028

Epoch [7/10], Step [500/938], Loss: 0.0815

Epoch [7/10], Step [600/938], Loss: 0.1039

Epoch [7/10], Step [700/938], Loss: 0.0908

Epoch [7/10], Step [800/938], Loss: 0.1013

Epoch [7/10], Step [900/938], Loss: 0.0977

Epoch [8/10], Step [100/938], Loss: 0.0443

Epoch [8/10], Step [200/938], Loss: 0.1171

Epoch [8/10], Step [300/938], Loss: 0.0893

Epoch [8/10], Step [400/938], Loss: 0.1235

Epoch [8/10], Step [500/938], Loss: 0.0858

Epoch [8/10], Step [600/938], Loss: 0.0964

Epoch [8/10], Step [700/938], Loss: 0.1956

Epoch [8/10], Step [800/938], Loss: 0.0784

Epoch [8/10], Step [900/938], Loss: 0.1079

Epoch [9/10], Step [100/938], Loss: 0.1038

Epoch [9/10], Step [200/938], Loss: 0.0431

Epoch [9/10], Step [300/938], Loss: 0.1246

Epoch [9/10], Step [400/938], Loss: 0.1199

Epoch [9/10], Step [500/938], Loss: 0.1456

Epoch [9/10], Step [600/938], Loss: 0.1238

Epoch [9/10], Step [700/938], Loss: 0.1275

Epoch [9/10], Step [800/938], Loss: 0.1513

Epoch [9/10], Step [900/938], Loss: 0.1011

Epoch [10/10], Step [100/938], Loss: 0.1043

Epoch [10/10], Step [200/938], Loss: 0.0608

Epoch [10/10], Step [300/938], Loss: 0.0960

Epoch [10/10], Step [400/938], Loss: 0.1052

Epoch [10/10], Step [500/938], Loss: 0.0582

Epoch [10/10], Step [600/938], Loss: 0.0633

Epoch [10/10], Step [700/938], Loss: 0.0626

Epoch [10/10], Step [800/938], Loss: 0.0665

Epoch [10/10], Step [900/938], Loss: 0.0427

6. 测试模型

测试的过程与训练的过程基本相同,只是数据源改为测试集,不会对模型参数进行更新

# 计算测试集上的准确率

correct = 0

total = 0

for images, labels in testloader:

images = images.reshape(-1, 28*28)

images = (images - 0.5) * 2

outputs = model(images)

_, predicted = torch.max(outputs.data, 1)

total += labels.size(0)

correct += (predicted == labels).sum().item()

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

输出结果如下:

Accuracy of the model on the 10000 test images: 97.88 %

7. 总结

在本文中,我们介绍了如何使用PyTorch实现逻辑回归算法,并使用PyTorch自带数据集MNIST进行了训练和测试。在完成本文后,您现在应该已经熟悉了PyTorch的基本概念以及如何构建模型并训练和测试它们。

未来,您可以尝试在此基础上添加更多隐藏层数,调整学习率、批处理大小等超参数来提高模型的性能。祝您好运!

后端开发标签