Polkadot 价格分析 13 月 XNUMX 日

卷积神经网络——CIFAR-10 数据集上的 PyTorch 实现

源节点: 1866263

这篇文章是作为 数据科学博客马拉松

介绍

Cifar 10 | 卷积神经网络pytorch
                                    图片1

卷积神经网络,也称为 ConvNets,最早由 Yann LeCun 在 1980 年代提出,Yann LeCun 是一位在后台工作的计算机科学研究人员。 LeCun 建立在日本科学家 Kunihiko Fukushima 的工作之上,是图像识别的基础网络。

旧版本的 CNN,称为 LeNet(LeCun 之后),可以看到手写数字。 CNN 帮助从邮政中查找密码。 但是,尽管拥有专业知识,ConvNets 仍然接近计算机视觉和人工智能,因为它们面临一个主要问题:它们无法扩展太多。 CNN 需要大量数据并整合资源才能很好地处理大图像。

当时,这种方法只适用于低分辨率图像。 Pytorch 是一个可以做深度学习操作的库。 我们可以用它来执行卷积神经网络。 卷积神经网络包含许多层人工神经元。 合成神经元是生物对应物的复杂模拟,是计算多个输入和产品值激活的加权质量的数学函数。

卷积神经网络pytorch
图片2

上图向我们展示了一个 CNN 模型,它接收一个类似数字的图像 2,并为我们提供图像中显示的数字作为数字的结果。 我们将在本文中详细讨论我们如何获得它。

CIFAR-10 是一个包含 10 个不同类别的图像集合的数据集。 该数据集广泛用于研究目的,以测试不同的机器学习模型,尤其是计算机视觉问题。 在本文中,我们将尝试使用 Pytorch 构建神经网络模型,并在 CIFAR-10 数据集上对其进行测试,以检查可以获得何种预测精度。

导入 PyTorch 库 

将 numpy 导入为 np 将熊猫导入为 pd
import torch import torch.nn.functional as F from torchvision import datasets,transforms from torch import nn import matplotlib.pyplot as plt import numpy as np import seaborn as sns #from tqdm.notebook import tqdm from tqdm import tqdm

在这一步中,我们导入所需的库。 我们可以看到我们使用 NumPy 进行数值运算,使用 Pandas 进行数据框运算。 Torch 库用于导入 Pytorch。

Pytorch 有一个 nn 组件,用于机器学习操作和功能的抽象。 这是作为 F 导入的。使用 torchvision 库,以便我们可以导入 CIFAR-10 数据集。 这个库有很多图像数据集,被广泛用于研究。 可以导入转换,以便我们可以将图像大小调整为所有图像的大小相同。 使用 tqdm 以便我们可以在训练期间跟踪进度并用于可视化。

读取所需的数据集

trainData = pd.read_csv('cifar-10/trainLabels.csv') trainData.head()

读取数据集后,我们可以看到各种标签,如青蛙、卡车、鹿、汽车等。

使用 PyTorch 分析数据

print("点数:",trainData.shape[0]) print("特征数:",trainData.shape[1]) print("Features:",trainData.columns.values) print("特征数:",trainData.shape[12,8]) trainData 中 col 的唯一值"): print(col,":",len(trainData[col].unique())) plt.figure(figsize=(XNUMX))

输出:

点数:50000 特征数:2 特征:['id' 'label'] 唯一值数 id:50000 标签:10

在这一步中,我们分析数据集,看到我们的训练数据有大约 50000 行,带有它们的 id 和相关标签。 与名称 CIFAR-10 一样,共有 10 个类。

使用 PyTorch 获取验证集

from torch.utils.data import random_split val_size = 5000 train_size = len(dataset) - val_size train_ds, val_ds = random_split(dataset, [train_size, val_size]) len(train_ds), len(val_ds)

此步骤与训练步骤相同,但我们希望将数据拆分为训练集和验证集。

(45000,5000)
from torch.utils.data.dataloader import DataLoader batch_size=64 train_dl = DataLoader(train_ds, batch_size, shuffle=True, num_workers=4, pin_memory=True) val_dl = DataLoader(val_ds, batch_size, num_workers=4, pin_memory=True)

torch.utils 有一个数据加载器,它可以帮助我们绕过各种参数(如工人数量或批量大小)加载所需的数据。

定义所需的功能

@torch.no_grad() defaccuracy(outputs, labels): _, preds = torch.max(outputs, dim=1) return torch.tensor(torch.sum(preds == labels).item() / len(preds )) class ImageClassificationBase(nn.Module): def training_step(self, batch): images, labels = batch out = self(images) # 生成预测 loss = F.cross_entropy(out, labels) # 计算损失 accu = accuracy(out ,labels) return loss,accu def validation_step(self, batch): images, labels = batch out = self(images) # 生成预测 loss = F.cross_entropy(out, labels) # 计算损失 acc =accuracy(out, labels) # 计算准确率 return {'Loss': loss.detach(), 'Accuracy': acc} def validation_epoch_end(self,outputs): batch_losses = [x['Loss'] for x in output] epoch_loss = torch.stack(batch_losses) ).mean() # 合并损失 batch_accs = [x['Accuracy'] for x in output] epoch_acc = torch.stack(batch_accs).mean() # 合并精度 return {'Loss': epoch_loss.item(), '准确度':epoch_acc.item()} def epoch_end(self, epoch, result): pr int("Epoch :",epoch + 1) print(f'Train Accuracy:{result["train_accuracy"]*100:.2f}% Validation Accuracy:{result["Accuracy"]*100:.2f}%' ) 打印(f'火车损失:{result["train_loss"]:.4f} 验证损失:{result["Loss"]:.4f}')

正如我们在这里看到的,我们使用了 ImageClassification 的类实现,它采用了一个参数,即 nn.Module。 在这个类中,我们可以实现各种功能或各种步骤,如训练、验证等。这里的功能是简单的 Python 实现。

训练步骤分批获取图像和标签。 我们使用交叉熵作为损失函数并计算损失并返回损失。 这类似于我们在函数中看到的验证步骤。 epoch 结束时将损失和精度结合起来,最后,我们打印精度和损失。

卷积神经网络模块的实现

class Cifar10CnnModel(ImageClassificationBase): def __init__(self): super().__init__() self.network = nn.Sequential( nn.Conv2d(3, 32, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(2, 2), # output: 64 x 16 x 16 nn.BatchNorm2d(64) , nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1), nn .ReLU(), nn.MaxPool2d(2, 2), # 输出:128 x 8 x 8 nn.BatchNorm2d(128), nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(2, 2), # output: 256 x 4 x 4 nn.BatchNorm2d(256), nn.Flatten(), nn.Linear(256*4*4, 1024), nn.ReLU(), nn.Linear(1024, 512), nn.ReLU(), nn.Linear (512, 10)) def forward(self, xb): return self.network(xb)

这是神经网络实现中最重要的部分。 在整个过程中,我们使用从 Torch 导入的 nn 模块。 正如我们在第一行中看到的,Conv2d 是一个帮助实现卷积神经网络的模块。 这里的第一个参数 3 表示图像是彩色的,是 RGB 格式的。 如果它是灰度图像,我们会选择 1。

32 是初始输出通道的大小,当我们进入下一个 conv2d 层时,我们会将这个 32 作为输入通道,64 作为输出通道。

第一行中的第三个参数称为内核大小,它帮助我们处理使用的过滤器。 填充操作是最后一个参数。

卷积操作在这里连接到一个激活层和 Relu。 在两个 Conv2d 层之后,我们有一个大小为 2 * 2 的最大池化操作。从中得出的值是批量标准化的,以确保稳定性并避免内部协变量偏移。 使用更多层重复这些操作,以加深网络并减小规模。 最后,我们将图层展平,以便我们可以构建一个线性图层,将这些值映射到 10 个值。 这 10 个神经元中每个神经元的概率将根据最大概率确定特定图像属于哪个类别。

训练模型

@torch.no_grad() def 评估(model, data_loader): model.eval() 输出 = [model.validation_step(batch) for batch in data_loader] return model.validation_epoch_end(outputs) def fit(model, train_loader, val_loader,epochs =10,learning_rate=0.001): best_valid = None history = [] optimizer = torch.optim.Adam(model.parameters(), learning_rate,weight_decay=0.0005) for epoch in range(epochs): # 训练阶段 model.train( ) train_losses = [] train_accuracy = [] for batch in tqdm(train_loader): loss,accu = model.training_step(batch) train_losses.append(loss) train_accuracy.append(accu) loss.backward() optimizer.step() 优化器.zero_grad() # 验证阶段 result =evaluate(model, val_loader) result['train_loss'] = torch.stack(train_losses).mean().item() result['train_accuracy'] = torch.stack(train_accuracy). mean().item() model.epoch_end(epoch, result) if(best_valid == None or best_valid
历史 = 拟合(模型,train_dl,val_dl)

这是训练我们的模型以获得所需结果的基本步骤。 此处的拟合函数将使用我们创建的模型拟合训练和 Val 数据。 fit 函数最初采用一个名为 history 的列表,该列表负责处理每个 epoch 的迭代数据。 我们运行一个 for 循环,以便我们可以迭代每个 epoch。 对于每个批次,我们确保使用 tqdm 显示进度。 我们称我们之前实施的训练步骤并计算准确度和损失。 我们之前定义的反向传播和运行优化器。 一旦我们这样做,我们就会跟踪我们的列表,这些功能可以帮助我们打印详细信息和进度。

另一方面,evaluate 函数使用 eval 函数,对于每一步,我们从数据加载器中获取批处理,并计算输出。 然后将该值传递到我们之前定义的验证纪元端,并返回相应的值。

绘制结果

在这一步中,我们将可视化每个时期的准确性。 我们可以观察到,随着 epoch 的增加,系统的准确性不断增加,同样的损失也在不断减少。 此处的红线表示训练数据进度,蓝色表示验证。 我们可以看到我们的结果中存在大量的过度拟合,因为训练数据的表现非常优于验证结果,在损失的情况下也是如此。 10 个 epoch 后,训练数据似乎绕过了 90% 的准确率,但损失约为 0.5。 测试数据大约为 81%,损失接近 0.2。

def plot_accuracies(history): Validation_accuracies = [x['Accuracy'] for x in history] ​​Training_Accuracy = [x['train_accuracy'] for x in history] ​​plt.plot(Training_Accuracies, '-rx') plt.plot(Validation_accuracies , '-bx') plt.xlabel('epoch') plt.ylabel('accuracy') plt.legend(['Training', 'Validation']) plt.title('Accuracy vs. No. of epochs') ; plot_accuracies(历史)
精度图
def plot_losses(history): train_losses = [x.get('train_loss') for x in history] ​​val_losses = [x['Loss'] for x in history] ​​plt.plot(train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel('epoch') plt.ylabel('loss') plt.legend(['Training', 'Validation']) plt.title('Loss vs. No. of epochs '); 情节损失(历史)

test_dataset = ImageFolder(data_dir+'/test', transform=ToTensor()) test_loader = DeviceDataLoader(DataLoader(test_dataset, batch_size), device) result = evaluate(final_model, test_loader) print(f'Test Accuracy:{result["Accuracy" ]*100:.2f}%')
测试准确率:81.07%

我们可以看到我们最终的准确率为 81.07%。

总结

图片:https://unsplash.com/photos/5L0R8ZqPZHk

关于我: 我是一名对深度学习和自然语言处理领域感兴趣的研究生,目前正在攻读人工智能研究生。

图片来源

  1. Image 1: https://becominghuman.ai/cifar-10-image-classification-fd2ace47c5e8
  2. 图 2:https://www.analyticsvidhya.com/blog/2021/05/convolutional-neural-networks-cnn/

请随时与我联系:

  1.  领英:https://www.linkedin.com/in/siddharth-m-426a9614a/
  2.  Github:https://github.com/Siddharth1698

本文中显示的媒体不归 Analytics Vidhya 所有,由作者自行决定使用。

来源:https://www.analyticsvidhya.com/blog/2021/09/convolutional-neural-network-pytorch-implementation-on-cifar10-dataset/

时间戳记:

更多来自 分析维迪亚