当前位置:   article > 正文

在PyTorch中使用Logistic回归进行10种猴子物种分类

10种猴子分类python

欢迎关注 “小白玩转Python”,发现更多 “有趣”

引言

本文提供了一个使用PyTorch构建一个非常基本的 Logistic模型的简单步骤,并将其应用于猴子图像的分类。

首先我们可以从下面的网址下载用于模型训练和测试的数据集:

https://www.kaggle.com/slothkong/10-monkey-species

这个数据集包含了10种猴子的图片,包括:

n0 — alouattapalliata

n1 — erythrocebuspatas

n2 — cacajaocalvus

n3 — macacafuscata

n4 — cebuellapygmea

n5 — cebuscapucinus

n6 — micoargentatus

n7 — saimirisciureus

n8 — aotusnigriceps

n9 — trachypithecusjohnii

在数据集中有两个文件: 训练文件和验证文件。训练和验证文件都包含10个标记为 n0-n9的子文件夹,如上所述,它们各代表一种猴子。每个猴子的图像至少是400x300像素。训练文件中可用的总图像为1096,验证文件夹中可用的总图像为272个图像。训练图像将用于训练和验证模型,而验证图像将用作测试图像,以报告模型的最终准确性。

第一步: 加载和查看数据

构建任何机器学习模型的第一步是理解基础数据。让我们首先读取图像数据,查看其中的一些图像,并将图像数据转换为张量。

导入相关库:

  1. # Import relevant libraries
  2. import torch
  3. import jovian
  4. import torchvision
  5. import torchvision.transforms as transforms
  6. import torch.nn as nn
  7. import pandas as pd
  8. import numpy as np
  9. import matplotlib
  10. import matplotlib.pyplot as plt
  11. import seaborn as sns
  12. import torch.nn.functional as F
  13. from torchvision.datasets.utils import download_url
  14. from torch.utils.data import DataLoader, TensorDataset, random_split
  15. from PIL import Image
  16. import glob

设置超参数:

  1. # Hyperparameters
  2. batch_size = 16
  3. learning_rate = 1e-3
  4. jovian.reset()
  5. jovian.log_hyperparams(batch_size=batch_size, learning_rate=learning_rate)

载入图像(包括训练图像和测试图像)并将图像转换为 float32类型的张量:

  1. # Load image and convert image to multidimensional array
  2. def image_to_array(images_folder):
  3. dataset = []
  4. for i in range(10):
  5. for filename in glob.glob(images_folder + "/n{}/*.jpg".format(i)):
  6. im = Image.open(filename)
  7. im = im.resize((400,300))
  8. pixels = np.asarray(im).astype('float32')
  9. pixels /= 255.0
  10. pixels = torch.from_numpy(pixels)
  11. dataset.append((pixels, i))
  12.     return dataset
  1. # Load Training Data
  2. train_dataset = image_to_array("monkey_species/training/training")
  3. # Load Test Data
  4. test_dataset = image_to_array("monkey_species/validation/validation")

查看示例图片:

  1. # View a sample Image
  2. img_tensor, label = train_dataset[0]
  3. print(img_tensor.shape)
  4. plt.imshow(img_tensor)
  5. print('Label:', label)

第二步:为训练准备数据

上面已经将图像数据转换为张量,我们可以开始准备用于模型训练,验证和测试的数据了。

训练数据——将用于训练模型(通过计算交叉熵损失和使用梯度下降法调整模型的权重)。

验证数据——将用于在训练时评估模型,并调整超参数(学习率和批量大小)。

测试数据——将用于计算模型的准确度。

从训练数据集创建验证集(20%的训练数据将用于验证)。同时生成批量的训练、验证和测试数据:

  1. # Training and Validation dataset
  2. val_size = round(0.2*len(train_dataset))
  3. train_size = len(train_dataset) - val_size
  4. train_ds, val_ds = random_split(train_dataset, [train_size, val_size])
  5. # Dataloaders
  6. train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)
  7. val_loader = DataLoader(val_ds, batch_size=batch_size)
  8. test_loader = DataLoader(test_dataset, batch_size=batch_size)
  1. # Verify batch
  2. for xb, yb in train_loader:
  3. print("inputs:", xb)
  4. print("targets:", yb)
  5. break

第三步:训练模型

现在我们已经为训练、验证和测试准备好了数据。我们可以使用训练数据集开始训练模型,并使用验证集对其进行验证。

为了进行训练,让我们创建一个自定义模型类和一些实用程序函数,如下所示:

  1. input_size = 300*400*3
  2. num_classes = len(label_dict)
  3. print("Input Size: ", input_size, "\nNumber of Classes: ", num_classes)
  1. class MonkeyClassificationModel(nn.Module):
  2. def __init__(self):
  3. super().__init__()
  4. self.linear = nn.Linear(input_size, num_classes)
  5. def forward(self, xb):
  6. xb = xb.reshape(-1, input_size)
  7. out = self.linear(xb)
  8. return out
  9. def training_step(self, batch):
  10. images, labels = batch
  11. out = self(images) # Generate predictions
  12. loss = F.cross_entropy(out, labels) # Calculate loss
  13. return loss
  14. def validation_step(self, batch):
  15. images, labels = batch
  16. out = self(images) # Generate predictions
  17. loss = F.cross_entropy(out, labels) # Calculate loss
  18. acc = accuracy(out, labels) # Calculate accuracy
  19. return {'val_loss': loss.detach(), 'val_acc': acc.detach()}
  20. def validation_epoch_end(self, outputs):
  21. batch_losses = [x['val_loss'] for x in outputs]
  22. epoch_loss = torch.stack(batch_losses).mean() # Combine losses
  23. batch_accs = [x['val_acc'] for x in outputs]
  24. epoch_acc = torch.stack(batch_accs).mean() # Combine accuracies
  25. return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()}
  26. def epoch_end(self, epoch, result):
  27. print("Epoch [{}], val_loss: {:.4f}, val_acc: {:.4f}".format(epoch, result['val_loss'], result['val_acc']))
  28. model = MonkeyClassificationModel()
  29. list(model.parameters())
  1. def accuracy(outputs, labels):
  2. _, preds = torch.max(outputs, dim=1)
  3. return torch.tensor(torch.sum(preds == labels).item() / len(preds))
  4. def evaluate(model, val_loader):
  5. outputs = [model.validation_step(batch) for batch in val_loader]
  6. return model.validation_epoch_end(outputs)
  7. def fit(epochs, lr, model, train_loader, val_loader, opt_func=torch.optim.SGD):
  8. history = []
  9. optimizer = opt_func(model.parameters(), lr)
  10. for epoch in range(epochs):
  11. # Training Phase
  12. for batch in train_loader:
  13. loss = model.training_step(batch)
  14. loss.backward()
  15. optimizer.step()
  16. optimizer.zero_grad()
  17. # Validation phase
  18. result = evaluate(model, val_loader)
  19. model.epoch_end(epoch, result)
  20. history.append(result)
  21. return history
  1. history1 = fit(100, learning_rate, model, train_loader, val_loader)
  2. history2 = fit(100, learning_rate/10, model, train_loader, val_loader)
  3. history3 = fit(100, learning_rate/10, model, train_loader, val_loader)
  4. history4 = fit(100, learning_rate/100, model, train_loader, val_loader)
  5. history5 = fit(100, learning_rate/1000, model, train_loader, val_loader)
  6. history = history1 + history2 + history3 + history4 + history5
  7. accuracies = [r['val_acc'] for r in history]
  8. plt.plot(accuracies, '-x')
  9. plt.xlabel('epoch')
  10. plt.ylabel('accuracy')
  11. plt.title('Accuracy vs. No. of epochs')
  1. # Evaluate on test dataset
  2. result = evaluate(model, test_loader)
  3. result

第四步: 使用训练后的模型进行预测

模型经过训练后,我们可以使用该模型来预测,即对测试图像进行分类。让我们定义一个分类图片的函数:

  1. def predict_image(input_img, model):
  2. inputs = input_img.unsqueeze(0)
  3. predictions = model(inputs)
  4. _, preds = torch.max(predictions, dim=1)
  5. return preds[0].item()
  1. label_dict = {0:"alouattapalliata", 1:"erythrocebuspatas", 2:"cacajaocalvus", 3:"macacafuscata",
  2. 4:"cebuellapygmea", 5:"cebuscapucinus", 6:"micoargentatus", 7:"saimirisciureus",
  3. 8:"aotusnigriceps", 9:"trachypithecusjohnii"}

部分测试结果如下:

预测正确

预测错误

保存模型:

  1. # Save
  2. torch.save(model.state_dict(), 'monkey_classification.pth')

模型精度及提高精度的思路

使用测试数据集计算模型的准确率约为56.6%。使用这个相当简单的 Logistic模型模型得到的准确度很差。因此,对于这个特定的数据集,需要考虑一个更复杂的机器学习或者深度学习模型。相信使用卷积神经网络(CNN)或深层神经网络(DNN)可以获得更好的分类精度。

可以通过以下策略进一步提高模型的准确性:

1. 增加数据

2. 使用CNN模型

3. 更改优化函数

结束语

尽管 Logistic模型的准确性很差,但本篇文章展示了如何使用 PyTorch 构建一个简单的 Logistic模型。类似的步骤可以应用于任何简单的线性分类问题。

·  END  ·

HAPPY LIFE

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/263849
推荐阅读
相关标签
  

闽ICP备14008679号