网站优化和网站推广,修改网站主目录的位置,seo sem 外贸建站 网站建设 文化墙设计,物流网站的建设论文经典卷积神经网络-VGGNet
一、背景介绍
VGG是Oxford的Visual Geometry Group的组提出的。该网络是在ILSVRC 2014上的相关工作#xff0c;主要工作是证明了增加网络的深度能够在一定程度上影响网络最终的性能。VGG有两种结构#xff0c;分别是VGG16和VGG19#xff0c;两者并…经典卷积神经网络-VGGNet
一、背景介绍
VGG是Oxford的Visual Geometry Group的组提出的。该网络是在ILSVRC 2014上的相关工作主要工作是证明了增加网络的深度能够在一定程度上影响网络最终的性能。VGG有两种结构分别是VGG16和VGG19两者并没有本质上的区别只是网络深度不一样。 二、VGG-16网络结构 其中VGG系列具体的网络结构如下表所示 如图所示这是论文中所有VGG网络的详细信息D列对应的为VGG-16网络。16指的是在这个网络中包含16个卷积层和全连接层不算池化层和Softmax。 VGG-16的卷积层没有那么多的超参数在整个网络模型中所有卷积核的大小都是 3 × 3的并且padding为samestride为1。所有池化层的池化核大小都是 2 × 2 的并且步长为2。在几次卷积之后紧跟着池化整个网络结构很规整。 总共包含约1.38亿个参数但其结构并不复杂结构很规整都是几个卷积层后面跟着可以压缩图像大小的池化层同时卷积层的卷积核数量的变化也存在一定的规律都是池化之后图像高度宽度减半但在下一个卷积层中通道数翻倍这正是这种简单网络结构的一个规则。 VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核11x117x75x5。对于给定的感受野与输出有关的输入图片的局部大小采用堆积的小卷积核是优于采用大的卷积核因为多层非线性层可以增加网络深度来保证学习更复杂的模式而且代价还比较小参数更少。在VGG中使用了3个3x3卷积核来代替7x7卷积核使用了2个3x3卷积核来代替5×5卷积核这样做的主要目的是在保证具有相同感受野的条件下提升了网络的深度在一定程度上提升了神经网络的效果。 它的主要缺点就是需要训练的特征数量非常大。有些文章介绍了VGG-19但通过研究发现VGG-19和VGG-16的性能表现几乎不分高下所以很多人还是使用VGG-16这也说明了单纯的增加网络深度其性能不会有太大的提升。 论文中还介绍了权重初始化方法即预训练低层模型参数为深层模型参数初始化赋值。原文网络权重初始化是非常重要的坏的初始化会使得深度网络的梯度的不稳定导致无法学习。为了解决这个问题我们首先在网络A中使用随机初始化进行训练。然后到训练更深的结构时我们将第一层卷积层和最后三层全连接层的参数用网络A中的参数初始化中间层的参数随机初始化。 论文中揭示了随着网络深度的增加图像的高度和宽度都以一定规律不断缩小每次池化之后刚好缩小一半而通道数量在不断增加而且刚好也是在每组卷积操作后增加一倍。也就是说图像缩小和通道增加的比例是有规律的从这个角度看这篇论文很吸引人。
三、VGG-16的Pytorch实现
我们可以根据https://dgschwend.github.io/netscope/#/preset/vgg-16来搭建VGG-16。 后面要将VGG-16Net应用到CIFAR10数据集上所以对网络做了一些修改具体代码如下
from torch import nnclass Vgg16_Net(nn.Module):def __init__(self):super(Vgg16_Net, self).__init__()self.layer1 nn.Sequential(# input_size (3, 32, 32)nn.Conv2d(in_channels3, out_channels64, kernel_size3, stride1, padding1),nn.BatchNorm2d(64),nn.ReLU(inplaceTrue),# input_size (64, 32, 32)nn.Conv2d(in_channels64, out_channels64, kernel_size3, stride1, padding1),nn.BatchNorm2d(64),nn.ReLU(inplaceTrue),# input_size (64, 32, 32)nn.MaxPool2d(kernel_size2, stride2))self.layer2 nn.Sequential(# input_size (64, 16, 16)nn.Conv2d(in_channels64, out_channels128, kernel_size3, stride1, padding1),nn.BatchNorm2d(128),nn.ReLU(inplaceTrue),# input_size (128, 16, 16)nn.Conv2d(in_channels128, out_channels128, kernel_size3, stride1, padding1),nn.BatchNorm2d(128),nn.ReLU(inplaceTrue),# input_size (128, 16, 16)nn.MaxPool2d(2, 2))self.layer3 nn.Sequential(# input_size (128, 8, 8)nn.Conv2d(in_channels128, out_channels256, kernel_size3, stride1, padding1),nn.BatchNorm2d(256),nn.ReLU(inplaceTrue),# input_size (256, 8, 8)nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.BatchNorm2d(256),nn.ReLU(inplaceTrue),# input_size (256, 8, 8)nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.BatchNorm2d(256),nn.ReLU(inplaceTrue),# input_size (256, 8, 8)nn.MaxPool2d(2, 2))self.layer4 nn.Sequential(# input_size (256, 4, 4)nn.Conv2d(in_channels256, out_channels512, kernel_size3, stride1, padding1),nn.BatchNorm2d(512),nn.ReLU(inplaceTrue),# input_size (512, 4, 4)nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.BatchNorm2d(512),nn.ReLU(inplaceTrue),# input_size (512, 4, 4)nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.BatchNorm2d(512),nn.ReLU(inplaceTrue),# input_size (512, 4, 4)nn.MaxPool2d(2, 2))self.layer5 nn.Sequential(# input_size (512, 2, 2)nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.BatchNorm2d(512),nn.ReLU(inplaceTrue),# input_size (512, 2, 2)nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.BatchNorm2d(512),nn.ReLU(inplaceTrue),# input_size (512, 2, 2)nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.BatchNorm2d(512),nn.ReLU(inplaceTrue),# input_size (512, 2, 2)nn.MaxPool2d(2, 2)# output_size (512, 1, 1))self.conv nn.Sequential(self.layer1,self.layer2,self.layer3,self.layer4,self.layer5)self.fc nn.Sequential(# input_size 512nn.Linear(512, 512),nn.ReLU(inplaceTrue),nn.Dropout(0.5),nn.Linear(512, 256),nn.ReLU(inplaceTrue),nn.Dropout(0.5),nn.Linear(256, 10))def forward(self, x):x self.conv(x)# -1表示自动计算行数# -1也可以改成x.size(0) 表示batch_size的大小x x.view(-1, 512 * 1 * 1)x self.fc(x)return x四、案例CIFAR-10分类问题
import time
import torch
import torchvision
from model import *
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
from matplotlib import pyplot as plt# 加载数据集 拿到dataloader
def load_dataset(batch_size):train_data torchvision.datasets.CIFAR10(../dataset/CIFAR10, trainTrue, downloadTrue, transformtransforms.ToTensor())test_data torchvision.datasets.CIFAR10(../dataset/CIFAR10, trainFalse, downloadTrue, transformtransforms.ToTensor())train_dataloader DataLoader(train_data, batch_sizebatch_size, shuffleTrue, num_workers2)test_dataloader DataLoader(test_data, batch_sizebatch_size, shuffleFalse, num_workers2)return train_dataloader, test_dataloader# 模型训练
def train(model, train_dataloader, criterion, optimizer, epochs, device, num_print, lr_schedulerNone, test_dataloaderNone):# 记录train和test的acc方便绘制学习曲线record_train list()record_test list()# 开始训练model.train()for epoch in range(epochs):print( epoch: [{}/{}] .format(epoch 1, epochs))# total记录样本数 correct记录正确预测样本数total, correct, train_loss 0, 0, 0start time.time()# 结合enumerate函数和迭代器的unpacking 可以在获取数据的同时获取该批次数据对应的索引for i, (image, target) in enumerate(train_dataloader):image, target image.to(device), target.to(device)output model(image)loss criterion(output, target)optimizer.zero_grad()loss.backward()optimizer.step()train_loss loss.item()total target.size(0)correct (output.argmax(dim1) target).sum().item()train_acc 100.0 * correct / totalif (i 1) % num_print 0:print(step: [{}/{}], train_loss: {:.3f} | train_acc: {:6.3f}% | lr: {:.6f}.format(i 1,len(train_dataloader), train_loss / (i 1), train_acc, get_cur_lr(optimizer)))# 更新当前优化器的学习率if lr_scheduler is not None:lr_scheduler.step()print(--- cost time: {:.4f}s ---.format(time.time() - start))if test_dataloader is not None:record_test.append(test(model, test_dataloader, criterion, device))record_train.append(train_acc)# 保存当前模型torch.save(model.state_dict(), train_model/VGG-16Net_{}.pth.format(epoch 1))return record_train, record_test# 模型测试
def test(model, test_dataloader, criterion, device):# total记录样本数 correct记录正确预测样本数total, correct 0, 0# 开始测试model.eval()with torch.no_grad():print(*************** test ***************)for X, y in test_dataloader:X, y X.to(device), y.to(device)output model(X)loss criterion(output, y)total y.size(0)correct (output.argmax(dim1) y).sum().item()test_acc 100.0 * correct / totalprint(test_loss: {:.3f} | test_acc: {:6.3f}%.format(loss.item(), test_acc))print(************************************\n)# 记得重新调用model.train()model.train()return test_acc# 获取当前的学习率 这里直接返回了第一个参数分组的学习率
def get_cur_lr(optimizer):for param_group in optimizer.param_groups:return param_group[lr]# 绘制学习曲线
def learning_curve(record_train, record_testNone):# 设置 Matplotlib 图形样式# ggplot2 是一个用于数据可视化的流行 R 语言包以其优雅和灵活的语法而闻名plt.style.use(ggplot)plt.plot(range(1, len(record_train) 1), record_train, labeltrain acc)if record_test is not None:plt.plot(range(1, len(record_test) 1), record_test, labeltest acc)plt.legend(loc4)plt.title(learning curve)plt.xticks(range(0, len(record_train) 1, 5))plt.yticks(range(0, 101, 5))plt.xlabel(epoch)plt.ylabel(accuracy)plt.show()# 定义超参数
BATCH_SIZE 128
NUM_EPOCHS 20
NUM_CLASSES 10
LEARNING_RATE 0.02
MOMENTUM 0.9
WEIGHT_DECAY 0.0005
NUM_PRINT 100
DEVICE cuda if torch.cuda.is_available() else cpudef main():model Vgg16_Net()model model.to(DEVICE)# 加载数据train_dataloader, test_dataloader load_dataset(BATCH_SIZE)# 定义损失函数criterion nn.CrossEntropyLoss()# 定义优化器optimizer torch.optim.SGD(model.parameters(),lrLEARNING_RATE,momentumMOMENTUM,weight_decayWEIGHT_DECAY,nesterovTrue)# 定义学习率调度器lr_scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_size7, gamma0.1)# 进行训练 返回训练集正确率和测试集正确率record_train, record_test train(model, train_dataloader, criterion, optimizer, NUM_EPOCHS, DEVICE, NUM_PRINT, lr_scheduler, test_dataloader)# 绘制学习曲线learning_curve(record_train, record_test)if __name__ __main__:main()查看训练结果可以发现测试集正确率基本保持在87.3%左右训练集正确率接近100% 学习曲线如下 参考链接 https://cloud.tencent.com/developer/article/1638597 https://blog.csdn.net/m0_50127633/article/details/117047057?spm1001.2014.3001.5502