📜  使用 PyTorch 对 MNIST 进行逻辑回归

📅  最后修改于: 2022-05-13 01:55:49.760000             🧑  作者: Mango

使用 PyTorch 对 MNIST 进行逻辑回归

逻辑回归

逻辑回归也称为二元分类,是最流行的机器学习算法之一。它属于监督学习分类算法。它用于预测目标标签的概率。通过二进制分类,这意味着模型预测标签为 0 或 1。目标变量是分类数据类型,例如:是或否、幸存或未幸存、男性或女性、通过或失败等。逻辑回归利用 Sigmoid函数进行预测。 Sigmoid 激活函数是一个非线性函数,定义为:

y = 1/(1+e-z) 

#the y is in range 0-1
#z = x*w + b where w is weight and b is bias

Pytorch中MNIST的物流回归

Pytorch 是强大的机器学习Python框架。使用 Pytorch 框架,实现逻辑回归变得更容易,它还提供了 MNIST 数据集。

安装:

pip install torch
pip install torchvision --no-deps

使用逻辑回归构建完整的 MNIST 预测模型的步骤

导入必要的模块

import torch
import torchvision
import torch.nn as tn
import matplotlib.pyplot as plt
import torchvision.transforms as tt
import torch.utils as utils

从 torchvision 下载数据集

Torchvision 模块提供了 MNIST 数据集,可以通过输入以下代码进行下载:

Python
train_data = torchvision.datasets.MNIST('./data',download=True)
test_data = torchvision.datasets.MNIST('data',train=False)
print(train_data)
print(test_data)


Python3
print(train_data[0])


Python3
import matplotlib.pyplot as plt
  
plt.subplot(1,2,1)
image, label = train_data[0]
plt.imshow(image, cmap='gray')
plt.title("Label of Image:{}".format(label),fontsize=20)
plt.subplot(1,2,2)
image, label = train_data[1]
plt.imshow(image, cmap='gray')
plt.title("Label of Image:{}".format(label),fontsize=20)


输出:

Dataset MNIST
    Number of datapoints: 60000
    Root location: ./data
    Split: Train
Dataset MNIST
    Number of datapoints: 10000
    Root location: data
    Split: Test

好的,我们现在拥有的训练数据和测试数据都是图像的形式:

Python3

print(train_data[0])

输出:

(, 5)

如果您仔细注意输出,我们可以深入了解训练数据。该图像由28*28像素组成,第一个索引图像为 5。因为它是元组形式,其中索引 1 是图像,索引 2 是代码块标签。使用 Matplotlib,我们可以可视化第一次训练数据索引包含的图像。

可视化

Python3

import matplotlib.pyplot as plt
  
plt.subplot(1,2,1)
image, label = train_data[0]
plt.imshow(image, cmap='gray')
plt.title("Label of Image:{}".format(label),fontsize=20)
plt.subplot(1,2,2)
image, label = train_data[1]
plt.imshow(image, cmap='gray')
plt.title("Label of Image:{}".format(label),fontsize=20)

输出:

数据转换:

由于数据是图像形式的,因此必须将其转换为 Tensor,以便 PyTorch 神经网络可以训练数据。 Torchvision 提供了一种变换方法。

train_data = torchvision.datasets.MNIST('data',train=True,transform=tt.ToTensor())
test_data = torchvision.datasets.MNIST('data',train=False,transform=tt.ToTensor()) 

需要的参数

使其可迭代

使用 DataLoader,我们可以遍历训练数据的张量。

train_dataLoader = torch.utils.data.DataLoader(train_data, batch_size=batch_size,shuffle=True)
test_dataLoader = torch.utils.data.DataLoader(test_data,batch_size=batch_size,shuffle=False)

建立逻辑回归模型

创建适合特征和输出数据的逻辑回归模型。

class LogisticRegression(tn.Module):
    def __init__(self,input_size,num_classes):
        super(LogisticRegression,self).__init__()
        self.linear = tn.Linear(input_size,num_classes)
    
    def forward(self,feature):
        output = self.linear(feature)
        return output

损失和优化器

我们将使用 CrossEntropyLoss函数来计算计算的损失。使用 CrossEntropyLoss函数的原因是它计算了 softmax函数和交叉熵。

而Stochastic Gradient Descent是用来计算梯度和更新参数的优化器。

model = LogisticRegression(input_size,num_classes)
loss = tn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate)

训练和预测

将图像和标签转换为具有梯度的张量,然后清除梯度 wrt 参数(optimizer.zero_grad())。根据梯度计算损失,并进一步尝试通过添加学习率来更新参数来减少损失。这个过程称为反向传播。

run = 0
for epoch in range(num_epochs):
    for i,(images,labels) in enumerate(train_dataLoader):
        images = torch.autograd.Variable(images.view(-1,input_size))
        labels = torch.autograd.Variable(labels)
        
        # Nullify gradients w.r.t. parameters
        optimizer.zero_grad()
        #forward propagation
        output = model(images)
        # compute loss based on obtained value and actual label
        compute_loss = loss(output,labels)
        # backward propagation
        compute_loss.backward()
        # update the parameters
        optimizer.step()
        run+=1
        
        if (i+1)%200 == 0:
            # check total accuracy of predicted value and actual label
            accurate = 0
            total = 0
            for images,labels in test_dataLoader:
                images = torch.autograd.Variable(images.view(-1,input_size))
                output = model(images)
                _,predicted = torch.max(output.data, 1)
                # total labels
                total+= labels.size(0)
                
                # Total correct predictions
                accurate+= (predicted == labels).sum()
                accuracy_score = 100 * accurate/total
            
            print('Iteration: {}. Loss: {}. Accuracy: {}'.format(run, compute_loss.item(), accuracy_score))

print('Final Accuracy:',accuracy_score)

最后结果:

准确度得分为89,还不错。