使用 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())
需要的参数
input_size = 28*28 #Size of image
num_classes = 10 #the image number are in range 0-10
num_epochs = 5 #one cycle through the full train data
batch_size = 100 #sample size consider before updating the model’s weights
learning_rate = 0.001 #step size to update parameter
使其可迭代
使用 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,还不错。