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

news2024/9/22 1:09:00

文章链接
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×512
            nn.Linear(4096,4096),
            nn.Linear(4096,1000)

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

  nn.Linear(4096,1000)

初步代码框架如下:

import torch
from torch import nn

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.Linear(25088,4096), #7×7×512
            nn.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×512
            nn.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 DataLoader

datasets_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=10


for i in range(epoch):
    print("--------第{}轮训练开始-----".format(i+1))

    for data in dataloader_train:
        imgs,targets=data
        outputs=fenlei(imgs)
        loss=los_fun(outputs,targets)

        optimizer.zero_grad()
        loss.backward()

        total_train_step=total_train_step+1
        print("训练次数:{},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×512
            nn.Linear(4096,4096),
            nn.Linear(4096,1000)

            )
    def forward(self,x):
        x=self.MyVgg(x)
        return x

fenlei=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=data
        imgs=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+1
        if 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 plt

transform_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 out

    def _make_layers(self, vgg):
        layers = []
        in_channels = 3
        for 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 = x

        layers += [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 = data
            images = 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 / total
    accuracy_rate.append(accuracy)
    print(f'准确率为:{accuracy}%'.format(accuracy))


for epoch in range(total_times):
    model.train()
    model.to(device)
    running_loss = 0.0
    total_correct = 0
    total_trainset = 0

    for 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 += correct
        total_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.0
    test()
    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.coloradmin.cn/o/1075844.html

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

相关文章

谷歌 Chrome 浏览器正推进“追踪保护”功能

导读近日消息,根据国外科技媒体 Windows Latest 报道,谷歌计划在 Chrome 浏览器中推进“追踪保护”(Tracking Protection)功能,整合浏览器现有隐私功能,保护用户被网站跟踪。 根据一项 Chromium 提案&…

Java List 中存不同的数据类型

在最近的实践中&#xff0c;有人突然问了一个问题&#xff1a; 在 Java 的 List 中可以存不同的数据类型吗&#xff1f; 这个问题突然给问到了&#xff0c;我们都知道 Java 中的 List 中存的是对象&#xff0c;通常我们定义都会这样的定义&#xff1a; List<String> t…

ycb数据集筛选

tain数据集&#xff1a; 03. 04. 05. 06. 07. 08. 09. 10. 11. 13 14 15peach桃子&#xff1a; 16 17orange橘子&#xff1a; 18plum李子&#xff1a; 21 24 26sponge&#xff1a; 29 33 35 37 40large marker 43.phillips screwdriver 48 52 55 56…

零基础教程:使用YOLOV7训练VisDrone数据集

1.源码地址&#xff1a; https://github.com/WongKinYiu/yolov7 下载之后解压 2.环境准备 1.用pycharm打开项目文件&#xff0c;选择自己的虚拟环境 2.下载项目所需要的包和权重文件 打开Terminal 输入以下命令&#xff1a; pip install -r requirements.txt 下载预训练权…

用Python开发QQ机器人详解

前言 虽然该文最终是达到以python开发mirai机器人的目的&#xff0c;但起步教程&#xff0c;尤其是环境配置上仍然有大量的相同操作&#xff0c;对其他编程语言仍有借鉴之处 假设你已经安装好了 Java、Python等运行必须的环境 mirai生态 mirai官方生态文档 要使用mirai开发Q…

第四届厦门国际银行数创金融杯建模大赛火热进行中!丰厚奖励等你来拿!

第四届厦门国际银行数创金融杯建模大赛火热进行中&#xff01;厦门国际银行联合厦门大学数据挖掘中心诚邀您一起用科技的力量&#xff0c;探索数据的奥秘。 本届大赛以实际金融业务场景中的文本识别作为主题&#xff0c;设置了高达38万元的丰厚奖金以及竞赛获奖证书&#xff0c…

pdf怎么转成jpg图片格式

pdf怎么转成jpg图片格式&#xff1f;对于大家平时在工作或者生活中的图片使用习惯&#xff0c;经常需要将各种格式的文件转换成易于浏览和使用的JPG格式图片以便保存。如今&#xff0c;因为pdf文件具有更强的稳定性和设备兼容性&#xff0c;PDF文件在平时的电脑使用过程中可以说…

AQS面试题

更多面试资料请添加wx&#xff1a;suns45 ———Java的AQS——— 1、AQS的理解 AQS是一个锁框架&#xff0c;提供了扩展地方 当多个线程抢锁时&#xff0c;获取不到锁的线程&#xff0c;AQS会自动管理 AQS是同步队列条件队列 AQS分为4个时机&#xff0c;获取锁&#xff0c…

国产化技术探究达梦8数据库搭建一主一从双机热备守护Data Watch集群搭建实战

国产化技术探究达梦8数据库搭建一主一从双机热备守护集群搭建实战 一、环境说明 服务器类型IP地址操作系统数据库实例名称主机172.18.21.144centos7DMSERVER备机172.18.21.147centos7DMSERVER2 参数主库备库实例名称DMSERVERDMSERVER 2IP172.18.21.144172.18.21.147OGUID453…

有趣的数学 积分符号∫ (integration)简述

1、简述 积分是微积分的一个主要部分。它是求和概念的延伸。事实上&#xff0c;积分符号源自一个拉长的字母S&#xff0c;最初由莱布尼茨使用&#xff08;也有人说是牛顿&#xff09;&#xff0c;代表Summa&#xff0c;在拉丁语中意为“和”&#xff0c;对切片进行求和的想法。…

计算机的体系与结构

文章目录 前言一、冯诺依曼体系二、现代计算机的结构总结 前言 今天给大家介绍计算机的体系和结构&#xff0c;分为两个板块&#xff1a;冯诺依曼体系和现代计算机的结构。 一、冯诺依曼体系 冯诺依曼体系是将程序指令和数据一起存储的计算机设计概念结构。 冯诺依曼体系可以…

基于LSTM-Adaboost的电力负荷预测的MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 主要内容&#xff1a; LSTM-AdaBoost负荷预测模型先通过 AdaBoost集成算法串行训练多个基学习器并计算每个基学习 器的权重系数,接着将各个基学习器的预测结果进行线性组合,生成最终的预测结果。代码中的LST…

MySQL之MHA集群

MHA概述 什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点故障的问题。 MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换…

hbba网站下载国家标准/行业标准的方法

hbba网站是不提供下载按钮并且不支持右键的&#xff0c;那么如何下载呢&#xff1f; 1、首先看一下pdf有多少页&#xff0c;一般标准介绍上有写。 2、使用edge或google浏览器打开pdf预览页面&#xff0c;打开开发者模式&#xff0c;用小箭头指向第一页&#xff0c;这样就获取到…

数据库引擎选择指南:MyISM和InnoDB哪个更适合你?

亲爱的小伙伴们&#xff0c;大家好&#xff01;我是小米&#xff0c;今天我要和大家一起来聊一聊两个数据库引擎&#xff0c;分别是MyISM和InnoDB。这两个数据库引擎在MySQL中都扮演着非常重要的角色&#xff0c;了解它们的特点和区别对于我们理解数据库的工作原理和性能优化非…

短视频矩阵系统源码--saas开发

一、概述 抖音SEO矩阵系统源代码是一套针对抖音平台的搜索引擎优化工具&#xff0c;它可以帮助用户提高抖音视频在搜索结果中的排名&#xff0c;增加曝光率和流量。本开发文档旨在提供系统的功能框架、技术要求和开发示例&#xff0c;以便开发者进行二次开发和优化。 二、功能框…

ctfshow web入门 php特性 web136-web140

1.web136 还有一种写文件的命令时tee命令 payload&#xff1a; : ls /|tee 1 访问1下载查看文件1发现根目录下有flag cat /f149_15_h3r3|tee 2 访问下载查看文件22.web137 call_user_func <?php class myclass {static function say_hello(){echo "He…

【m98】视频帧的 jitterbuffer 1:

管理待解码的视频帧: VCMFrameBuffer VCMFrameBufferStateEnum 代表帧的状态信息:组帧失败的(kStateEmpty)?kStateIncomplete(存储了部分包)?kStateComplete(拥有了所有包?) enum VCMFrameBufferStateEnum {kStateEmpty, // frame popped by the RTP receiver…

phpstorm不提示$this->request,不提示Controller父类的方法

![在这里插入图片描述](https://img-blog.csdnimg.cn/d55799a22b724099930eb7fb67260a12.png 最后 保存就可以了

Vue-2.0组件化开发

组件化 一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构、样式、行为。 好处&#xff1a;便于维护&#xff0c;利于复用->提升开发效率 组件分类&#xff1a;普通组件、根组件 根组件 整个应用最上层的组件&#xff0c;包裹所有普通小组件。 Ctrl…