SqueezeNet 一维,二维网络复现 pytorch 小白易懂版

2023-10-21 05:52

本文主要是介绍SqueezeNet 一维,二维网络复现 pytorch 小白易懂版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SqueezeNet

时隔一年我又开始复现神经网络的经典模型,这次主要复的是轻量级网络全家桶,轻量级神经网络旨在使用更小的参数量,无限的接近大模型的准确率,降低处理时间和运算量,这次要复现的是轻量级网络的非常经典的一个模型SqueezeNet,它由美国加州大学伯克利分校的研究团队开发,并于2016年发布。


文章链接: https://arxiv.org/pdf/1602.07360.pdf?source=post_page---------------------------

看懂这篇文章需要的基础知识

  1. 了解python语法基础
  2. 了解深度学习基本原理
  3. 知道什么是卷积层池化层激活函数层softmanx层
  4. 熟悉卷积层池化层需要的参数
  5. 需要了解pytorch模型的基本构成

我记得去年的这个时候,好像GPT还没被特别广泛的使用,还没到一键就能直接输出写好的模型的这一个步骤,那为什么还要看博客这类的文章呢,应该是因为毕竟GPT他还是靠着已有的资料进行读取,他不能图文并茂的给你写一个一定好用的大型模型,不然直接把论文甩给他让他复现就好了,所以还是打算写一下,然后简单画点图然后给之后的学弟学妹们留一点遗产。

SqueezeNet 的模型结构

下面是原论文给出的模型结构
在这里插入图片描述
原文中给出了三种模型,分别是第一个基础模型,以及第二个和第三个带有残差分支的模型,其中卷积池化分支我们都有了解,这里新的东西就是这个Fire层,那就先从这个Fire层开始介绍

Fire层

作者说他的SqueezeNet网络为什么可以有更小的参数量,主要由于用了下面这个叫Fire层的东西,Fire层分两部分

  • 一部分是Squeeze层其实就是卷积核大小为1×1的一个卷积层
  • 另一部分呢是expend层他实际上是卷积核大小为1×1和卷积核大小为卷积层和3×3输出的一个拼接

下面是原论文中对Fire模型的详细描述
在这里插入图片描述
在这里插入图片描述
那如果要实现一维的那就把3×3的卷积核改成1×3的
加上激活函数,其实现代码应该是这样的,接下来详细介绍里面的参数。

  • in_channels 指Fire模块的输入通道数,也是就每个Fire模块的squeeze卷积层的输入通道数
  • squeeze_channels 指的是squeeze层的输出通道数
  • expand1x1_channels 指的是expand层中卷积核大小为1×1的卷积层的输出通道数
  • expand1x3_channels 指的是expand层中卷积核大小为1×2的卷积层的输出通道数
class FireModule(torch.nn.Module):def __init__(self, in_channels, squeeze_channels, expand1x1_channels, expand1x3_channels):super(FireModule, self).__init__()self.squeeze = torch.nn.Conv1d(in_channels, squeeze_channels, kernel_size=1)self.relu = torch.nn.ReLU(inplace=True)self.expand1x1 = torch.nn.Conv1d(squeeze_channels, expand1x1_channels, kernel_size=1)self.expand1x3 = torch.nn.Conv1d(squeeze_channels, expand1x3_channels, kernel_size=3, padding=1)def forward(self, x):x = self.squeeze(x)x = self.relu(x)out1x1 = self.expand1x1(x)out1x3 = self.expand1x3(x)out = torch.cat([out1x1, out1x3], dim=1)return self.relu(out)

基础知识补充: torch.cat 将向量在某一个维度上拼接

import torch
# Create two tensors
out1x1 = torch.tensor([[1, 2, 3], [1, 2, 3]])
out1x3 = torch.tensor([[4, 5, 6], [7, 8, 9]])# Concatenate the tensors along the second dimension (dim=1)
out = torch.cat([out1x1, out1x3], dim=1)
print(out)
# tensor([[1, 2, 3, 4, 5, 6],
#         [1, 2, 3, 7, 8, 9]])
out = torch.cat([out1x1, out1x3], dim=0)
print(out)
# tensor([[1, 2, 3],
#         [1, 2, 3],
#         [4, 5, 6],
#         [7, 8, 9]])

那有了Fire层模块之后就可以开始搭建我们的模型,那在搭建的过程中,各个层的参数如何设置呢,原文中给了如下表
在这里插入图片描述

  • 第一列Layer name/type 指的是层的名称和类型
  • 第二列Output size 指的是输出尺寸
  • 第三列是filter size/stride (if not a fire layer)滤波器(卷积核/池化核)的大小(不包含Fire层)
  • 第四列depth 卷积层的深度,可以无视掉,没什么用
  • 第五-第七 给的就是Fire 层的参数了

再后面的是稀疏性字节大小还有修剪前后的参数大小,这部分不用过于关注,可能要多提一下的就是这个稀疏性sparsity,他指的是卷积层里选择多少参数一直为0,但是并没有详细说具体是怎么实现的,然后我也去搜了一下,需要用一些正则化的东西才可以,这个问题我打算再详细理解一下,暂时我们都默认稀疏性是100,不再为了稀疏性降低参数量实现额外复杂的工作.

根据参数和结构实现代码

一维

import torch
from torchsummary import summary
class FireModule(torch.nn.Module):def __init__(self, in_channels, squeeze_channels, expand1x1_channels, expand1x3_channels):super(FireModule, self).__init__()self.squeeze = torch.nn.Conv1d(in_channels, squeeze_channels, kernel_size=1)self.relu = torch.nn.ReLU(inplace=True)self.expand1x1 = torch.nn.Conv1d(squeeze_channels, expand1x1_channels, kernel_size=1)self.expand1x3 = torch.nn.Conv1d(squeeze_channels, expand1x3_channels, kernel_size=3, padding=1)def forward(self, x):x = self.squeeze(x)x = self.relu(x)out1x1 = self.expand1x1(x)out1x3 = self.expand1x3(x)out = torch.cat([out1x1, out1x3], dim=1)return self.relu(out)class SqueezeNet(torch.nn.Module):def __init__(self,in_channels,classes):super(SqueezeNet, self).__init__()self.features = torch.nn.Sequential(# conv1torch.nn.Conv1d(in_channels, 96, kernel_size=7, stride=2),torch.nn.ReLU(inplace=True),# maxpool1torch.nn.MaxPool1d(kernel_size=3, stride=2),# Fire2FireModule(96, 16, 64, 64),# Fire3FireModule(128, 16, 64, 64),# Fire4FireModule(128, 32, 128, 128),# maxpool4torch.nn.MaxPool1d(kernel_size=3, stride=2),# Fire5FireModule(256, 32, 128, 128),# Fire6FireModule(256, 48, 192, 192),# Fire7FireModule(384, 48, 192, 192),# Fire8FireModule(384, 64, 256, 256),# maxpool8torch.nn.MaxPool1d(kernel_size=3, stride=2),# Fire9FireModule(512, 64, 256, 256))self.classifier = torch.nn.Sequential(# conv10torch.nn.Conv1d(512, classes, kernel_size=1),torch.nn.ReLU(inplace=True),# avgpool10torch.nn.AdaptiveAvgPool1d((1)))def forward(self, x):x = self.features(x)x = self.classifier(x)x = torch.flatten(x, 1)return xif __name__ == "__main__":# 创建一个SqueezeNet实例model = SqueezeNet(in_channels=3,classes=10)# model = FireModule(96,16,64,64)# 打印模型结构summary(model=model, input_size=(3, 224), device='cpu')

二维

import torch
from torchsummary import summary
class FireModule(torch.nn.Module):def __init__(self, in_channels, squeeze_channels, expand1x1_channels, expand3x3_channels):super(FireModule, self).__init__()self.squeeze = torch.nn.Conv2d(in_channels, squeeze_channels, kernel_size=1)self.relu = torch.nn.ReLU(inplace=True)self.expand1x1 = torch.nn.Conv2d(squeeze_channels, expand1x1_channels, kernel_size=1)self.expand3x3 = torch.nn.Conv2d(squeeze_channels, expand3x3_channels, kernel_size=3, padding=1)def forward(self, x):x = self.squeeze(x)x = self.relu(x)out1x1 = self.expand1x1(x)out3x3 = self.expand3x3(x)out = torch.cat([out1x1, out3x3], dim=1)return self.relu(out)class SqueezeNet(torch.nn.Module):def __init__(self,in_channels,classes):super(SqueezeNet, self).__init__()self.features = torch.nn.Sequential(# conv1torch.nn.Conv2d(in_channels, 96, kernel_size=7, stride=2),torch.nn.ReLU(inplace=True),# maxpool1torch.nn.MaxPool2d(kernel_size=3, stride=2),# Fire2FireModule(96, 16, 64, 64),# Fire3FireModule(128, 16, 64, 64),# Fire4FireModule(128, 32, 128, 128),# maxpool4torch.nn.MaxPool2d(kernel_size=3, stride=2),# Fire5FireModule(256, 32, 128, 128),# Fire6FireModule(256, 48, 192, 192),# Fire7FireModule(384, 48, 192, 192),# Fire8FireModule(384, 64, 256, 256),# maxpool8torch.nn.MaxPool2d(kernel_size=3, stride=2),# Fire9FireModule(512, 64, 256, 256))self.classifier = torch.nn.Sequential(# conv10torch.nn.Conv2d(512, classes, kernel_size=1),torch.nn.ReLU(inplace=True),# avgpool10torch.nn.AdaptiveAvgPool2d((1,1)))def forward(self, x):x = self.features(x)x = self.classifier(x)x = torch.flatten(x, 1)return xif __name__ == "__main__":# 创建一个SqueezeNet实例model = SqueezeNet(in_channels=3,classes=10)# model = FireModule(96,16,64,64)# 打印模型结构summary(model=model, input_size=(3, 224, 224), device='cpu')

结束

对于SqueezeNet的第二个和第三个模型,我先把其他的轻量级网络都复现完之后我再回来写一下,对于入门来说先实现个基础版本就够用了

这篇关于SqueezeNet 一维,二维网络复现 pytorch 小白易懂版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/252373

相关文章

Pytorch介绍与安装过程

《Pytorch介绍与安装过程》PyTorch因其直观的设计、卓越的灵活性以及强大的动态计算图功能,迅速在学术界和工业界获得了广泛认可,成为当前深度学习研究和开发的主流工具之一,本文给大家介绍Pyto... 目录1、Pytorch介绍1.1、核心理念1.2、核心组件与功能1.3、适用场景与优势总结1.4、优

conda安装GPU版pytorch默认却是cpu版本

《conda安装GPU版pytorch默认却是cpu版本》本文主要介绍了遇到Conda安装PyTorchGPU版本却默认安装CPU的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、问题描述二、网上解决方案罗列【此节为反面方案罗列!!!】三、发现的根本原因[独家]3.1 p

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

PyTorch中cdist和sum函数使用示例详解

《PyTorch中cdist和sum函数使用示例详解》torch.cdist是PyTorch中用于计算**两个张量之间的成对距离(pairwisedistance)**的函数,常用于点云处理、图神经网... 目录基本语法输出示例1. 简单的 2D 欧几里得距离2. 批量形式(3D Tensor)3. 使用不

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

Docker安装MySQL镜像的详细步骤(适合新手小白)

《Docker安装MySQL镜像的详细步骤(适合新手小白)》本文详细介绍了如何在Ubuntu环境下使用Docker安装MySQL5.7版本,包括从官网拉取镜像、配置MySQL容器、设置权限及内网部署,... 目录前言安装1.访问docker镜像仓库官网2.找到对应的版本,复制右侧的命令即可3.查看镜像4.启

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义