📅  最后修改于: 2020-04-29 01:00:46             🧑  作者: Mango
Logistic逻辑回归是一种非常常用的统计方法,它使我们能够根据一组自变量来预测二进制输出。先前已在本文中介绍了逻辑回归的各种属性及其Python实现。现在,我们将了解如何在PyTorch中实现这一点,PyTorch是Facebook正在开发的一种非常流行的深度学习库。
现在,我们将看到如何使用PyTorch中的Logistic回归对MNIST数据集中的手写数字进行分类。首先,您需要将PyTorch安装到Python环境中。最简单的方法是使用pip
或conda
工具。访问pytorch.org并安装您想要使用的Python解释器和程序包管理器的版本。
安装了PyTorch之后,现在让我们看一下代码。编写下面给出的三行代码,以导入所需的库函数和对象。
import torch
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable
此处,torch.nn模块包含该模型所需的代码,torchvision.datasets包含MNIST数据集。它包含我们将在此处使用的手写数字数据集。该torchvision.transforms模块包含的对象转换成其他各种方法。在这里,我们将使用它从图像转换为PyTorch张量。另外,torch.autograd模块除其他外还包含Variable类,我们将在定义张量时使用该类。
接下来,我们将下载数据集并将其加载到内存中。
# MNIST数据集(图像和标签)
train_dataset = dsets.MNIST(root ='./data',
train = True,
transform = transforms.ToTensor(),
download = True)
test_dataset = dsets.MNIST(root ='./data',
train = False,
transform = transforms.ToTensor())
# 数据集加载器(输入点线)
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)
现在,我们将定义超级参数。
# 超级参数
input_size = 784
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001
在我们的数据集中,图片尺寸为28 * 28。因此,我们的输入大小为784。此外,其中还有10位数字,因此,我们可以有10个不同的输出。因此,我们将num_classes设置为10。此外,我们将在整个数据集上训练五次。最后,我们将分小批训练每个图像100张,以防止由于内存溢出而导致程序崩溃。
此后,我们将定义如下模型。在这里,我们将模型初始化为torch.nn.Module的子类,然后定义正向传递。在我们编写的代码中,softmax是在每次前向传递期间内部计算的,因此我们不需要在forward()函数中指定它。
class LogisticRegression(nn.Module):
def __init__(self, input_size, num_classes):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, num_classes)
def forward(self, x):
out = self.linear(x)
return out
定义了类之后,现在我们为该对象实例化一个对象。
model = LogisticRegression(input_size, num_classes)
接下来,我们设置损失函数和优化器。在这里,我们将使用交叉熵损失,而对于优化器,我们将使用随机梯度下降算法,其学习速率为0.001,如上面的hyper参数所定义。
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
现在,我们将开始培训。在这里,我们将执行以下任务:
# 训练模型
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
# 前向传播 + 计算损失 + 反向传播
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print('Epoch: [% d/% d], Step: [% d/% d], Loss: %.4f'
% (epoch + 1, num_epochs, i + 1,
len(train_dataset) // batch_size, loss.data[0]))
最后,我们将使用以下代码测试模型。
# 测试模型
correct = 0
total = 0
for images, labels in test_loader:
images = Variable(images.view(-1, 28 * 28))
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: % d %%' % (
100 * correct / total))
假设您正确执行了所有步骤,您将获得82%的准确度,与使用一种特殊类型的神经网络结构的当今最新模型相距甚远。供您参考,您可以在下面找到本文的完整代码:
import torch
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable
# MNIST数据集(图像和标签)
train_dataset = dsets.MNIST(root ='./data',
train = True,
transform = transforms.ToTensor(),
download = True)
test_dataset = dsets.MNIST(root ='./data',
train = False,
transform = transforms.ToTensor())
# 数据集加载器(输入点线)
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)
# 超级参数
input_size = 784
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001
# 模型
class LogisticRegression(nn.Module):
def __init__(self, input_size, num_classes):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, num_classes)
def forward(self, x):
out = self.linear(x)
return out
model = LogisticRegression(input_size, num_classes)
# 损失与优化
# Softmax是内部计算的.
# 设置要更新的参数.
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
# 训练模型
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
# 前向传播 + 计算损失 + 反向传播
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print('Epoch: [% d/% d], Step: [% d/% d], Loss: %.4f'
% (epoch + 1, num_epochs, i + 1,
len(train_dataset) // batch_size, loss.data[0]))
# 测试模型
correct = 0
total = 0
for images, labels in test_loader:
images = Variable(images.view(-1, 28 * 28))
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: % d %%' % (
100 * correct / total))