小白学习pytorch教程八使用图像数据增强手段,提升cifar-10数据集精确度(代码片段)

刘润森! 刘润森!     2022-12-07     723

关键词:

@Author:Runsen

上次基于CIFAR-10 数据集,使用PyTorch ​​构建图像分类模型的精确度是60%,对于如何提升精确度,方法就是常见的transforms图像数据增强手段。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader

import torchvision
import torchvision.datasets as datasets
import torchvision.transforms as transforms
import torchvision.utils as vutils

import numpy as np
import os
import warnings
from matplotlib import pyplot as plt
warnings.filterwarnings('ignore')`
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

加载数据集

# number of images in one forward and backward pass
batch_size = 128

# number of subprocesses used for data loading
# Normally do not use it if your os is windows
num_workers = 2

train_dataset = datasets.CIFAR10('./data/CIFAR10/', 
                                 train = True, 
                                 download = True, 
                                 transform = transform_train)

train_loader = DataLoader(train_dataset, 
                          batch_size = batch_size, 
                          shuffle = True, 
                          num_workers = num_workers)

val_dataset = datasets.CIFAR10('./data/CIFAR10', 
                                train = True, 
                                transform = transform_test)

val_loader = DataLoader(val_dataset, 
                        batch_size = batch_size, 
                        shuffle = False, 
                        num_workers = num_workers)

test_dataset = datasets.CIFAR10('./data/CIFAR10', 
                                train = False, 
                                transform = transform_test)

test_loader = DataLoader(test_dataset, 
                         batch_size = batch_size, 
                         shuffle = False, 
                         num_workers = num_workers)

# declare classes in CIFAR10
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

之前的transform ’只是进行了缩放和归一,在这里添加RandomCrop和RandomHorizontalFlip

# define a transform to normalize the data

transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(), # converting images to tensor
    transforms.Normalize(mean = (0.5, 0.5, 0.5), std = (0.5, 0.5, 0.5)) 
    # if the image dataset is black and white image, there can be just one number. 
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean = (0.5, 0.5, 0.5), std = (0.5, 0.5, 0.5))
])

可视化具体的图像

# function that will be used for visualizing the data

def imshow(img):
    img = img / 2 + 0.5  # unnormalize
    plt.imshow(np.transpose(img, (1, 2, 0)))  # convert from Tensor image

# obtain one batch of imges from train dataset
dataiter = iter(train_loader)
images, labels = dataiter.next()
images = images.numpy() # convert images to numpy for display

# plot the images in one batch with the corresponding labels
fig = plt.figure(figsize = (25, 4))

# display images
for idx in np.arange(10):
    ax = fig.add_subplot(1, 10, idx+1, xticks=[], yticks=[])
    imshow(images[idx])
    ax.set_title(classes[labels[idx]])

建立常见的CNN模型

# define the CNN architecture

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        
        self.main = nn.Sequential(
            # 3x32x32
            nn.Conv2d(in_channels = 3, out_channels = 32, kernel_size = 3, padding = 1), # 3x32x32 (O = (N+2P-F/S)+1)
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size = 2, stride = 2), # 32x16x16
            nn.BatchNorm2d(32),
            
            nn.Conv2d(32, 64, kernel_size = 3, padding = 1), # 32x16x16
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2), # 64x8x8
            nn.BatchNorm2d(64),
            
            nn.Conv2d(64, 128, 3, padding = 1), # 64x8x8
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2), # 128x4x4
            nn.BatchNorm2d(128),
        )
        
        self.fc = nn.Sequential(
            nn.Linear(128*4*4, 1024),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            
            nn.Linear(1024, 256),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            
            nn.Linear(256, 10)
        )
        
    def forward(self, x):
        # Conv and Poolilng layers
        x = self.main(x)
        
        # Flatten before Fully Connected layers
        x = x.view(-1, 128*4*4) 
        
        # Fully Connected Layer
        x = self.fc(x)
        return x

cnn = CNN().to(device)
cnn


torch.nn.CrossEntropyLoss对输出概率介于0和1之间的分类模型进行分类。

训练模型

# 超参数:Hyper Parameters
learning_rate = 0.001
train_losses = []
val_losses = []

# Loss function and Optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(cnn.parameters(), lr = learning_rate)

# define train function that trains the model using a CIFAR10 dataset

def train(model, epoch, num_epochs):
    model.train()
    
    total_batch = len(train_dataset) // batch_size
    
    for i, (images, labels) in enumerate(train_loader):
            
        X = images.to(device)
        Y = labels.to(device)

        ### forward pass and loss calculation
        # forward pass
        pred = model(X)
        #c alculation  of loss value
        cost = criterion(pred, Y)

        ### backward pass and optimization
        # gradient initialization
        optimizer.zero_grad()
        # backward pass
        cost.backward()
        # parameter update
        optimizer.step()
            
        # training stats
        if (i+1) % 100 == 0:
            print('Train, Epoch [%d/%d], lter [%d/%d], Loss: %.4f' 
                  % (epoch+1, num_epochs, i+1, total_batch, np.average(train_losses)))
            
            train_losses.append(cost.item())# def the validation function that validates the model using CIFAR10 dataset

def validation(model, epoch, num_epochs):
    model.eval()
    
    total_batch = len(val_dataset) // batch_size
    
    for i, (images, labels) in enumerate(val_loader):
        
        X = images.to(device)
        Y = labels.to(device)
        
        with torch.no_grad():
            pred = model(X)
            cost = criterion(pred, Y)
        
        if (i+1) % 100 == 0:
            print("Validation, Epoch [%d/%d], lter [%d/%d], Loss: %.4f"
                  % (epoch+1, num_epochs, i+1, total_batch, np.average(val_losses)))
            
            val_losses.append(cost.item())
            
def plot_losses(train_losses, val_losses):
    plt.figure(figsize=(5, 5))
    plt.plot(train_losses, label='Train', alpha=0.5)
    plt.plot(val_losses, label='Validation', alpha=0.5)
    plt.xlabel('Epochs')
    plt.ylabel('Losses')
    plt.legend()
    plt.grid(b=True)
    plt.title('CIFAR 10 Train/Val Losses Over Epoch')
    plt.show()

num_epochs = 20
for epoch in range(num_epochs):
    train(cnn, epoch, num_epochs)
    validation(cnn, epoch, num_epochs)
    torch.save(cnn.state_dict(), './data/Tutorial_3_CNN_Epoch_.pkl'.format(epoch+1))

plot_losses(train_losses, val_losses)

=
测试模型

def test(model):
    
    # declare that the model is about to evaluate
    model.eval()

    correct = 0
    total = 0
    
    with torch.no_grad():
        for images, labels in test_dataset:
            images = images.unsqueeze(0).to(device)
            
            # forward pass
            outputs = model(images)
            
            _, predicted = torch.max(outputs.data, 1)
            total += 1
            correct += (predicted == labels).sum().item()

    print("Accuracy of Test Images: %f %%" % (100 * float(correct) / total))


经过图像数据增强。模型从60提升到了84。

测试模型在哪些类上表现良好,

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))

with torch.no_grad():
    
    for data in test_loader:
        images, labels = data
        images = images.to(device)
        labels = labels.to(device)
        outputs = cnn(images)
        
        _, predicted = torch.max(outputs, 1)
        c = (predicted == labels).squeeze()
        
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1


for i in range(10):
    print('Accuracy of %5s : %2d %%' % (
        classes[i], 100 * class_correct[i] / class_total[i]))

小白学习pytorch教程十七pytorch中数据集torchvision和torchtext(代码片段)

@Author:Runsen对于PyTorch加载和处理不同类型数据,官方提供了torchvision和torchtext。之前使用torchDataLoader类直接加载图像并将其转换为张量。现在结合torchvision和torchtext介绍torch中的内置数据集Torchvision中的数据集MNISTMNIST... 查看详情

[九]深度学习pytorch-transforms图像增强(剪裁翻转旋转)(代码片段)

0.往期内容[一]深度学习Pytorch-张量定义与张量创建[二]深度学习Pytorch-张量的操作:拼接、切分、索引和变换[三]深度学习Pytorch-张量数学运算[四]深度学习Pytorch-线性回归[五]深度学习Pytorch-计算图与动态图机制[六]深度学习Pyto... 查看详情

小白学习pytorch教程十二迁移学习:微调vgg19实现图像分类(代码片段)

@Author:Runsen前言:迁移学习就是利用数据、任务或模型之间的相似性,将在旧的领域学习过或训练好的模型,应用于新的领域这样的一个过程。从这段定义里面,我们可以窥见迁移学习的关键点所在,... 查看详情

小白学习pytorch教程十四迁移学习:微调resnet实现男人和女人图像分类(代码片段)

@Author:Runsen上次微调了Alexnet,这次微调ResNet实现男人和女人图像分类。ResNet是ResidualNetworks的缩写,是一种经典的神经网络,用作许多计算机视觉任务。ResNet论文参见此处:https://arxiv.org/abs/1512.03385该模型... 查看详情

小白学习pytorch教程十三迁移学习:微调alexnet实现ant和bee图像分类(代码片段)

@Author:Runsen上次微调了VGG19,这次微调Alexnet实现ant和bee图像分类。多年来,CNN许多变体已经发展起来,从而产生了几种CNN架构。其中最常见的是:LeNet-5(1998)AlexNet(2012)ZFNet(2013)GoogleNet/Inception(2014 查看详情

小白学习pytorch教程十七基于torch实现unet图像分割模型(代码片段)

@Author:Runsen在图像领域,除了分类,CNN今天还用于更高级的问题,如图像分割、对象检测等。图像分割是计算机视觉中的一个过程,其中图像被分割成代表图像中每个不同类别的不同段。上面图片一段代表... 查看详情

如何使用 Pytorch 将增强图像添加到原始数据集中?

】如何使用Pytorch将增强图像添加到原始数据集中?【英文标题】:HowtoaddaugmentedimagestooriginaldatasetusingPytorch?【发布时间】:2019-07-2423:11:43【问题描述】:据我了解,RandomHorizo​​ntalFlip等替换图像而不是向数据集添加新图像。如... 查看详情

小白学习pytorch教程七基于乳腺癌数据集​​构建logistic二分类模型(代码片段)

...、文字分类都属于这一类。在这篇博客中,将学习如何在PyTorch中实现逻辑回归。文章目录1.数据集加载2.预处理3.模型搭建4.训练和优化1.数据集加载在这里,我将使用来自sklearn库的乳腺癌数据集。这是一个简单的二元类分类数据... 查看详情

小白学习pytorch教程十一基于mnist数据集训练第一个生成性对抗网络(代码片段)

@Author:RunsenGAN是使用两个神经网络模型训练的生成模型。一种模型称为生成网络模型,它学习生成新的似是而非的样本。另一个模型被称为判别网络,它学习区分生成的例子和真实的例子。生成性对抗网络2014࿰... 查看详情

小白学习pytorch教程十一基于mnist数据集训练第一个生成性对抗网络(代码片段)

@Author:RunsenGAN是使用两个神经网络模型训练的生成模型。一种模型称为生成网络模型,它学习生成新的似是而非的样本。另一个模型被称为判别网络,它学习区分生成的例子和真实的例子。生成性对抗网络2014࿰... 查看详情

小白学习pytorch教程十基于大型电影评论数据集训练第一个lstm模型(代码片段)

@Author:Runsen文章目录编码建立字典并对评论进行编码对标签进行编码删除异常值填充序列数据加载器RNN模型的实现训练本博客对原始IMDB数据集进行预处理,建立一个简单的深层神经网络模型,对给定数据进行情感分析... 查看详情

小白学习pytorch教程九基于pytorch训练第一个rnn模型(代码片段)

@Author:Runsen当阅读一篇课文时,我们可以根据前面的单词来理解每个单词的,而不是从零开始理解每个单词。这可以称为记忆。卷积神经网络模型(CNN)不能实现这种记忆,因此引入了递归神经网络模型(RNN)来解决这一问题... 查看详情

pytorch土堆pytorch教程学习transforms的使用(代码片段)

transforms在工具包torchvision下,用来对图像进行预处理:数据中心化、数据标准化、缩放、裁剪、旋转、翻转、填充、噪声添加、灰度变换、线性变换、仿射变换、亮度/饱和度/对比度变换等。transforms本质就是一个python文件,相当... 查看详情

小白学习pytorch教程十六在多标签分类任务上微调bert模型(代码片段)

@Author:RunsenBERT模型在NLP各项任务中大杀四方,那么我们如何使用这一利器来为我们日常的NLP任务来服务呢?首先介绍使用BERT做文本多标签分类任务。文本多标签分类是常见的NLP任务,文本介绍了如何使用Bert... 查看详情

在 PyTorch 中进行数据增强后得到糟糕的图像

】在PyTorch中进行数据增强后得到糟糕的图像【英文标题】:GettingBadImagesAfterDataAugmentationinPyTorch【发布时间】:2020-09-0517:27:07【问题描述】:我正在研究一个核分割问题,我试图在染色组织的图像中识别核的位置。给定的训练数... 查看详情

pytorch基础——迁移学习(代码片段)

一、介绍内容使机器能够“举一反三”的能力知识点使用PyTorch的数据集套件从本地加载数据的方法迁移训练好的大型神经网络模型到自己模型中的方法迁移学习与普通深度学习方法的效果区别两种迁移学习方法的区别二、从图... 查看详情

pytorch1.0中文官方教程:空间变换器网络教程(代码片段)

译者:冯宝宝作者:GhassenHAMROUNI在本教程中,您将学习如何使用称为空间变换器网络的视觉注意机制来扩充您的网络。你可以在DeepMindpaper阅读有关空间变换器网络的更多内容。空间变换器网络是对任何空间变换的差异化关注的概... 查看详情

深度学习炼丹-数据预处理和增强(代码片段)

...ages2.1,图像normalization定义2.2,图像normalization的好处2.3,PyTorch实践图像normalization三,数据增强(扩增)3.1,opencv 查看详情