IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> (一)pytorch一维卷积深度学习模型LeNet-AlexNet-ZFNet复现 -> 正文阅读

[人工智能](一)pytorch一维卷积深度学习模型LeNet-AlexNet-ZFNet复现

不管学习什么,基础都是非常重要的,那想对深度学习模型进行创新来说,基础就是所有的经典模型,想要从模型角度进行创新,毫无疑问就需要了解不同类型模型的特点,然后在对每一类模型有一定基础的了解上,再进行创新,目前主要有的经典模型有 LeNet-AlexNet-ZFNet-VGGNets-GooLeNet-ResNet-DenseNet其中前四种属于对卷积层纵向改变,GooLeNet,开始对模型结构进行了横向的变化,接着为了解决网络退化问题,2015年便出现了有名的ResNet残差网络,2017年结GooLeNet的Inception结构和ResNet的残差结构诞生了具有稠密结构的DenseNet稠密网络。而我由于做的是一维信号的识别,所以用pytorch变复现了以上模型的一维版本。本文复现,部分参考《PyTorch深度学习实战-从新手小白到数据专家》


第一篇首先复现的是LeNet网络

LetNet模型结构

LeNet网络是最早期的卷积神经网络只有2个卷积层,但却冥定了后期几乎所有卷积神经网络的基础卷积-池化-全连接的基本结构,在实际复现的过程中增加了一些应用性改动。
1.给每一个卷积层后加入批量标准化层,抑制梯度消失,提升样本初始分布对模型的抗干扰性
2.为了让不同通道数目,不同样本点大小的样本都可以在不对模型进行手动更改的情况下进行训练,所以对模型的最后的全连接部分进行了自适应处理,通过对输入数据的初始化,算出最后的全连接层的第一个参数的大小
3.在输入时检测样本维度大小,当数据维度大小输入错误时进行提示,新手友好

首先浅看一下LeNet的简简单单的模型的结构吧
在这里插入图片描述

因为给模型增加了自适应性所以输出的大小会根据输入数据的大小有不同的变化
表中我们命名输入批次为Batch,输入通道数为Channel,输入的样本点的数量为Sample
如输入的数据为1×1×224
则Batch=1,Channel=1,Sample=224
而经过卷积层和池化之后输出尺寸变化遵循以下公式
各层的参数如下
输出尺寸=(原尺寸+2×填充-核大小)//步幅 + 1

// → 双斜杠对应python中为向下取整操作 → 例: 5//2 = 2

例1:原尺寸Sample,经过了一个卷积核大小为5,步幅为1,填充为0的卷积层
则输出尺寸=(Sample + 2×0 - 5)//1 + 1 = (sample - 5)+1 = sample - 4

例2:原尺寸Sample,经过了一个池化核大小为5,步幅为2,填充为0的池化层
则输出尺寸=(Sample + 2×0 - 2)//2 + 1 = (sample - 2)//2+1 = sample//2 - 2//2 +1 = sample//2 - 1 +1 = sample//2

层号层名核大小 / 步长 / 填充输出大小
-Input-Batch×Channel×Sample
0Conv1d-15/1/0Batch × 20 × (Sample-4)
1MaxPool1d-12/2/0Batch × 20 × ((Sample-4)//2)
2BatchNorm1d-1-Batch × 20 × ((Sample-4)//2)
3Conv1d-25/1/0Batch × 50 × ((Sample-4)//2-4)
4MaxPool1d-22/2/0Batch × 50 × (((Sample-4)//2-4)//2)
5BatchNorm1d-1-Batch × 50 × (((Sample-4)//2-4)//2)
6Flatten-Batch × (50×((Sample-4)//2-4)//2)

进行到第6层之后此时的Sample(当前样本点数量) = (50×((Sample-4)//2-4)//2)

层号层名池化层尺寸输出大小
0Linear-1Sample×512Batch × 512
1ReLU-Batch × 512
2Linear-2512×5Batch × 5
3ReLU-Batch × 5

LetNet代码实现

OK 好了接下来我们看代码实现的部分

import torch 

class LeNet(torch.nn.Module):
   def __init__(self, input_channels, input_sample_points, classes):
       super(LeNet, self).__init__()

       self.input_channels = input_channels
       self.input_sample_points = input_sample_points

       self.features = torch.nn.Sequential(
           torch.nn.Conv1d(input_channels, 20, kernel_size=5),
           torch.nn.BatchNorm1d(20),
           torch.nn.MaxPool1d(2),
           torch.nn.Conv1d(20, 50, kernel_size=5),
           torch.nn.BatchNorm1d(50),
           torch.nn.MaxPool1d(2),
       )

       self.After_features_channels = 50
       # 根据公式计算出通过所有的卷积层和池化层后输出的通道中样本点的数量
       # self.After_features_sample_points = ((input_sample_points - 5 + 1) // 2 - 5 + 1) // 2
       self.After_features_sample_points = ((input_sample_points-4)//2-4) // 2


       self.classifier = torch.nn.Sequential(
           torch.nn.Linear(self.After_features_channels * self.After_features_sample_points, 512),
           torch.nn.ReLU(),
           torch.nn.Linear(512, classes),
           torch.nn.ReLU()
       )

   def forward(self, x):
       # 检查输入样本维度是否有错误
       if x.size(1) != self.input_channels or x.size(2) != self.input_sample_points:
           raise Exception(
               '输入数据维度错误,输入维度应为[Batch_size,{},{}],实际输入维度为{}'.format(self.input_channels, self.input_sample_points,x.size()))

       x = self.features(x)
       x = x.view(-1, self.After_features_channels * self.After_features_sample_points)
       x = self.classifier(x)
       return x


if __name__ == '__main__':
   model = LeNet(input_channels=1, input_sample_points=224, classes=5)
   input = torch.randn(size=(1, 1, 224))
   output = model(input)
   print(output.shape)
   #torch.Size([1, 5])

可以看到如果在训练时设定模型参数和实际输入的维度相同时最后会正常输出结果
那如果输入的维度和设置好的尺寸不一样呢?把输入数据的通道数改成2试一试

input = torch.randn(size=(1, 2, 224))

则就会报如下的错误提示你得修改维度这样对于新手来说对维度这个麻烦事就可以有一个辅助了
在这里插入图片描述
然后我们打印模型看一下对应层的参数

print(model)

在这里插入图片描述
这里可以稍微关注一下classifier里第0层的in_features = 2650
这2650是怎么来的呢还记得我们设置的输入的样本点数量是224,则在进入分类器之前此时输出的样本维度为Batch × 50 × (((Sample-4)//2-4)//2)
(((Sample-4)//2-4)//2) = (((224-4)//2-4)//2) = (220//2 - 4)//2 = 106//2 = 53
则经过下面这个改变维度的代码也就是Flatten层之后

x = x.view(-1, self.After_features_channels * self.After_features_sample_points)

数据变为Batch × 50×(((Sample-4)//2-4)//2) = Batch × (50×63) = Batch × 2650

好了下一步再用torchsummary库看一下每一层的参数的数量,以及存储变量和计算所用到的内存空间的大小

from torchsummary import summary
summary(model=model,input_size=(1,224),device='cpu')

在这里插入图片描述

AlexNet

复现完了LeNet, 接下来复现AlexNet和LeNet,结构上并没有什么创新,对比LeNet主要是首先加深了网络,在处理二维数据时进行了数据增强,其次是引入了Dropout避免过拟合,然后是引用了LRN(Local Response Normalization)有的文章和书上翻译成了局部相应归一化,应该是翻译错了应该是局部相应标准化Normalization是标准化的意思。从有了BN Batch Normalization 之后研究人员发现LRN没什么用所以就去掉了。

import torch 

class AlexNet(torch.nn.Module):
   def __init__(self,input_channels,input_sample_points,classes):
       super(AlexNet, self).__init__()

       self.input_channels = input_channels
       self.input_sample_points = input_sample_points

       self.features = torch.nn.Sequential(

           torch.nn.Conv1d(input_channels,64,kernel_size=11,stride=4,padding=2),
           torch.nn.BatchNorm1d(64),
           torch.nn.ReLU(inplace=True),
           #torch.nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),
           torch.nn.MaxPool1d(kernel_size=3,stride=2),

           torch.nn.Conv1d(64, 192, kernel_size=5, padding=2),
           torch.nn.BatchNorm1d(192),
           torch.nn.ReLU(inplace=True),
           #torch.nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),
           torch.nn.MaxPool1d(kernel_size=3, stride=2),

           torch.nn.Conv1d(192, 384, kernel_size=3, padding=1),
           torch.nn.BatchNorm1d(384),
           torch.nn.ReLU(inplace=True),
           torch.nn.Conv1d(384, 256, kernel_size=3, padding=1),
           torch.nn.ReLU(inplace=True),
           torch.nn.BatchNorm1d(256),
           torch.nn.Conv1d(256, 256, kernel_size=3, padding=1),
           torch.nn.BatchNorm1d(256),
           torch.nn.ReLU(inplace=True),
           torch.nn.MaxPool1d(kernel_size=3, stride=2),
   		#自适应平均池化不管输入多少输出一定为6
           torch.nn.AdaptiveAvgPool1d(6),
       )

       self.classifier = torch.nn.Sequential(

           torch.nn.Dropout(0.5),
           torch.nn.Linear(1536,1024),
           torch.nn.ReLU(inplace=True),

           torch.nn.Dropout(0.5),
           torch.nn.Linear(1024, 1024),
           torch.nn.ReLU(inplace=True),
           torch.nn.Linear(1024,classes),

       )

   def forward(self,x):
       if x.size(1)!=self.input_channels or x.size(2)!=self.input_sample_points:
           raise Exception('输入数据维度错误,输入维度应为[Batch_size,{},{}],实际输入维度为{}'.format(self.input_channels,self.input_sample_points,x.size()))

       x = self.features(x)
       x = x.view(-1,1536)
       x = self.classifier(x)
       return x


if __name__ == '__main__':
   model = AlexNet(input_channels=1, input_sample_points=224, classes=5)
   input = torch.randn(size=(1, 1, 224))
   output = model(input)
   print(output.shape)
   #torch.Size([1, 5])

ZFNet

ZFnet 将AlexNet的的第一个卷积核由于11变成7步长从4变成了2后面卷积层变为384,384,256复现ZFNet的时候提取特征部分又换回了普通的池化层

import torch

class ZFNet(torch.nn.Module):
   def __init__(self,input_channels,input_sample_points,classes):
       super(ZFNet, self).__init__()

       self.input_channels = input_channels
       self.input_sample_points = input_sample_points

       self.features = torch.nn.Sequential(
           torch.nn.Conv1d(input_channels,96,kernel_size=7,stride=2),
           torch.nn.BatchNorm1d(96),
           torch.nn.MaxPool1d(kernel_size=3,stride=2),
           torch.nn.Conv1d(96, 256, kernel_size=5, stride=2),
           torch.nn.BatchNorm1d(256),
           torch.nn.MaxPool1d(kernel_size=3, stride=2),

           torch.nn.Conv1d(256, 384, kernel_size=3, padding=1),
           torch.nn.BatchNorm1d(384),
           torch.nn.Conv1d(384, 384, kernel_size=3, padding=1),
           torch.nn.BatchNorm1d(384),
           torch.nn.Conv1d(384, 256, kernel_size=3, padding=1),
           torch.nn.BatchNorm1d(256),
           torch.nn.MaxPool1d(kernel_size=3, stride=2),
       )

       self.After_features_channels = 256
       self.After_features_sample_points = (((((((((input_sample_points-7)//2 + 1)-3)//2+1)-5)//2+1)-3)//2+1)-3)//2+1
       self.classifier = torch.nn.Sequential(

           torch.nn.Linear(self.After_features_channels*self.After_features_sample_points,1024),
           torch.nn.ReLU(inplace=True),
           torch.nn.Dropout(0.5),

           torch.nn.Linear(1024, 1024),
           torch.nn.ReLU(inplace=True),
           torch.nn.Dropout(0.5),

           torch.nn.Linear(1024,classes),
       )

   def forward(self,x):
       if x.size(1)!=self.input_channels or x.size(2)!=self.input_sample_points:
           raise Exception('输入数据维度错误,输入维度应为[Batch_size,{},{}],实际输入维度为{}'.format(self.input_channels,self.input_sample_points,x.size()))

       x = self.features(x)
       x = x.view(-1,self.After_features_channels*self.After_features_sample_points)
       x = self.classifier(x)
       return x


if __name__ == '__main__':
   model = ZFNet(input_channels=1, input_sample_points=224, classes=5)
   input = torch.randn(size=(1, 1, 224))
   output = model(input)
   print(output.shape)
   #torch.Size([1, 5])

总结

在复现一维模型的过程中报留了卷积层和池化层对应的尺寸,全连接层的尺寸做了相应的缩小,主要还是用作模型对比。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-06-06 17:19:25  更:2022-06-06 17:19:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 2:37:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码