【使用Pytorch实现VGG16网络模型】

介绍

VGG-Network是K. Simonyan和A. Zisserman在论文“Very Deep Convolutional Networks for Large-Scale Image Recognition”中提出的卷积神经网络模型。该架构在 ImageNet 中实现了 92.7% 的 top-5 测试准确率,该网络拥有超过 1400 万张属于 1000 个类别的图像。它是深度学习领域的著名架构之一,将第1层和第2层的大内核大小的过滤器分别替换为11和5,显示了对 AlexNet 架构的改进,多个3×3内核大小的过滤器相继出现。它经过数周的训练,使用的是 NVIDIA Titan Black GPU。
在这里插入图片描述

VGG16 架构

卷积神经网络的输入是固定大小的 224 × 224 RGB 图像。它所做的唯一预处理是从每个像素中减去在训练数据集上计算的平均 RGB 值,然后图像通过一堆卷积(Conv.)层,其中有一个非常小的感受野为 3 × 3 的过滤器,这是捕捉左/右、上/下概念的最小尺寸和中心部分。在其中一种配置中,它还使用 1 × 1 卷积滤波器,可以将其视为输入通道的线性变换,然后是非线性变换,卷积步幅固定为 1 个像素;卷积层输入的空间填充使得卷积后空间分辨率保持不变,即对于 3 × 3 Conv,填充为 1 个像素,然后空间池化由 5 个最大池化层执行,其中 16 个最大池化层跟在一些 Conv 层之后,但不是所有的 Conv 层。这个最大池化是在一个 2 × 2 像素的窗口上执行的,步长为 2。

在这里插入图片描述
该架构包含一堆卷积层,它们在不同的架构中具有不同的深度,然后是三个全连接(FC)层:前两个 FC 各有 4096 个通道,第三个 FC 执行 1000 路分类,因此包含 1000 个通道,每个类一个通道,最后一层是soft-max层。全连接层的配置在所有网络中都是相似的,所有隐藏层都配备了校正 (ReLU) 非线性。此外,这里的一个网络包含局部响应归一化 (LRN),这种归一化不会提高训练数据集的性能,但使用它会导致内存消耗和计算时间增加。

架构总结

• 模型的输入是固定大小的 224×224224×224 RGB 图像

• 预处理是从每个像素中减去训练集 RGB 值的平均值

• 卷积层 17

       - 步幅固定为 1 像素

       – 3×33×3 的填充是 1 个像素

• 空间池化层

       – 按照惯例,这一层不计入网络深度

       – 空间池化是使用最大池化层完成的

       – 窗口大小为 2×22×2

       - 步幅固定为 2

       – 卷积网络使用 5 个最大池化层

• 全连接层:

       • 第一名:4096 (ReLU)。

       ▪第二:4096(ReLU)。

       ▪第三:1000(Softmax)。

架构配置

下图包含了 VGG 网络的卷积神经网络配置

以下层:

 • VGG-11

 • VGG-11 (LRN)

 • VGG-13

 • VGG-16 (Conv1)

 • VGG-16

 • VGG-19

在这里插入图片描述
上面提到了卷积神经网络配置,每列一个。在下文中,网络以它们的名称 (A-E) 来表示。所有配置都遵循传统设计,仅在深度上有所不同:从网络 A 中的 11 个权重层,即 8 Conv。网络 E 中的 3 个 FC 层到 19 个权重层,即 16 个 Conv 和 3 个 FC 层。每个卷积层的宽度很小,通道数很小,从第一层的 64 开始,然后在每个最大池化层之后继续增加 2 倍,直到达到 512。每个配置的参数数量如下所述,虽然深度很大,但网络中的权值的数目并不大于较浅的网络中的权值的数目,而该网络具有较大的卷积层宽度和感受野。

在这里插入图片描述

训练

• 损失函数是多项逻辑回归
• 学习算法是基于动量反向传播的小批量随机梯度下降 (SGD)

·批量为 256

·动量为 0.9

• 正则化

· L2 权重衰减(惩罚乘数为 0.0005)

·前两个全连接层的 Dropout 设置为 0.5

• 学习率

·初始值:0.01

·当验证集准确性停止提高时,它会降低到 10。

• 尽管与 Alexnet 相比,它具有更多的参数和深度,但 CNN 需要更少的 epoch 来收敛损失函数,因为

·小卷积核和大深度的更多正则化。

·某些层的预初始化。

• 训练图像大小

· S 是同位素重新缩放图像的最小边

· 两种设置S的方法

▪Fix S,称为单尺度训练

▪这里 S = 256 和 S = 384

▪Vary S,称为多尺度训练

▪S 来自 [Smin, Smax] 其中 Smin = 256, Smax = 512

– 然后 224×224224×224
图像是从每次 SGD 迭代的重新缩放图像中随机裁剪的。

主要特征

• VGG16 共有 16 层,具有一些权重。

• 仅使用卷积层和池化层。

• 始终使用 3 x 3 内核进行卷积。20

• 2×2 大小的最大池。

• 1.38 亿个参数。

• 在ImageNet 数据上训练。

• 准确度为 92.7%。

• 另一个版本是 VGG 19,共有 19 层权重。

• 这是一个非常好的深度学习架构,可用于对任何特定任务进行基准测试。

• VGG 的预训练网络是开源的,因此可以开箱即用地用于各种类型的应用程序。

使用pytorch实现 VGG 网络

首先让我们为每个版本的 VGG 网络创建过滤器映射,请参阅上面的配置图像以了解过滤器的数量,即为版本创建一个字典,键名为 VGG11、VGG13、VGG16、VGG19,并根据每个版本的过滤器数量分别创建一个列表。这里列表中的“M”称为 Maxpool 操作。创建一个全局变量来提及架构的版本,然后创建一个名为 VGG_net 的类,其输入为 in_channels 和 num_classes,它接受图像输入通道数和输出类数。初始化Sequential层,然后创建一个名为 create_conv_layers 的函数,它将 VGGnet 架构配置作为输入,这是我们在上面为不同版本创建的列表。当它遇到上面列表中的字母“M”时,它会执行 MaxPool2d 操作。完整的实现代码如下:

import torch
import torch.nn as nn
VGG_types = {
"VGG11": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
"VGG13": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
"VGG16": [64,64,"M",128,128,"M",256,256,256,"M",512,512,512,"M",512,512,512,"M",],
"VGG19": [64,64,"M",128,128,"M",256,256,256,256,"M",512,512,512,512,
          "M",512,512,512,512,"M",],}


VGGType = "VGG16"
class VGGnet(nn.Module):
    def __init__(self, in_channels=3, num_classes=1000):
        super(VGGnet, self).__init__()
        self.in_channels = in_channels
        self.conv_layers = self.create_conv_layers(VGG_types[VGGType])
        self.fcs = nn.Sequential(
        nn.Linear(512 * 7 * 7, 4096),
        nn.ReLU(),
        nn.Dropout(p=0.5),
        nn.Linear(4096, 4096),
        nn.ReLU(),
        nn.Dropout(p=0.5),
        nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.conv_layers(x)
        x = x.reshape(x.shape[0], -1)
        x = self.fcs(x)
        return x

    def create_conv_layers(self, architecture):
        layers = []
        in_channels = self.in_channels

        for x in architecture:
            if type(x) == int:
                out_channels = x
                layers += [
                nn.Conv2d(
                in_channels=in_channels,
                out_channels=out_channels,
                kernel_size=(3, 3),
                stride=(1, 1),
                padding=(1, 1),
                ),
                nn.BatchNorm2d(x),
                nn.ReLU(),
                ]
                in_channels = x
            elif x == "M":
                layers += [nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2))]

        return nn.Sequential(*layers)


if __name__ == "__main__":
    device = "cuda" if torch.cuda.is_available() else "cpu"
    model = VGGnet(in_channels=3, num_classes=500).to(device)
    print(model)
    x = torch.randn(1, 3, 224, 224).to(device)
    print(model(x).shape)

在上面的测试代码中,给出的类数是 500,输出应为

在这里插入图片描述

  • 1
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: PyTorch可以使用预训练的VGG16模型来进行图片识别。以下是实现步骤: 1. 导入必要的库和模块: ``` import torch import torchvision import torchvision.transforms as transforms import torch.nn as nn ``` 2. 加载数据集并进行预处理: ``` transform = transforms.Compose( [transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[.485, .456, .406], std=[.229, .224, .225])]) trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2) testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2) ``` 3. 加载预训练的VGG16模型: ``` vgg16 = torchvision.models.vgg16(pretrained=True) ``` 4. 修改模型的最后一层,使其适应于CIFAR10数据集: ``` vgg16.classifier[6] = nn.Linear(4096, 10) ``` 5. 定义损失函数和优化器: ``` criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(vgg16.parameters(), lr=.001, momentum=.9) ``` 6. 训练模型: ``` for epoch in range(2): # 进行2个epoch的训练 running_loss = . for i, data in enumerate(trainloader, ): # 获取输入数据 inputs, labels = data # 梯度清零 optimizer.zero_grad() # 前向传播、反向传播、优化 outputs = vgg16(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() # 统计损失值 running_loss += loss.item() if i % 200 == 1999: # 每200个batch输出一次损失值 print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 200)) running_loss = . print('Finished Training') ``` 7. 测试模型: ``` correct = total = with torch.no_grad(): for data in testloader: images, labels = data outputs = vgg16(images) _, predicted = torch.max(outputs.data, 1) total += labels.size() correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % ( 100 * correct / total)) ``` 以上就是使用PyTorch实现VGG16图片识别的步骤。 ### 回答2: Pytorch是目前非常流行的深度学习框架之一,其自带的torchvision模块中已经集成了经典的VGG16模型,我们只需要根据自己的需求进行微调,就能实现基于VGG16的图片识别了。 1. 数据预处理 在使用VGG16模型进行图片识别前,首先需要进行数据预处理,包括图像尺寸调整、标准化等。我们可以使用transforms模块中自带的函数来完成数据预处理。 ``` from torchvision import transforms # 图像大小调整和标准化处理 transform = transforms.Compose( [transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])]) ``` 2. 加载模型使用VGG16模型之前,需要首先加载预训练的权重。在pytorch中,可以通过torchvision.models中的函数来加载预训练的VGG16模型。 ``` import torchvision.models as models # 加载VGG16模型 vgg16 = models.vgg16(pretrained=True) ``` 3. 修改全连接层 由于原始的VGG16模型是用于ImageNet数据集的1000个分类任务,而我们的任务可能只需要对少数类别进行分类,因此需要对全连接层进行微调。这里我们以10个类别的分类为例。 ``` # 修改全连接层 from torch import nn # 冻结前5层卷积层 for param in vgg16.parameters(): param.requires_grad = False # 修改分类器 vgg16.classifier = nn.Sequential( nn.Linear(25088, 4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(4096, 4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(4096, 10) ) ``` 4. 训练模型 经过数据预处理和模型微调后,我们就可以开始训练模型了。一般来说,我们需要定义损失函数和优化器,并在数据集上进行训练。 ``` # 定义损失函数 criterion = nn.CrossEntropyLoss() # 定义优化器 optimizer = optim.SGD(vgg16.classifier.parameters(), lr=0.001, momentum=0.9) # 训练模型 for epoch in range(num_epochs): running_loss = 0.0 for i, data in enumerate(trainloader, 0): # 输入数据 inputs, labels = data # 梯度清零 optimizer.zero_grad() # 前向传播 outputs = vgg16(inputs) # 计算损失 loss = criterion(outputs, labels) # 反向传播 loss.backward() # 更新梯度 optimizer.step() # 统计损失 running_loss += loss.item() # 打印日志 if i % 100 == 99: print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100)) running_loss = 0.0 ``` 5. 测试模型 在训练完成后,我们需要在测试集上测试模型的准确率。测试时,需要关闭参数的梯度计算,以免影响预测结果。 ``` # 测试模型 correct = 0 total = 0 with torch.no_grad(): for data in testloader: images, labels = data outputs = vgg16(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total)) ``` 以上就是使用pytorch实现VGG16图片识别的流程。当然,具体实现还需要结合自身的需求进行调整和优化,此处仅提供一个基本的参考。 ### 回答3: PyTorch是Facebook开源的深度学习框架,它提供了很多便捷的操作和工具,方便用户进行深度学习模型的设计和实现。其中包括了很多著名的深度学习模型实现,比如AlexNet、VGG等。接下来,我们就来介绍一下如何用PyTorch实现VGG16图片识别。 VGG是一种经典的卷积神经网络结构,它的主要特点是有很多的卷积层,并且每一层都是3×3的卷积核,所以它被称为VGGNet。在PyTorch中,我们可以使用“torchvision.models.vgg16”模块来加载和使用VGG16模型。以下是一个简单的示例代码: ``` import torch import torchvision import torchvision.transforms as transforms # 加载预训练的VGG16模型 vgg16 = torchvision.models.vgg16(pretrained=True) # 定义测试数据集 transform = transforms.Compose( [transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize( mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])]) testset = torchvision.datasets.ImageFolder(root='path/to/testset', transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2) # 定义所有的类别 classes = ('class1', 'class2', ...) # 开始测试 vgg16.eval() # 将模型调整为评估模式 with torch.no_grad(): # 不计算梯度,以节约内存 for data in testloader: images, labels = data outputs = vgg16(images) _, predicted = torch.max(outputs, 1) # 输出预测结果 for i in range(4): print('Predicted: ', classes[predicted[i]]) ``` 在这个代码中,我们首先加载了PyTorch中已预训练的VGG16模型。然后,我们定义了测试数据集,将测试集中的每张图片都缩放到256×256的大小,然后中心裁剪到224×224大小,最后将其转换为张量。我们还将每个通道的像素数值标准化到均值和标准差为0.5的范围内。 在测试时,我们将模型调整为评估模式,并关闭梯度计算以节约内存。对于每一批测试数据,我们将它们传递给模型进行预测,并输出每张图片预测的类别。 通过这个简单的代码示例,我们可以很容易地实现VGG16模型的图片识别。当然,在实际的应用中,我们还需要对模型进行调优,以获得更好的识别效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vcsir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值