热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

pytorchVGG11识别cifar10数据集(训练+预测单张输入图片操作)

这篇文章主要介绍了pytorchVGG11识别cifar10数据集(训练+预测单张输入图片操作),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

首先这是VGG的结构图,VGG11则是红色框里的结构,共分五个block,如红框中的VGG11第一个block就是一个conv3-64卷积层:

一,写VGG代码时,首先定义一个 vgg_block(n,in,out)方法,用来构建VGG中每个block中的卷积核和池化层:

n是这个block中卷积层的数目,in是输入的通道数,out是输出的通道数

有了block以后,我们还需要一个方法把形成的block叠在一起,我们定义这个方法叫vgg_stack:

def vgg_stack(num_convs, channels): # vgg_net = vgg_stack((1, 1, 2, 2, 2), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))


 net = []
 for n, c in zip(num_convs, channels):
  in_c = c[0]
  out_c = c[1]
  net.append(vgg_block(n, in_c, out_c))
 return nn.Sequential(*net)

右边的注释

vgg_net = vgg_stack((1, 1, 2, 2, 2), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))

里,(1, 1, 2, 2, 2)表示五个block里,各自的卷积层数目,((3, 64), (64, 128), (128, 256), (256, 512), (512, 512))表示每个block中的卷积层的类型,如(3,64)表示这个卷积层输入通道数是3,输出通道数是64。vgg_stack方法返回的就是完整的vgg11模型了。

接着定义一个vgg类,包含vgg_stack方法:

#vgg类
class vgg(nn.Module):
 def __init__(self):
  super(vgg, self).__init__()
  self.feature = vgg_net
  self.fc = nn.Sequential(
   nn.Linear(512, 100),
   nn.ReLU(True),
   nn.Linear(100, 10)
  )
 
 def forward(self, x):
  x = self.feature(x)
  x = x.view(x.shape[0], -1)
  x = self.fc(x)
  return x

最后:

net = vgg() #就能获取到vgg网络

那么构建vgg网络完整的pytorch代码是:

def vgg_block(num_convs, in_channels, out_channels):
 net = [nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), nn.ReLU(True)]
 
 for i in range(num_convs - 1): # 定义后面的许多层
  net.append(nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1))
  net.append(nn.ReLU(True))
 
 net.append(nn.MaxPool2d(2, 2)) # 定义池化层
 return nn.Sequential(*net)
 
# 下面我们定义一个函数对这个 vgg block 进行堆叠
def vgg_stack(num_convs, channels): # vgg_net = vgg_stack((1, 1, 2, 2, 2), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))
 net = []
 for n, c in zip(num_convs, channels):
  in_c = c[0]
  out_c = c[1]
  net.append(vgg_block(n, in_c, out_c))
 return nn.Sequential(*net)
 
#确定vgg的类型,是vgg11 还是vgg16还是vgg19
vgg_net = vgg_stack((1, 1, 2, 2, 2), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))
#vgg类
class vgg(nn.Module):
 def __init__(self):
  super(vgg, self).__init__()
  self.feature = vgg_net
  self.fc = nn.Sequential(
   nn.Linear(512, 100),
   nn.ReLU(True),
   nn.Linear(100, 10)
  )
 def forward(self, x):
  x = self.feature(x)
  x = x.view(x.shape[0], -1)
  x = self.fc(x)
  return x
 
#获取vgg网络
net = vgg() 

基于VGG11的cifar10训练代码:

import sys
import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
from torchvision.datasets import CIFAR10
import torchvision.transforms as transforms
 
def vgg_block(num_convs, in_channels, out_channels):
 net = [nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), nn.ReLU(True)]
 
 for i in range(num_convs - 1): # 定义后面的许多层
  net.append(nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1))
  net.append(nn.ReLU(True))
 
 net.append(nn.MaxPool2d(2, 2)) # 定义池化层
 return nn.Sequential(*net)
 
# 下面我们定义一个函数对这个 vgg block 进行堆叠
def vgg_stack(num_convs, channels): # vgg_net = vgg_stack((1, 1, 2, 2, 2), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))
 net = []
 for n, c in zip(num_convs, channels):
  in_c = c[0]
  out_c = c[1]
  net.append(vgg_block(n, in_c, out_c))
 return nn.Sequential(*net)
 
#vgg类
class vgg(nn.Module):
 def __init__(self):
  super(vgg, self).__init__()
  self.feature = vgg_net
  self.fc = nn.Sequential(
   nn.Linear(512, 100),
   nn.ReLU(True),
   nn.Linear(100, 10)
  )
 def forward(self, x):
  x = self.feature(x)
  x = x.view(x.shape[0], -1)
  x = self.fc(x)
  return x
 
# 然后我们可以训练我们的模型看看在 cifar10 上的效果
def data_tf(x):
 x = np.array(x, dtype='float32') / 255
 x = (x - 0.5) / 0.5
 x = x.transpose((2, 0, 1)) ## 将 channel 放到第一维,只是 pytorch 要求的输入方式
 x = torch.from_numpy(x)
 return x
 
transform = transforms.Compose([transforms.ToTensor(),
         transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5)),
         ])
def get_acc(output, label):
 total = output.shape[0]
 _, pred_label = output.max(1)
 num_correct = (pred_label == label).sum().item()
 return num_correct / total
 
def train(net, train_data, valid_data, num_epochs, optimizer, criterion):
 if torch.cuda.is_available():
  net = net.cuda()
 for epoch in range(num_epochs):
  train_loss = 0
  train_acc = 0
  net = net.train()
  for im, label in train_data:
   if torch.cuda.is_available():
    im = Variable(im.cuda())
    label = Variable(label.cuda())
   else:
    im = Variable(im)
    label = Variable(label)
   # forward
   output = net(im)
   loss = criterion(output, label)
   # forward
   optimizer.zero_grad()
   loss.backward()
   optimizer.step()
 
   train_loss += loss.item()
   train_acc += get_acc(output, label)
 
  if valid_data is not None:
   valid_loss = 0
   valid_acc = 0
   net = net.eval()
   for im, label in valid_data:
    if torch.cuda.is_available():
     with torch.no_grad():
      im = Variable(im.cuda())
      label = Variable(label.cuda())
    else:
     with torch.no_grad():
      im = Variable(im)
      label = Variable(label)
    output = net(im)
    loss = criterion(output, label)
    valid_loss += loss.item()
    valid_acc += get_acc(output, label)
   epoch_str = (
     "Epoch %d. Train Loss: %f, Train Acc: %f, Valid Loss: %f, Valid Acc: %f, "
     % (epoch, train_loss / len(train_data),
      train_acc / len(train_data), valid_loss / len(valid_data),
      valid_acc / len(valid_data)))
  else:
   epoch_str = ("Epoch %d. Train Loss: %f, Train Acc: %f, " %
       (epoch, train_loss / len(train_data),
       train_acc / len(train_data)))
 
  # prev_time = cur_time
  print(epoch_str)
 
if __name__ == '__main__':
 # 作为实例,我们定义一个稍微简单一点的 vgg11 结构,其中有 8 个卷积层
 vgg_net = vgg_stack((1, 1, 2, 2, 2), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))
 print(vgg_net)
 
 train_set = CIFAR10('./data', train=True, transform=transform, download=True)
 train_data = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
 test_set = CIFAR10('./data', train=False, transform=transform, download=True)
 test_data = torch.utils.data.DataLoader(test_set, batch_size=128, shuffle=False)
 
 net = vgg()
 optimizer = torch.optim.SGD(net.parameters(), lr=1e-1)
 criterion = nn.CrossEntropyLoss() #损失函数为交叉熵
 
 train(net, train_data, test_data, 50, optimizer, criterion)
 torch.save(net, 'vgg_model.pth')

结束后,会出现一个模型文件vgg_model.pth

二,然后网上找张图片,把图片缩成32x32,放到预测代码中,即可有预测结果出现,预测代码如下:

import torch
import cv2
import torch.nn.functional as F
from vgg2 import vgg ##重要,虽然显示灰色(即在次代码中没用到),但若没有引入这个模型代码,加载模型时会找不到模型
from torch.autograd import Variable
from torchvision import datasets, transforms
import numpy as np
 
classes = ('plane', 'car', 'bird', 'cat',
   'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
if __name__ == '__main__':
 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
 model = torch.load('vgg_model.pth') # 加载模型
 model = model.to(device)
 model.eval() # 把模型转为test模式
 
 img = cv2.imread("horse.jpg") # 读取要预测的图片
 trans = transforms.Compose(
  [
   transforms.ToTensor(),
   transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
  ])
 
 img = trans(img)
 img = img.to(device)
 img = img.unsqueeze(0) # 图片扩展多一维,因为输入到保存的模型中是4维的[batch_size,通道,长,宽],而普通图片只有三维,[通道,长,宽]
 # 扩展后,为[1,1,28,28]
 output = model(img)
 prob = F.softmax(output,dim=1) #prob是10个分类的概率
 print(prob)
 value, predicted = torch.max(output.data, 1)
 print(predicted.item())
 print(value)
 pred_class = classes[predicted.item()]
 print(pred_class)
 
 # prob = F.softmax(output, dim=1)
 # prob = Variable(prob)
 # prob = prob.cpu().numpy() # 用GPU的数据训练的模型保存的参数都是gpu形式的,要显示则先要转回cpu,再转回numpy模式
 # print(prob) # prob是10个分类的概率
 # pred = np.argmax(prob) # 选出概率最大的一个
 # # print(pred)
 # # print(pred.item())
 # pred_class = classes[pred]
 # print(pred_class)

缩成32x32的图片:

运行结果:

以上这篇pytorch VGG11识别cifar10数据集(训练+预测单张输入图片操作)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


推荐阅读
  • 解决Jupyter Notebook 中无法找到 TensorFlow 的问题
    本文记录了解决 Jupyter Notebook 在特定环境中无法识别已安装的 TensorFlow 的方法。主要原因是 Jupyter 默认在 base 环境中运行,而 TensorFlow 可能在其他环境中。通过配置 Jupyter 使其能够访问目标环境中的 TensorFlow。 ... [详细]
  • 本文介绍了如何使用 Google Colab 的免费 GPU 资源进行深度学习应用开发。Google Colab 是一个无需配置即可使用的云端 Jupyter 笔记本环境,支持多种深度学习框架,并且提供免费的 GPU 计算资源。 ... [详细]
  • 在 PyTorch 的 `CrossEntropyLoss` 函数中,当目标标签 `target` 为类别 ID 时,实际上会进行 one-hot 编码处理。例如,假设总共有三个类别,其中一个类别的 ID 为 2,则该标签会被转换为 `[0, 0, 1]`。这一过程简化了多分类任务中的损失计算,使得模型能够更高效地进行训练和评估。此外,`CrossEntropyLoss` 还结合了 softmax 激活函数和负对数似然损失,进一步提高了模型的性能和稳定性。 ... [详细]
  • 本文探讨了BERT模型在自然语言处理领域的应用与实践。详细介绍了Transformers库(曾用名pytorch-transformers和pytorch-pretrained-bert)的使用方法,涵盖了从模型加载到微调的各个环节。此外,还分析了BERT在文本分类、情感分析和命名实体识别等任务中的性能表现,并讨论了其在实际项目中的优势和局限性。 ... [详细]
  • 在Windows环境下离线安装PyTorch GPU版时,首先需确认系统配置,例如本文作者使用的是Win8、CUDA 8.0和Python 3.6.5。用户应根据自身Python和CUDA版本,在PyTorch官网查找并下载相应的.whl文件。此外,建议检查系统环境变量设置,确保CUDA路径正确配置,以避免安装过程中可能出现的兼容性问题。 ... [详细]
  • 本文将深入探讨生成对抗网络(GAN)在计算机视觉领域的应用。作为该领域的经典模型,GAN通过生成器和判别器的对抗训练,能够高效地生成高质量的图像。本文不仅回顾了GAN的基本原理,还将介绍一些最新的进展和技术优化方法,帮助读者全面掌握这一重要工具。 ... [详细]
  • PyTorch 使用问题:解决导入 torch 后 torch.cuda.is_available() 返回 False 的方法
    在配置 PyTorch 时,遇到 `torch.cuda.is_available()` 返回 `False` 的问题。本文总结了多种解决方案,并分享了个人在 PyCharm、Python 和 Anaconda3 环境下成功配置 CUDA 的经验,以帮助读者避免常见错误并顺利使用 GPU 加速。 ... [详细]
  • 本文深入解析了PyTorch框架中的`Parameter()`类和`register_parameter()`方法。首先,通过官方文档介绍了`Parameter()`类的基本功能及其在模型参数管理中的作用。接着,详细探讨了`register_parameter()`方法如何将自定义参数添加到模型中,并确保这些参数能够被优化器识别和更新。最后,对比分析了两者的主要差异,帮助读者理解在不同场景下选择合适的方法来管理和优化模型参数。 ... [详细]
  • 2019年斯坦福大学CS224n课程笔记:深度学习在自然语言处理中的应用——Word2Vec与GloVe模型解析
    本文详细解析了2019年斯坦福大学CS224n课程中关于深度学习在自然语言处理(NLP)领域的应用,重点探讨了Word2Vec和GloVe两种词嵌入模型的原理与实现方法。通过具体案例分析,深入阐述了这两种模型在提升NLP任务性能方面的优势与应用场景。 ... [详细]
  • 不用蘑菇,不拾金币,我通过强化学习成功通关29关马里奥,创造全新纪录
    《超级马里奥兄弟》由任天堂于1985年首次发布,是一款经典的横版过关游戏,至今已在多个平台上售出超过5亿套。该游戏不仅勾起了许多玩家的童年回忆,也成为强化学习领域的热门研究对象。近日,通过先进的强化学习技术,研究人员成功让AI通关了29关,创造了新的纪录。这一成就不仅展示了强化学习在游戏领域的潜力,也为未来的人工智能应用提供了宝贵的经验。 ... [详细]
  • 本文提供了PyTorch框架中常用的预训练模型的下载链接及详细使用指南,涵盖ResNet、Inception、DenseNet、AlexNet、VGGNet等六大分类模型。每种模型的预训练参数均经过精心调优,适用于多种计算机视觉任务。文章不仅介绍了模型的下载方式,还详细说明了如何在实际项目中高效地加载和使用这些模型,为开发者提供全面的技术支持。 ... [详细]
  • 利用 PyTorch 实现 Python 中的高效矩阵运算 ... [详细]
  • 本文介绍了一款高效的开源OCR文本识别模型,结合了TextBoxes++和RetinaNet的优势。该模型在文本检测方面表现出色,适用于多种场景。项目代码已托管至GitHub,方便研究人员和开发者使用和改进。 ... [详细]
  • 在上一节中,我们完成了网络的前向传播实现。本节将重点探讨如何为检测输出设定目标置信度阈值,并应用非极大值抑制技术以提高检测精度。为了更好地理解和实践这些内容,建议读者已经完成本系列教程的前三部分,并具备一定的PyTorch基础知识。此外,我们将详细介绍这些技术的原理及其在实际应用中的重要性,帮助读者深入理解目标检测算法的核心机制。 ... [详细]
  • 在 PyTorch 中,`pin_memory` 技术用于锁定页面内存。当在创建 `DataLoader` 时将 `pin_memory` 参数设置为 `True`,这意味着生成的 Tensor 数据最初会被存储在锁定的内存中。这一技术能够显著提高数据从 CPU 到 GPU 的传输效率,从而加快训练速度。通过合理利用 `pin_memory`,可以有效减少数据加载的瓶颈,提升整体性能。 ... [详细]
author-avatar
的发个地方
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有