第三章 GoogLeNet网络详解

news2024/9/23 3:28:08

系列文章目录

第一章 AlexNet网络详解

第二章 VGG网络详解

第三章 GoogLeNet网络详解 

第四章 ResNet网络详解 

第五章 ResNeXt网络详解 

第六章 MobileNetv1网络详解 

第七章 MobileNetv2网络详解 

第八章 MobileNetv3网络详解 

第九章 ShuffleNetv1网络详解 

第十章 ShuffleNetv2网络详解 

第十一章 EfficientNetv1网络详解 

第十二章 EfficientNetv2网络详解 

第十三章 Transformer注意力机制

第十四章 Vision Transformer网络详解 

第十五章 Swin-Transformer网络详解 

第十六章 ConvNeXt网络详解 

第十七章 RepVGG网络详解 

第十八章 MobileViT网络详解 


文章目录

  • GoogLeNet网络详解
  • 0. 前言
  • 1. 摘要
  • 2. GoogLeNet网络详解网络架构
    • 1. GoogLeNet网络详解_Model.py(pytorch实现)
    • 2.
  • 总结


0、前言


1、摘要

       我们提出了一种被称为Inception的深度卷积神经网络架构,该架构在ImageNet大规模视觉识别挑战赛2014(ILSVRC14)的分类和检测方面实现了新的技术水平。该架构的主要特点是在网络内部改进了计算资源的利用。通过精心设计,我们增加了网络的深度和宽度,同时保持了计算预算不变。为了优化质量,架构决策基于Hebbian原理和多尺度处理的直觉。我们在ILSVRC14提交的一种特定的具体化称为GoogLeNet,是一种22层深度网络,其质量在分类和检测的背景下得到评估。

2、VGG网络结构

1.在ILSVRC14中,Inception深度卷积神经网络架构取得了分类和检测方面的最新技术成果。

2. 本文的研究背景是设计一种深度卷积神经网络架构,以在ImageNet大规模视觉识别挑战赛2014中取得更好的分类和检测结果。

3.本文的主要论点是通过精心设计的Inception架构,能够提高神经网络内部计算资源的利用率以及完善多尺度处理的直觉,从而实现更好的分类和检测结果。

4.以往的研究使用的方法主要是传统的卷积神经网络架构,这种方法存在一些问题如网络深度有限,不能充分利用计算资源等。

5.本文提出的研究方法是使用Inception架构设计深度卷积神经网络,通过增加网络层数和宽度并保持计算预算不变的方式,提高计算资源利用率和精度。

6.本研究的发现是Inception架构能够在ImageNet大规模视觉识别挑战赛2014中取得更好的分类和检测结果,具有重要意义。然而,该研究的局限性在于其应用范围较为有限,需要进一步优化和改进。

GoogLeNet网络有22层深(包括pool层,有27层深),在分类器之前,采用Network in Network中用Averagepool(平均池化)来代替全连接层的思想,而在avg pool之后,还是添加了一个全连接层,是为了大家做finetune(微调)。而无论是VGG还是LeNet、AlexNet,在输出层方面均是采用连续三个全连接层,全连接层的输入是前面卷积层的输出经过reshape得到。据发现,GoogLeNet将fully-connected layer用avg pooling layer代替后,top-1 accuracy 提高了大约0.6%;然而即使在去除了fully-connected layer后,依然必须dropout。由于全连接网络参数多,计算量大,容易过拟合,所以GoogLeNet没有采用VGG、LeNet、AlexNet三层全连接结构,直接在Inception模块之后使用Average Pool和Dropout方法,不仅起到降维作用,还在一定程度上防止过拟合。在Dropout层之前添加了一个7×7的Average Pool,一方面是降维,另一方面也是对低层特征的组合。我们希望网络在高层可以抽象出图像全局的特征,那么应该在网络的高层增加卷积核的大小或者增加池化区域的大小,GoogLeNet将这种操作放到了最后的池化过程,前面的Inception模块中卷积核大小都是固定的,而且比较小,主要是为了卷积时的计算方便。

 Local Response Normalization(LRN)是一种在卷积神经网络中用于局部响应归一化的技术。它由Krizhevsky等人在AlexNet网络中提出,并在后续的一些经典网络中得到了使用,如GoogleNet和VGGNet等。LRN的主要目的是通过抑制相邻神经元的响应,增强网络的泛化性能。它通过对每个神经元的输出进行归一化处理,使得每个神经元的响应对相邻神经元的响应不敏感。具体来说,对于卷积层中的每个神经元,LRN会对其输出进行如下的归一化计算:
LRN公式:

其中,bx,yi表示归一化后的输出,ax,yi表示原始输出,N表示该层中神经元的总数,n表示归一化时局部感受野的大小,k、α和β是超参数,分别控制归一化的强度、偏置和非线性程度。需要注意的是,LRN在一些后续的研究中被发现对网络的性能并没有显著的提升,甚至可能对结果产生负面影响。因此,LRN已经逐渐被一些新的正则化方法所取代,如Batch Normalization和Group Normalization等。

1.GoogLeNet_Model.py(pytorch实现)

import torch.nn as nn
import torch

class AlexNet(nn.Module):
    def __init__(self,num_classes=1000,init_weights=False):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(48, 128, kernel_size=5, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(128, 192, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 192, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 128, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3,stride=2)
        )
        self.classifier = nn.Sequential(
            nn.Dropout(p=0.5),
            nn.Linear(128*6*6, 2048),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(2048, 2048),
            nn.ReLU(inplace=True),
            nn.Linear(2048, num_classes)
        )
        if init_weights:
            self._initialize_weights()

    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, start_dim=1)
        x = self.classifier(x)
        return x

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                nn.init.constant_(m.bias, 0)

2.train.py

import os
import sys
import json
import torch
import torch.nn as nn
from torchvision import transforms, datasets, utils
import matplotlib.pyplot as plt
import numpy as np
import torch.optim as optim
from tqdm import tqdm
from model import AlexNet

def main():
    device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu')
    print("using {} device.".format(device))

    data_transform = {
        "train": transforms.Compose([transforms.RandomResizedCrop(224),
                                     transforms.RandomHorizontalFlip(),
                                     transforms.ToTensor(),
                                     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]),
        "val": transforms.Compose([transforms.Resize((224, 224)),
                                   transforms.ToTensor(),
                                   transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])}
    data_root = 'D:/100_DataSets/'
    image_path = os.path.join(data_root, "03_flower_data")
    assert os.path.exists(image_path), "{} path does not exits.".format(image_path)
    train_dataset = datasets.ImageFolder(root=os.path.join(image_path, "train"),transform = data_transform['train'])
    train_num = len(train_dataset)
    flower_list = train_dataset.class_to_idx
    cla_dict = dict((val, key) for key, val in flower_list.items())
    json_str = json.dumps(cla_dict, indent=4)
    with open('class_indices.json', 'w') as json_file:
        json_file.write(json_str)
    batch_size = 6
    nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])
    print('Using {} dataloder workers every process'.format(nw))
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                             batch_size=batch_size,
                                             shuffle=True,
                                             num_workers=nw)
    validate_dataset = datasets.ImageFolder(root=os.path.join(image_path, "val"),
                                            transform=data_transform['val'])
    val_num = len(validate_dataset)
    validate_loader = torch.utils.data.DataLoader(validate_dataset,
                                                 batch_size=4,
                                                 shuffle=False,
                                                 num_workers=nw)
    print("using {} image for train, {} images for validation.".format(train_num, val_num))
    net = AlexNet(num_classes=5, init_weights=True)
    net.to(device)
    loss_fuction = nn.CrossEntropyLoss()
    optimizer = optim.Adam(net.parameters(), lr=0.0002)
    epochs = 10
    save_path = './AlexNet.pth'
    best_acc = 0.0
    train_steps = len(train_loader)
    for epoch in range(epochs):
        net.train()
        running_loss = 0.0
        train_bar = tqdm(train_loader, file=sys.stdout)
        for step, data in enumerate(train_bar):
            images, labels = data
            optimizer.zero_grad()
            outputs = net(images.to(device))
            loss = loss_fuction(outputs, labels.to(device))
            loss.backward()
            optimizer.step()
            running_loss += loss.item()
            train_bar.desc = "train epoch[{}/{}] loss:{:,.3f}".format(epoch+1, epochs, loss)
        net.eval()
        acc = 0.0
        with torch.no_grad():
            val_bar = tqdm(validate_loader, file=sys.stdout)
            for val_data in val_bar:
                val_images, val_labels = val_data
                outputs = net(val_images.to(device))
                predict_y = torch.max(outputs, dim=1)[1]
                acc += torch.eq(predict_y, val_labels.to(device)).sum().item()
        val_accurate = acc / val_num
        print('[epoch % d] train_loss: %.3f val_accuracy: %.3f' %
              (epoch+1, running_loss / train_steps, val_accurate))
        if val_accurate > best_acc:
            best_acc = val_accurate
            torch.save(net.state_dict(),save_path)
    print("Finished Training")

if __name__ == '__main__':
    main()






3.predict.py

import os
import json
import torch
from PIL import Image
from torchvision import transforms
import matplotlib.pyplot as plt
from model import AlexNet

def main():
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    data_transform = transforms.Compose(
        [transforms.Resize((224, 224)),
         transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5),(0.5, 0.5, 0.5))]
    )
    img_path = "D:/20_Models/01_AlexNet_pytorch/image_predict/tulip.jpg"
    assert os.path.exists(img_path), "file: '{}' does not exist.".format(img_path)
    img = Image.open(img_path)
    plt.imshow(img)
    img = data_transform(img)
    img = torch.unsqueeze(img, dim=0)
    json_path = './class_indices.json'
    assert os.path.exists(json_path), "file: '{}' does not exist.".format(json_path)
    with open(json_path,"r") as f:
        class_indict = json.load(f)
    model = AlexNet(num_classes=5).to(device)
    weights_path = "./AlexNet.pth"
    assert os.path.exists(weights_path), "file: '{}' does not exist.".format(weights_path)
    model.load_state_dict(torch.load(weights_path))
    model.eval()
    with torch.no_grad():
        output = torch.squeeze(model(img.to(device))).cpu()
        predict = torch.softmax(output, dim=0)
        predict_cla = torch.argmax(predict).numpy()
    print_res = "class: {} prob: {:.3f}".format(class_indict[str(predict_cla)],
                                                predict[predict_cla].numpy())
    plt.title(print_res)
    for i in range(len(predict)):
        print("class: {:10} prob: {:.3}".format(class_indict[str(i)],predict[i].numpy()))
    plt.show()

if __name__ == '__main__':
    main()

4.predict.py

import os
from shutil import copy, rmtree
import random

def mk_file(file_path: str):
    if os.path.exists(file_path):
        rmtree(file_path)
    os.makedirs(file_path)

def main():
    random.seed(0)
    split_rate = 0.1
    #cwd = os.getcwd()
    #data_root = os.path.join(cwd, "flower_data")
    data_root = 'D:/100_DataSets/03_flower_data'
    origin_flower_path = os.path.join(data_root, "flower_photos")
    assert os.path.exists(origin_flower_path), "path '{}' does not exist".format(origin_flower_path)
    flower_class = [cla for cla in os.listdir(origin_flower_path) if os.path.isdir(os.path.join(origin_flower_path, cla))]
    train_root = os.path.join(data_root,"train")
    mk_file(train_root)
    for cla in flower_class:
        mk_file(os.path.join(train_root, cla))
    val_root = os.path.join(data_root, "val")
    mk_file(val_root)
    for cla in flower_class:
        mk_file(os.path.join(val_root,cla))
    for cla in flower_class:
        cla_path = os.path.join(origin_flower_path,cla)
        images = os.listdir(cla_path)
        num = len(images)
        eval_index = random.sample(images, k=int(num*split_rate))
        for index, image in enumerate(images):
            if image in eval_index:
                image_path = os.path.join(cla_path, image)
                new_path = os.path.join(val_root, cla)
                copy(image_path, new_path)
            else:
                image_path = os.path.join(cla_path, image)
                new_path = os.path.join(train_root, cla)
                copy(image_path, new_path)
            print("\r[{}] processing [{} / {}]".format(cla, index+1, num), end="")
        print()
    print("processing done!")
    
if __name__ == "__main__":
    main()

总结

提示:这里对文章进行总结:

每天一个网络,网络的学习往往具有连贯性,新的网络往往是基于旧的网络进行不断改进。

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

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

相关文章

基于Java软件科技公司信息管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

STM32启动模式

M3/M4/M7内核复位后,做的第一件事: 从地址0x00000000处取出堆栈指针MSP的初始值,该值就是栈顶地址。从地址0x00000004处取出程序计数器指针PC的初始值,该值是复位向量。 芯片厂商可能会把0x00000000和0x00000004地址映射到其它的…

ADC(模数转换)详解

ADC(模数转换)详解 前言ADC的定义ADC简介ADC特性ADC时钟工作模式单通道单次转换练习多通道扫描模式单次转换 前言 在STM32微控制器中,ADC代表模数转换器(Analog-to-Digital Converter)。ADC是一种用于将模拟信号转换为…

【Linux】程序地址空间?进程地址空间

目录 程序地址空间回顾进程地址空间什么是进程地址空间&#xff1f;进程地址空间与PCB、物理内存、页表和磁盘之间的关系为什么要存在虚拟地址空间&#xff1f;重新理解地址空间 程序地址空间回顾 了解进程的运行&#xff1a; 1 #include <stdio.h>2 #include <unist…

Web安全——HTML基础

HTML 一、对于前端以及后端的认识以及分析二、HTML认知1、网页的组成2、浏览器3、Web标准 三、简单的HTML页面架构四、HTML常见标签1、meta标签2、标题标签3、文本属性4、form表单5、a 标签6、锚文本7、img 标签8、table 表格9、列表标签9.1、无序列表9.2、有序列表 10、框架的…

个人工作总结和计划怎么写

工作总结和计划怎么写1 20__年就快结束&#xff0c;回首年的工作&#xff0c;有硕果累累的喜悦&#xff0c;有与同事协同攻关的艰辛&#xff0c;也有遇到困难和挫折时惆怅&#xff0c;时光过得飞快&#xff0c;不知不觉中&#xff0c;充满希望的_年就伴随着新年伊始即将临近。可…

C++ 重载函数

文章目录 前言一、什么是重载函数&#xff1f;二、重载函数的类型&#xff0c;作用。1. 构造函数重载&#xff1a;2. 运算符重载&#xff1a;3. 函数重载&#xff1a;4. 成员函数重载&#xff1a; 总结 前言 一、什么是重载函数&#xff1f; 在C中&#xff0c;函数重载&#x…

【Linux工具篇】---vim的基本使用

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【Linux专栏】&#x1f388; 本专栏旨在分享学习Linux的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录 &#x1f370…

C# 学习(一)概述

今天开始学习 C#&#xff0c;所有学习资料来源于&#xff1a; 菜鸟教程 一、C# 简介 C# 是 .NET 框架的一部分&#xff0c;随之创造出来的语言&#xff0c;所以了解 C# 前&#xff0c;需要知道 .NET 是个什么东西。 1.1 .NET 框架介绍 .NET 是微软提出的 Web 的一种软件开发…

智能文档图像处理技术应用与实践

写在前面智能文档处理面临的技术难题智能文档处理的研究领域● 文档图像分析与预处理● 手写板反光擦除● 版面分析与文档还原 写在最后 写在前面 VALSE 2023 无锡视觉与学习青年学者研讨会近期在无锡国际博览中心举办&#xff0c;由江南大学和无锡新吴区联合承办。本次会议旨…

卡尔曼滤波在目标跟踪中的应用(4)

在前一节内容中&#xff0c;我们学习了二维匀加速运动目标的卡尔曼滤波问题&#xff0c;同时利用MATLAB进行了仿真验证&#xff0c;今天我们继续往下扩展一个维度&#xff0c;学习三维空间下的卡尔曼滤波问题。 话不多说&#xff0c;开整&#xff01;&#xff01;&#xff01; …

【深度学习】6-1 卷积神经网络 - 卷积层

卷积神经网络(Convolutional Neural Network&#xff0c;CNN)。 CNN 被用于图像识别、语音识别等各种场合&#xff0c;在图像识别的比赛中&#xff0c;基于深度学习的方法几乎都以 CNN 为基础。 首先&#xff0c;来看一下 CNN 的网络结构&#xff0c;了解 CNN 的大致框架。CNN…

算法程序设计 之 装载问题(6/8)

一、实验目的&#xff1a; 理解并掌握回溯法与分支限界法的联系与区别&#xff0c;学会构造不同问题的解空间树&#xff0c;用上述两种算法解决装载问题。 实验内容问题描述&#xff1a;有n个集装箱要装上2艘载重量分别为C1和C2的轮船&#xff0c;其中集装箱i的重量为wi&#…

论文浅尝 | DEER:解释实体关系的描述性知识图谱

笔记整理&#xff1a;王润哲&#xff0c;东南大学硕士&#xff0c;研究方向为多元关系抽取 链接&#xff1a;https://aclanthology.org/2022.emnlp-main.448.pdf 动机 实体关系是知识图谱中不可或缺的一层重要信息&#xff0c;它们描述了实体之间的语义关系&#xff0c;这种连接…

【力扣刷题 | 第十二天】

目录 前言&#xff1a; 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 111. 二叉树的最小深度 - 力扣&#xff08;LeetCode&#xff09; 前序遍历&#xff1a; 后序遍历&#xff1a; 总结&#xff1a; 前言&#xff1a; 今天还是对树的基础题进行刷题&am…

大数据Doris(四十七):开启Steam Load记录

文章目录 开启Steam Load记录 一、停止 Doris 集群 二、在 node3-node5 BE 节点上配置 be.conf 三、重新启动 Doris 集群 开启Steam Load记录 后续执行Stream Load 导入任务后&#xff0c;我们会在Doris集群中会查询对应Stream Load任务的情况&#xff0c;默认BE是不记录S…

【Rust日报】2023-06-20 使用Quickwit、Jaeger和Grafana监控您的Rust应用程序

使用Quickwit、Jaeger和Grafana监控您的Rust应用程序 你可能已经看过了Lucas Palmieri的博客文章Are we observable yet? An introduction to Rust telemetry。如果你还没有看过&#xff0c;我们建议阅读一下&#xff0c;因为它提供了一个全面的介绍&#xff0c;介绍了如何处理…

【Python 基础篇】Python 函数:代码重用的利器

文章目录 导言一、创建函数二、函数参数1、位置参数2、关键字参数3、默认参数 三、函数返回值四、函数的高级用法1、递归函数2、匿名函数3、内置函数 总结 导言 函数是一种在Python中定义和封装可重用代码的重要机制。它们使我们能够将复杂的任务分解为更小的部分&#xff0c;…

【算法与数据结构】15、LeetCode三数之和

文章目录 一、题目二、双指针法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、双指针法 思路分析&#xff1a;我们使用双指针法&#xff0c;但这道题因为要求数组三个元素的和&#xff0c;一共用到了三个指…

新人拿到一个web项目如何使用idea发布运行

本文描述的是一个新手&#xff0c;拿到一个web项目&#xff0c;使用idea如何发布运行。项目中没有非常复杂的元素&#xff0c;只是试着描述应该如何配置相关内容。 内容描述前提&#xff0c;首先请您确认tomcat已经安装&#xff0c;其次确认jdk已经安装&#xff0c;并明确他们在…