位置: IT常识 - 正文

卷积神经网络学习—Resnet50(论文精读+pytorch代码复现)(卷积神经网络课程)

编辑:rootadmin
卷积神经网络学习—Resnet50(论文精读+pytorch代码复现) 前言一、Resnet论文精读引入残差残差块ResNet50模型基本构成BN层Resnet50总体结构二、Resnet50代码复现完整代码前言

推荐整理分享卷积神经网络学习—Resnet50(论文精读+pytorch代码复现)(卷积神经网络课程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:卷积神经网络视频,卷积神经网络教程,卷积神经网络学到了什么,卷积神经网络教学视频,卷积神经网络学到了什么,卷积神经网络教程,卷积神经网络学生,卷积神经网络学的是什么,内容如对您有帮助,希望把文章链接给更多的朋友!

如果说在CNN领域一定要学习一个卷积神经网络,那一定非Resnet莫属了。 接下来我将按照:Resnet论文解读、Pytorch实现ResNet50模型两部分,进行讲解,博主也是初学者,不足之处欢迎大家批评指正。

预备知识:卷积网络的深度越深,提取的特征越高级,性能越好,但传统的卷积神经网络随着层数深度的增加,会面临网络退化、梯度消失、梯度爆炸等问题,使得高层网络的性能反而不如浅层网络。

卷积细节: 将一个*(W,H,C)的3维矩阵*,输入卷积层,卷积步长stride,边界填充数量padding,KxK卷积核Cout个:

输出一个(W-K+2padding)/stride +1,(H-K+2padding)/stride +1,Cout)的3维矩阵。

网络退化: 深层网络训练模型可收敛,但在测试集和训练集的误差均大于浅层网络。 (与过拟合不同:过拟合是训练集误差低,测试集误差高) 梯度消失: 假设每层梯度是一个小于1的数,由链式法则,反向传播时,梯度时不断相乘的,每向前传播一层,梯度就乘以一个小于1的数,传到最后一层,梯度已经接近0了,这就是梯度消失,换句话说就是,小于1的数连成很快会趋近于0。 梯度爆炸: 反之,如果每层梯度是一个大于1的数,大于1的数连成很快会趋近于无穷。

为解决上述问题 Resnet创新亮点: 1.解决梯度消失\爆炸问题:引入BN层(Batch Normalization),弃用Dropout 2.解决网络退化问题:引入残差(Residual)

`提示:以下是本篇文章正文

一、Resnet论文精读引入残差

残差的基本思想:真实测量值=预测值+残差 **

残差块

**: 其中,输入X,分为两路,X为恒等映射,F(X)为残差映射,两者求和进入激活函数,再输出Relu(F(X)+X)。

残差F(X)的作用:是修正恒等映射X的误差,使网络拟合的更好。 如果X足够好,则残差的参数均为0,使输出的F(X)=0; 如果X不够好,F(X)在X的基础上优化。

其中,F(X)与X相加时,shape必须相同,若F(X)的数据维数变化(如stride>1降维),则X也需要进行相应的变化(如对X做1x1的卷积)。

求F(X)残差的卷积均使用3x3conv,下采样大小降维一半。

卷积神经网络学习—Resnet50(论文精读+pytorch代码复现)(卷积神经网络课程)

由于恒等映射X的存在,反向传播时,梯度可以从深层直接给到浅层,避免了梯度消失与爆炸。

改进的残差块:

**

ResNet50模型基本构成

** ResNet50有两个基本的块,分别名为Conv Block和Identity Block。 Conv Block:针对X和F(X)的维度(通道数和size)是不一样的,所以不能连续串联,它的作用是改变网络的维度;

Identity Block:针对X和F(X)的维度(通道数和size)相同,可以串联,用于加深网络的。 **

BN层

:** Batch normalization:目的是预处理使我们的一批(Batch)的feature map满足均值为0,方差为1的分布规律,这样能够加速网络的收敛。(在网络中间调整每层输入的feature map)。

一个batch size为2(两张图片,每张图片有3个通道,其中颜色红,绿,蓝分别代表r,g,b通道。)的Batch Normalization的原理,首先会统计每个通道数目所有点的像素值,求得均值和方差,然后在每个通道上分别用该点的像素值减均值除方差得到该点的像素值,此过程就是BN。最后将其接入到激活函数中。 (其中,Xi是指一批数据的同一个通道的所有特征图的数据,如下图X1就是指两张彩图的R通道的所有数据)

上述公式中,xi经过减均值,除方差之后,得到的数据的均值为0,方差为1,而后面的γ和β参数的作用又是什么呢?有时均值为0,方差为1并不是最好的效果,所以可以用通过γ调整数据的方差,通过β调整数据的均值。

介绍完BN层的原理,下面我们来看看具体的实例吧: feature map1、feature map2分别是由image1、image2经过一系列卷积池化后得到的特征矩阵。其中每个网格的值代表该点的像素值,分别统计feature map1 和feature map2每个通道的像素值,得到一个矩阵,在使用BN的计算公式计算经过BN以后,得到每个通道每个像素点的像素值。计算公式也如下。 [注]: (1)训练时要将traning参数设置为True,在验证时将trainning参数设置为False。在pytorch中可通过创建 模型的model.train()和model.eval()方法控制。 (2)batch size尽可能设置大点,设置小后表现可能很糟糕,设置的越大求的均值和方差越接近整个训练集的均值和方差。 (3)一般将bn层放在卷积层(Conv)和激活层(例如Relu)之间,且卷积层不要使用偏置bias,因为使用偏置和不使用偏置的yi是相等的,所以使用偏置只会徒增网络的参数,导致训练起来更加的费劲。

标准化(standardization):将数据通过去均值实现中心化的处理,根据凸优化理论与数据概率分布相关知识,数据中心化符合数据分布规律,更容易取得训练之后的泛化效果, 数据标准化是数据预处理的常见方法之一,缩放和每个点都有关系,通过方差(variance)体现出来。与归一化对比,标准化中所有数据点都有贡献(通过均值和标准差造成影响)。加速模型收敛:标准化后,最优解的寻优过程明显会变得平缓,更容易正确的收敛到最优解。 归一化(Normalization):归一化的目标是找到某种映射关系,将原数据映射到(a,b)区间上,如0~1之间,缩放仅仅跟最大、最小值的差别有关。提升模型精度:归一化后,不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性。

**

Resnet50总体结构

:** Resnet网络就是残差块的堆叠,解决了网络退化问题,实现网络层数的加深,使之拥有足够好的特征提取能力。

补充: Resnet解决网络退化的原理: 1.深度梯度回传顺畅:恒等映射这一路的梯度是1,可以把浅层的信号传到深层,也可以把深层的梯度注回浅层,防止梯度消失。 2.传统线性结构网络难以拟合“恒等映射”:什么都不做时很重要;skip connection可以让模型自行选择要不要更新;弥补了高度线性造成的不可逆的信息损失。 3.图像相邻像素梯度的局部相关性:解决了传统多层卷积造成的,回传的相邻像素梯度的局部相关性越来越低的问题。

二、Resnet50代码复现

完整代码

代码如下(示例):

import torch.nn as nnimport torch# Resnet 18/34使用此残差块class BasicBlock(nn.Module): # 卷积2层,F(X)和X的维度相等 # expansion是F(X)相对X维度拓展的倍数 expansion = 1 # 残差映射F(X)的维度有没有发生变化,1表示没有变化,downsample=None # in_channel输入特征矩阵的深度(图像通道数,如输入层有RGB三个分量,使得输入特征矩阵的深度是3),out_channel输出特征矩阵的深度(卷积核个数),stride卷积步长,downsample是用来将残差数据和卷积数据的shape变的相同,可以直接进行相加操作。 def __init__(self, in_channel, out_channel, stride=1, downsample=None, **kwargs): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(out_channel) # BN层在conv和relu层之间 self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(out_channel) self.relu = nn.ReLU(inplace=True) self.downsample = downsample def forward(self, x): identity = x if self.downsample is not None: identity = self.downsample(x) out = self.conv1(x) out = self.bn1(out) out = self.relu(out) out = self.conv2(out) out = self.bn2(out) # out=F(X)+X out += identity out = self.relu(out) return out# Resnet 50/101/152使用此残差块class Bottleneck(nn.Module): # 卷积3层,F(X)和X的维度不等 """ 注意:原论文中,在虚线残差结构的主分支上,第一个1x1卷积层的步距是2,第二个3x3卷积层步距是1。 但在pytorch官方实现过程中是第一个1x1卷积层的步距是1,第二个3x3卷积层步距是2, 这么做的好处是能够在top1上提升大概0.5%的准确率。 """ # expansion是F(X)相对X维度拓展的倍数 expansion = 4 def __init__(self, in_channel, out_channel, stride=1, downsample=None, groups=1, width_per_group=64): super(Bottleneck, self).__init__() width = int(out_channel * (width_per_group / 64.)) * groups # 此处width=out_channel self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=width,kernel_size=1, stride=1, bias=False) # squeeze channels self.bn1 = nn.BatchNorm2d(width) # ----------------------------------------- self.conv2 = nn.Conv2d(in_channels=width, out_channels=width, groups=groups,kernel_size=3, stride=stride, bias=False, padding=1) self.bn2 = nn.BatchNorm2d(width) # ----------------------------------------- self.conv3 = nn.Conv2d(in_channels=width, out_channels=out_channel * self.expansion,kernel_size=1, stride=1, bias=False) # unsqueeze channels self.bn3 = nn.BatchNorm2d(out_channel * self.expansion) self.relu = nn.ReLU(inplace=True) self.downsample = downsample def forward(self, x): identity = x # downsample是用来将残差数据和卷积数据的shape变的相同,可以直接进行相加操作。 if self.downsample is not None: identity = self.downsample(x) out = self.conv1(x) out = self.bn1(out) out = self.relu(out) out = self.conv2(out) out = self.bn2(out) out = self.relu(out) out = self.conv3(out) out = self.bn3(out) # out=F(X)+X out += identity out = self.relu(out) return outclass ResNet(nn.Module): def __init__(self, block, # 使用的残差块类型 blocks_num, # 每个卷积层,使用残差块的个数 num_classes=1000, # 训练集标签的分类个数 include_top=True, # 是否在残差结构后接上pooling、fc、softmax groups=1, width_per_group=64): super(ResNet, self).__init__() self.include_top = include_top self.in_channel = 64 # 第一层卷积输出特征矩阵的深度,也是后面层输入特征矩阵的深度 self.groups = groups self.width_per_group = width_per_group # 输入层有RGB三个分量,使得输入特征矩阵的深度是3 self.conv1 = nn.Conv2d(3, self.in_channel, kernel_size=7, stride=2,padding=3, bias=False) self.bn1 = nn.BatchNorm2d(self.in_channel) self.relu = nn.ReLU(inplace=True) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) # _make_layer(残差块类型,残差块中第一个卷积层的卷积核个数,残差块个数,残差块中卷积步长)函数:生成多个连续的残差块的残差结构 self.layer1 = self._make_layer(block, 64, blocks_num[0]) self.layer2 = self._make_layer(block, 128, blocks_num[1], stride=2) self.layer3 = self._make_layer(block, 256, blocks_num[2], stride=2) self.layer4 = self._make_layer(block, 512, blocks_num[3], stride=2) if self.include_top: # 默认为True,接上pooling、fc、softmax self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) # 自适应平均池化下采样,无论输入矩阵的shape为多少,output size均为的高宽均为1x1 # 使矩阵展平为向量,如(W,H,C)->(1,1,W*H*C),深度为W*H*C self.fc = nn.Linear(512 * block.expansion, num_classes) # 全连接层,512 * block.expansion为输入深度,num_classes为分类类别个数 for m in self.modules(): # 初始化 if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') # _make_layer()函数:生成多个连续的残差块,(残差块类型,残差块中第一个卷积层的卷积核个数,残差块个数,残差块中卷积步长) def _make_layer(self, block, channel, block_num, stride=1): downsample = None # 寻找:卷积步长不为1或深度扩张有变化,导致F(X)与X的shape不同的残差块,就要对X定义下采样函数,使之shape相同 if stride != 1 or self.in_channel != channel * block.expansion: downsample = nn.Sequential( nn.Conv2d(self.in_channel, channel * block.expansion, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(channel * block.expansion)) # layers用于顺序储存各连续残差块 # 每个残差结构,第一个残差块均为需要对X下采样的残差块,后面的残差块不需要对X下采样 layers = [] # 添加第一个残差块,第一个残差块均为需要对X下采样的残差块 layers.append(block(self.in_channel, channel, downsample=downsample, stride=stride, groups=self.groups, width_per_group=self.width_per_group)) self.in_channel = channel * block.expansion # 后面的残差块不需要对X下采样 for _ in range(1, block_num): layers.append(block(self.in_channel, channel, groups=self.groups, width_per_group=self.width_per_group)) # 以非关键字参数形式,将layers列表,传入Sequential(),使其中残差块串联为一个残差结构 return nn.Sequential(*layers) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) if self.include_top: # 一般为True x = self.avgpool(x) x = torch.flatten(x, 1) x = self.fc(x) return x# 至此resnet的基本框架就写好了# ——————————————————————————————————————————————————————————————————————————————————# 下面定义不同层的resnetdef resnet50(num_classes=1000, include_top=True): # https://download.pytorch.org/models/resnet50-19c8e357.pth return ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)def resnet34(num_classes=1000, include_top=True): # https://download.pytorch.org/models/resnet34-333f7ec4.pth return ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)def resnet101(num_classes=1000, include_top=True): # https://download.pytorch.org/models/resnet101-5d3b4d8f.pth return ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes, include_top=include_top)def resnext50_32x4d(num_classes=1000, include_top=True): # https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth groups = 32 width_per_group = 4 return ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top, groups=groups, width_per_group=width_per_group)def resnext101_32x8d(num_classes=1000, include_top=True): # https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth groups = 32 width_per_group = 8 return ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes, include_top=include_top, groups=groups, width_per_group=width_per_group)
本文链接地址:https://www.jiuchutong.com/zhishi/300707.html 转载请保留说明!

上一篇:多智能体强化学习—QMIX(多智能体概念)

下一篇:css添加边框阴影(css添加边框阴影 立体效果)

  • 钉钉打卡在哪里打(钉钉打卡怎样在家里打)

    钉钉打卡在哪里打(钉钉打卡怎样在家里打)

  • 小米mix4防水级别(小米mix4防水么)

    小米mix4防水级别(小米mix4防水么)

  • 电脑怎么强行结束应用(电脑怎么强行结束一个任务)

    电脑怎么强行结束应用(电脑怎么强行结束一个任务)

  • qq自动回复可以维持多久(qq自动回复可以不对某些人发吗)

    qq自动回复可以维持多久(qq自动回复可以不对某些人发吗)

  • iphone11怎么清理内存(iphone11怎么清理喇叭灰尘)

    iphone11怎么清理内存(iphone11怎么清理喇叭灰尘)

  • 手机卡仅限紧急呼叫怎么回事(手机卡仅限紧急呼叫是被注销了吗)

    手机卡仅限紧急呼叫怎么回事(手机卡仅限紧急呼叫是被注销了吗)

  • 苹果耳机音量自动减小到无(苹果耳机音量自动减小到无怎么设置)

    苹果耳机音量自动减小到无(苹果耳机音量自动减小到无怎么设置)

  • 手机强制关机怎么关(手机强制关机怎么设置)

    手机强制关机怎么关(手机强制关机怎么设置)

  • 华为电源键在哪里(华为手机电源键在哪里)

    华为电源键在哪里(华为手机电源键在哪里)

  • 如果设置了仅聊天,对方显示的是什么(如果设置了仅聊天,对方还能看到我的朋友圈吗)

    如果设置了仅聊天,对方显示的是什么(如果设置了仅聊天,对方还能看到我的朋友圈吗)

  • qq标识有哪些(qq上的标识有哪几种)

    qq标识有哪些(qq上的标识有哪几种)

  • ip前三段一致说明什么问题(ip前两段代表什么意思)

    ip前三段一致说明什么问题(ip前两段代表什么意思)

  • 短信一点开就退出了什么意思(为什么打开短信以后信息就直接退出)

    短信一点开就退出了什么意思(为什么打开短信以后信息就直接退出)

  • itunes能在安卓手机上下载吗(itunes能在安卓用吗)

    itunes能在安卓手机上下载吗(itunes能在安卓用吗)

  • 优酷怎么缓存视频(优酷里面怎么缓存视频)

    优酷怎么缓存视频(优酷里面怎么缓存视频)

  • 抖音每天点赞上限是多少(抖音每天点赞上限是多少个赞)

    抖音每天点赞上限是多少(抖音每天点赞上限是多少个赞)

  • 哔哩哔哩怎么下载视频到手机相册(哔哩哔哩怎么分享完整视频)

    哔哩哔哩怎么下载视频到手机相册(哔哩哔哩怎么分享完整视频)

  • 文本文件可以直接在word中处理吗(文本文件可以压缩吗)

    文本文件可以直接在word中处理吗(文本文件可以压缩吗)

  • huawei share关不掉(huawei share没反应)

    huawei share关不掉(huawei share没反应)

  • 三星s10能贴膜吗(三星s10自带贴膜可以撕掉吗)

    三星s10能贴膜吗(三星s10自带贴膜可以撕掉吗)

  • 红米pro备忘录在哪里(redmi备忘录在哪)

    红米pro备忘录在哪里(redmi备忘录在哪)

  • 云盘在什么地方(云盘存储在什么地方)

    云盘在什么地方(云盘存储在什么地方)

  • 无线宝箱授权安全吗(淘宝无线宝箱授权怎样查看)

    无线宝箱授权安全吗(淘宝无线宝箱授权怎样查看)

  • 苹果x支持多少w快充(苹果X支持多少瓦快充)

    苹果x支持多少w快充(苹果X支持多少瓦快充)

  • 穿越视频怎么拍(穿越视频怎么拍摄)

    穿越视频怎么拍(穿越视频怎么拍摄)

  • y85怎样设置返回键(vivoy85a手机怎么设置返回键在屏幕上)

    y85怎样设置返回键(vivoy85a手机怎么设置返回键在屏幕上)

  •   ipad什么时候上市的(ipad什么时候上的高刷)

    ipad什么时候上市的(ipad什么时候上的高刷)

  • 电脑怎么设置QQ有消息自动弹出(电脑怎么设置qq下载的文件的位置)

    电脑怎么设置QQ有消息自动弹出(电脑怎么设置qq下载的文件的位置)

  • phpcms html不可写怎么办(php写在html里不行)

    phpcms html不可写怎么办(php写在html里不行)

  • 个税系统更正申报可以更正几次
  • 房地产增值税预缴规定
  • 交强险必须交车船使用税吗?交多少钱?
  • 旧机器设备出口
  • 印花税退税减半征收会计分录怎么写?
  • 税控盘为什么要年年交服务费
  • 开具电费发票如何入账?
  • 有限合伙企业属于什么经济类型
  • 多计提个税怎么办
  • 列支会议费要求
  • 没有抵扣怎么办
  • 二手设备进口海关
  • 专票当月抵扣后当月作废会被发现吗
  • 存货盘亏怎么做账务处理
  • 装修计入固定资产
  • 有票据的福利费是不需要职工薪酬科目过渡吗
  • 出口退税附加税什么时候缴纳
  • 水利建设基金2021
  • 继承或赠与所得的房产
  • 借款利息不能抵扣进项税
  • 开红字冲红发票 下个月怎么申报
  • 实物福利计入工资总额
  • 鸿蒙系统通知栏和控制
  • 王者荣耀百里守约是男是女
  • 劳务派遣发票备注栏要求
  • 经营负债是指什么
  • Linux系统中Squid代理服务器配置全过程解析
  • 如何取消windows启动管理器
  • 住房公积金余额查询
  • 以太网默认网关怎么查看
  • 房地产销售未完工产品收入是含税的吗
  • 哪些费用可以用医保
  • 工会经费税前扣除标准2022
  • 固定资产后续支出资本化和费用化
  • php foreach二维数组
  • 镶嵌在巨石之间的英文
  • axios有哪些常用方法
  • 数据挖掘论文选题
  • 增值税发票认证不了怎么回事
  • 购销合同印花税税率
  • 水利建设基金的计费方式
  • 三栏式明细账需要每笔结余额吗
  • 企业缴纳水利建设基金的依据是什么
  • php怎么修改当前用户的密码
  • vuex 3
  • 银行不良资产核销后怎么处理
  • 必要报酬率和期望报酬率谁大更好
  • 专用红字发票如何开具
  • 事业单位会计的特点
  • 固定资产没有发票
  • 其他综合收益的二级科目有哪些
  • 日常生活中各种形式的能量的转化
  • 核定征收需要什么资料
  • 企业筹建期的开办费后期怎么算
  • 企业一般用什么系统
  • 怎么做好出纳帐
  • 什么是结账?结账前要做哪些准备工作?
  • window10节电模式怎么关闭
  • linux系统软件包安装
  • mac 8g 虚拟机
  • 使用iso镜像文件
  • win7 64位打开软件时显示丢失wpcap.dll的三种解决办法
  • 进入Linux单用户模式
  • cocos2d游戏源码
  • Python Flask-web表单使用详解
  • android 退出app
  • jquery设置文本字体样式
  • gridview行数
  • jquery使用教程
  • js拖动效果
  • python 字典怎么添加数据
  • 专项调查法
  • 党建阵地作用发挥不好
  • 单位自有住房免增值税吗
  • 网上申报纳税小程序是啥
  • 在网上缴费后如何退款
  • 小微企业所得税优惠政策最新2023
  • 如何查询医院是否有怀孕建档名额
  • 烟叶进口关税
  • 财税相关书籍
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设