pytorch实现经典神经网络:VGG16模型之初探

文章链接
https://blog.csdn.net/weixin_44791964/article/details/102585038?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169675238616800211588158%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=169675238616800211588158&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-2-102585038-null-null.nonecase&utm_term=VGG&spm=1018.2226.3001.4450

VGG16原理链接
https://zhuanlan.zhihu.com/p/460777014

代码参考:
https://blog.csdn.net/m0_50127633/article/details/117045008?ops_request_misc=&request_id=&biz_id=102&utm_term=pytorch%20vgg16&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-117045008.142v95insert_down28v1&spm=1018.2226.3001.4187

https://blog.csdn.net/weixin_46676835/article/details/128730174?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169681442316800215096882%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=169681442316800215096882&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-5-128730174-null-null.142v95insert_down28v1&utm_term=pytorch%20vgg16&spm=1018.2226.3001.4187
在这里插入图片描述
在这里插入图片描述

分解一下:
卷积提取特征,池化压缩。
1、一张原始图片被resize到(224,224,3)。
2、conv1两次[3,3]卷积网络,输出的特征层为64,输出为(224,224,64),再2X2最大池化,输出net为(112,112,64)。

注意 池化不会改变通道数

在这里插入图片描述
根据公式第一步取stride=1,padding=1
在这里插入图片描述
stride=2 padding=0(不用写)

 nn.Conv2d(3,64,3,1,1),nn.Conv2d(64,64,3,1,1)nn.Conv2d(3,64,3,1,1),nn.Conv2d(64,64,3,1,1),nn.MaxPool2d(2,2)

3、conv2两次[3,3]卷积网络,第一次输入的特征层为64,输出net为(112,112,128),再2X2最大池化,输出net为(56,56,128)。

  nn.Conv2d(64,128,3,1,1),nn.Conv2d(128, 128, 3, 1, 1),nn.MaxPool2d(2,2)

4、conv3三次[3,3]卷积网络,输入的特征层为256,输出net为(56,56,256),再2X2最大池化,输出net为(28,28,256)。

 nn.Conv2d(128,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.MaxPool2d(2,2)

5、conv3三次[3,3]卷积网络,输入的特征层为256,输出net为(28,28,512),再2X2最大池化,输出net为(14,14,512)。

nn.Conv2d(256,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),

6、conv3三次[3,3]卷积网络,输出的特征层为256,输出net为(14,14,512),再2X2最大池化,输出net为(7,7,512)。

 nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2)

7、利用卷积的方式模拟全连接层,效果等同,输出net为(1,1,4096)。共进行两次。

 nn.Linear(25088,4096), #7×7×512nn.Linear(4096,4096),nn.Linear(4096,1000)

8、利用卷积的方式模拟全连接层,效果等同,输出net为(1,1,1000)。
最后输出的就是每个类的预测。

  nn.Linear(4096,1000)

初步代码框架如下:

import torch
from torch import nnclass VGG(nn.Module):def __init__(self):super(VGG, self).__init__()self.MyVgg=nn.Sequential(nn.Conv2d(3,64,3,1,1),nn.Conv2d(64,64,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(64,128,3,1,1),nn.Conv2d(128, 128, 3, 1, 1),nn.MaxPool2d(2,2),nn.Conv2d(128,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(256,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),nn.Linear(25088,4096), #7×7×512nn.Linear(4096,4096),nn.Linear(4096,1000))

补充与完善

1、记得进行数据拉平:
在这里插入图片描述
模型部分

class VGG(nn.Module):def __init__(self):super(VGG, self).__init__()self.MyVgg=nn.Sequential(nn.Conv2d(3,64,3,1,1),nn.Conv2d(64,64,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(64,128,3,1,1),nn.Conv2d(128, 128, 3, 1, 1),nn.MaxPool2d(2,2),nn.Conv2d(128,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(256,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),nn.Flatten(),nn.Linear(25088,4096), #7×7×512nn.Linear(4096,4096),nn.Linear(4096,1000))def forward(self,x):x=self.MyVgg(x)return x

2、导入数据
使用cifar10数据集

import torch
from torch import nn
import torchvision
from torch.utils.data import DataLoaderdatasets_train=torchvision.datasets.CIFAR10("./data",train=True,download=True,transform=torchvision.transforms.ToTensor())
datasets_test=torchvision.datasets.CIFAR10("./data",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader_train=DataLoader(datasets_train,batch_size=64)
dataloader_test=DataLoader(datasets_test,batch_size=64)

3、创建损失函数
使用交叉熵CrossEntropyLoss

from torch import nn
los_fun=nn.CrossEntropyLoss()

4、创建优化器:

learning_rate=0.001
optimizer=torch.optim.SGD(fenlei.parameters(),lr=learning_rate)

5、编写训练代码:

total_train_step=0
tatal_test_step=0
epoch=10for i in range(epoch):print("--------第{}轮训练开始-----".format(i+1))for data in dataloader_train:imgs,targets=dataoutputs=fenlei(imgs)loss=los_fun(outputs,targets)optimizer.zero_grad()loss.backward()total_train_step=total_train_step+1print("训练次数:{},Loss:{}".format(total_train_step, loss))

训练时报错:
在这里插入图片描述
原因我们假设输入的是224×224×3了
然而cfar10的数据集是32×32×3

所以我们需要加入resize操作:

from torchvision import transforms
datasets_train=torchvision.datasets.CIFAR10("./data",train=True,download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Resize([224,224])])       )

6、使用GPU训练:

#定义训练设备
device=torch.device('cuda'if torch.cuda.is_available()else 'cpu')
fenlei.to(device)
los_fun=los_fun.to(device)

我的

import torch
from torch import nn
import torchvision
from torch.utils.data import DataLoader
from torchvision import transforms
datasets_train=torchvision.datasets.CIFAR10("./data",train=True,download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Resize([224,224])])       )
datasets_test=torchvision.datasets.CIFAR10("./data",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader_train=DataLoader(datasets_train,batch_size=24,drop_last=True)
dataloader_test=DataLoader(datasets_test,batch_size=64,drop_last=True)img,target=datasets_train[0]
print(img.shape)class VGG(nn.Module):def __init__(self):super(VGG, self).__init__()self.MyVgg=nn.Sequential(nn.Conv2d(3,64,3,1,1),nn.Conv2d(64,64,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(64,128,3,1,1),nn.Conv2d(128, 128, 3, 1, 1),nn.MaxPool2d(2,2),nn.Conv2d(128,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.Conv2d(256,256,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(256,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.Conv2d(512,512,3,1,1),nn.MaxPool2d(2,2),nn.Flatten(),nn.Linear(25088,4096), #7×7×512nn.Linear(4096,4096),nn.Linear(4096,1000))def forward(self,x):x=self.MyVgg(x)return xfenlei=VGG()from torch import nn
los_fun=nn.CrossEntropyLoss()learning_rate=0.001
optimizer=torch.optim.SGD(fenlei.parameters(),lr=learning_rate)total_train_step=0
tatal_test_step=0
epoch=10#定义训练设备
device=torch.device('cuda'if torch.cuda.is_available()else 'cpu')
fenlei.to(device)
los_fun=los_fun.to(device)for i in range(epoch):print("--------第{}轮训练开始-----".format(i+1))for data in dataloader_train:imgs,targets=dataimgs=imgs.to(device)targets=targets.to(device)outputs = fenlei(imgs)loss=los_fun(outputs,targets)optimizer.zero_grad()loss.backward()total_train_step=total_train_step+1if total_train_step%10==0:print("训练次数:{},Loss:{}".format(total_train_step, loss))

为啥人家的代码训练这么快?

在这里插入图片描述

在PyTorch中,nn.Dropout和nn.ReLU是常用的神经网络模块,分别用于正则化和激活函数。
nn.Dropout是一种正则化技术,旨在减少神经网络的过拟合问题。过拟合是指模型在训练集上表现很好,但在测试集上表现较差的现象。Dropout通过在训练过程中随机将一定比例的神经元置为0,以强制网络学习到冗余特征,从而提高模型的泛化能力。这可以防止过拟合,并提高网络的鲁棒性。
nn.ReLU是一种常用的激活函数,它被广泛应用在神经网络中。ReLU的全称是Rectified Linear Unit,它的定义很简单:对于输入x,当x小于0时,输出为0;当x大于等于0时,输出为x。ReLU函数的优点是计算简单、非线性、减轻梯度消失等。
在神经网络中,ReLU函数能够引入非线性,增加模型的拟合能力,并且减少梯度消失问题。当输入为负时,ReLU将输出为0,这有助于稀疏表示,从而使得网络更加有效地学习特征。
综上所述,nn.Dropout用于减少过拟合,提高泛化能力,而nn.ReLU用于引入非线性和解决梯度消失问题。它们在神经网络中的应用非常常见,并且经过广泛验证的有效技术。

明天看录播有助于理解他的代码:

import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plttransform_train = transforms.Compose([transforms.Pad(4),transforms.ToTensor(),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),transforms.RandomHorizontalFlip(),transforms.RandomGrayscale(),transforms.RandomCrop(32, padding=4),])transform_test = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))]
)device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainLoader = torch.utils.data.DataLoader(trainset, batch_size=24, shuffle=True)testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testLoader = torch.utils.data.DataLoader(testset, batch_size=24, shuffle=False)vgg = [96, 96, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M']class VGG(nn.Module):def __init__(self, vgg):super(VGG, self).__init__()self.features = self._make_layers(vgg)self.dense = nn.Sequential(nn.Linear(512, 4096),nn.ReLU(inplace=True),nn.Dropout(0.4),nn.Linear(4096, 4096),nn.ReLU(inplace=True),nn.Dropout(0.4),)self.classifier = nn.Linear(4096, 10)def forward(self, x):out = self.features(x)out = out.view(out.size(0), -1)out = self.dense(out)out = self.classifier(out)return outdef _make_layers(self, vgg):layers = []in_channels = 3for x in vgg:if x == 'M':layers += [nn.MaxPool2d(kernel_size=2, stride=2)]else:layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),nn.BatchNorm2d(x),nn.ReLU(inplace=True)]in_channels = xlayers += [nn.AvgPool2d(kernel_size=1, stride=1)]return nn.Sequential(*layers)model = VGG(vgg)
# model.load_state_dict(torch.load('CIFAR-model/VGG16.pth'))
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=5e-3)
loss_func = nn.CrossEntropyLoss()
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.4, last_epoch=-1)total_times = 40
total = 0
accuracy_rate = []def test():model.eval()correct = 0  # 预测正确的图片数total = 0  # 总共的图片数with torch.no_grad():for data in testLoader:images, labels = dataimages = images.to(device)outputs = model(images).to(device)outputs = outputs.cpu()outputarr = outputs.numpy()_, predicted = torch.max(outputs, 1)total += labels.size(0)correct += (predicted == labels).sum()accuracy = 100 * correct / totalaccuracy_rate.append(accuracy)print(f'准确率为:{accuracy}%'.format(accuracy))for epoch in range(total_times):model.train()model.to(device)running_loss = 0.0total_correct = 0total_trainset = 0for i, (data, labels) in enumerate(trainLoader, 0):data = data.to(device)outputs = model(data).to(device)labels = labels.to(device)loss = loss_func(outputs, labels).to(device)optimizer.zero_grad()loss.backward()optimizer.step()running_loss += loss.item()_, pred = outputs.max(1)correct = (pred == labels).sum().item()total_correct += correcttotal_trainset += data.shape[0]if i % 1000 == 0 and i > 0:print(f"正在进行第{i}次训练, running_loss={running_loss}".format(i, running_loss))running_loss = 0.0test()scheduler.step()# torch.save(model.state_dict(), 'CIFAR-model/VGG16.pth')
accuracy_rate = np.array(accuracy_rate)
times = np.linspace(1, total_times, total_times)
plt.xlabel('times')
plt.ylabel('accuracy rate')
plt.plot(times, accuracy_rate)
plt.show()print(accuracy_rate)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/99605.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Overload游戏引擎分析】从视图投影矩阵提取视锥体及overload对视锥体的封装

overoad代码中包含一段有意思的代码,可以从视图投影矩阵逆推出摄像机的视锥体,本文来分析一下原理 一、平面的方程 视锥体是用平面来表示的,所以先看看平面的数学表达。 平面方程可以由其法线N(A, B, C)和一个点Q(x0,…

Python ASCII码与字符相互转换

cinput("请输入一个字符:") aint(input("请输入一个ascii码:")) print(c"的ascii的码为:",ord(c)) print(a,"对应的字符为:",chr(a))

Django实战项目-学习任务系统-用户登录

第一步:先创建一个Django应用程序框架代码 1,先创建一个Django项目 django-admin startproject mysite将创建一个目录,其布局如下:mysite/manage.pymysite/__init__.pysettings.pyurls.pyasgi.pywsgi.py 2,再创建一个…

git清除所有历史commit

如果在git中不小心提交了敏感信息(如API密钥)到Git,并希望删除所有提交并重新开始,可以采取以下步骤: 新建初始分支 git checkout --orphan new_branch添加文件 git add -A git commit -m "Initial commit" -s # -s …

开发餐饮类私域流量是开发应用APP还是小程序还是低代码跨平台APP分析他的利与弊

在开发餐饮类应用程序时,我们需要先了解市场需求,定义目标受众,并提供独特的功能。个人感觉我们提供周围的在线订购、外卖服务、用户评价等功能,以吸引用户。同时,设计用户习惯的界面,使用户轻松选择自己的…

javaScript:拖拽效果

目录 前言 实现思路 获取事件对象和坐标点: 配合定位: 鼠标事件监听: 拖拽过程: 停止拖拽: 代码实现(代码讲解) 前言 JavaScript的拖拽效果是一种常见的交互技术,它允许用户…

Java使用Hutool工具包将汉字转换成汉语拼音

主题:使用Java将汉字转换成拼音 介绍 在Java开发中,有时候我们需要将汉字转换成拼音,以方便进行数据处理、搜索和排序等操作。本文将介绍如何使用Hutool和Pinyin4j这两个Java库来实现汉字转拼音的功能。 依赖库介绍 在开始之前,…

mc我的世界云服务器租用价格表

开Minecraft我的世界服务器配置怎么选择?10人以内玩2核4G就够用了,开我的世界服务器选择轻量应用服务器就够了,轻量CPU采用至强白金处理器,大型整合包一般1.12版本的,轻量2核4G配置都差不多的,如果是1.16的…

在线免费无时长限制录屏工具 - 录猎在线版

需要录屏的小伙伴注意啦,想要长时间录制又不想花钱的,可以看下这款在线版录屏软件 —— 录猎在线版,一个录屏软件所需要的基本功能它都有,设置录制范围、录制的声音来源、摄像头也能录制的。同时它是支持Windows和Mac系统的&#…

PyCharm搭建Scrapy环境

Scrapy入门 1、Scrapy概述2、PyCharm搭建Scrapy环境3、Scrapy使用四部曲4、Scrapy入门案例4.1、明确目标4.2、制作爬虫4.3、存储数据4.4、运行爬虫 1、Scrapy概述 Scrapy是一个由Python语言开发的适用爬取网站数据、提取结构性数据的Web应用程序框架。主要用于数据挖掘、信息处…

【计算机网络】-基础知识

1.计算机网络(计算机技术通信技术)的结合 ICTITCT 2.计算机分类1:通信子网(通信节点、通信链路),资源子网(PC、服务器,类似终端节点) 分类2:网络的结构,例如…

Mac电脑交互式原型设计 Axure RP 8汉化最新 for mac

Axure RP 8是一款专业且快速的原型设计工具,主要用于定义需求、规格、设计功能和界面。这款工具主要适用于用户体验设计师、交互设计师、业务分析师、信息架构师、可用性专家和产品经理等职业。 Axure RP 8的主要特性包括能够快速设计出应用软件或Web网站的线框图、…

RustDay01——运行在线GitHub Rust环境

1.跟着教程进入GitHub教室 2. 授权确认后进入学习空间 3.点击链接进入在线平台 4.添加本机密钥对到GitHub 5. 安装依赖 我们使用在线的Linux试验平台,就自动帮我们clone好了仓库 我们直接在仓库目录执行 cargo install --force --path . 安装依赖 PS:其实刚开始…

uni-app:实现简易自定义下拉列表

效果 代码 <template><view><view class"dropdown-trigger" tap"showDropdown">{{ selectedItem }}</view><view class"dropdown-list" v-if"showList"><view class"dropdown-item" v-f…

关于开展2023年度光明科学城出站博士后生活资助申报工作的通知

各相关单位&#xff1a; 根据《光明区关于实施光明科学城“人才高地计划”的若干措施》&#xff08;深光发〔2022〕1号&#xff09;和《光明科学城青年科技人才培育专项行动方案》&#xff08;深光人才〔2022〕2号&#xff09;有关规定&#xff0c;现就2023年度光明科学城出站博…

电容笔值不值得买?ipad上好用的电容笔推荐

由于大多数学生都没有稳定的工作&#xff0c;在购买产品的时候&#xff0c;往往会选择一些比较经济实惠的产品。随着ipad的版本更新&#xff0c;以及出现更多的功能&#xff0c;它将逐渐进入我们的生活与工作。由于电子产品的不断升级&#xff0c;不断改进&#xff0c;对电容笔…

Spring WebClient 基于响应式编程模型的HTTP客户端

一、简介 WebClient是一个非阻塞的、可扩展的、基于Reactive Streams规范的HTTP客户端。它提供了一种简洁的方式来进行HTTP请求&#xff0c;并且可以很好地与其他Spring组件集成。WebClient支持同步和异步操作&#xff0c;使得它非常适合用于构建响应式应用程序。 WebClient允…

Unity ToLua热更框架使用教程(1)

从本篇开始将为大家讲解ToLua在unity当中的使用教程。 Tolua的框架叫LuaFramework&#xff0c;首先附上下载链接&#xff1a; https://github.com/jarjin/LuaFramework_UGUI_V2 这个地址的是UGUI的。 下载完之后导入项目&#xff0c;首先&#xff0c;我们要先让这个项目跑起…

JavaScript中的浅拷贝和深拷贝

浅拷贝 创建一个新对象&#xff0c;这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型&#xff0c;拷贝的就是基本类型的值&#xff0c;如果属性是引用类型&#xff0c;拷贝的就是内存地址 &#xff0c;所以如果其中一个对象改变了这个地址&#xff0c;就会影响到…

Git常用命令及解释

Git是一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变化。以下是Git的常用命令及其详细解释&#xff1a; git init&#xff1a;初始化一个新的Git仓库。在项目的根目录运行该命令会在当前目录下创建一个新的Git仓库&#xff0c;并初始化版本控制。 git clone <r…