庖丁解牛-Resnet50 深度剖析,细致讲解,深入理解

2023-11-01

背景介绍

ResNet-50侧边输出形状
假设输入为352,则
output2 = 256x88x88
output3 = 512x44x44
output4 = 1024x22x22
output5 = 2048x11x11

VGG-16侧边输出形状
假设输入为352,则
output1 = 64x320x320

output2 = 128x160x160
output3 = 256x88x88
output4 = 512x44x44
output5 = 512x22x22

请看50-layer这一列
是本文介绍的层的结构:

resnet-50
有四组大block
每组分别是3, 4, 6, 3个小block
每个小block里面有三个卷积
另外这个网络的最开始有一个单独的卷积层,
因此是:(3+4+6+3)*3+1=49
最后又一个全连接层,因而一共50层

如下图,每个大block里面的
第一个都是IN !==OUT情况,侧支线,命名为:Conv Block
其他都是    IN  ==OUT情况,侧支线,   命名为:ID      Block
3 = +右+右
4 = +右+右+右
6 = +右+右+右+右+右
3 = +右+右

0 特征图尺寸计算

1 卷积层计算: N = (W-F+2P)/2 + 1
F 卷积核
S 步长
P Padding

2 池化层计算: N = (W-F)/s + 1
F 卷积核
S 步长
P Padding


3 当尺寸不被整除时
卷积向下取整,池化向上取整。
本题中 (200-5+2*1)/2+1 为99.5,取99
(99-3)/1+1 为97
(97-3+2*1)/1+1 为97
 
卷积前后尺寸不变情况: 当stride为1的时候,当kernel为 3 padding为1或者kernel为5 padding为2 ,卷积前后尺寸不变。

1 resnet用skip-connection规避梯度消失问题

梯度消失:反向传递到浅层的时候,gradient会小到接近0,
导致学习效率低,parameters更新越来越慢

多个Resnet Blocks累积起来能解决梯度消失问题。
Resnet Block = main path  +  skip connection

2 ResNet有2个基本的block:

Identity Block: 输入和输出的dimension是一样的,    所以可以串联多个;
串联多个,
可直接相加,
维度不变(input shape = output shape)
Conv Block:      输入和输出的dimension是不一样的,所以不能连续串联,它的作用本来就是为了改变特征向量的dimension
不能连续串联,
在skip connection里面加入了conv2d layer, 以让维度相等然后相加
改变维度 (input shape != output shape)

因为CNN最后都是要把输入图像一点点的转换成很小但是depth很深的feature map,
一般的套路是用统一的比较小的kernel(比如VGG都是用3*3),
但是随着网络深度的增加,output的channel也增大(学到的东西越来越复杂),
所以有必要在进入Identity Block之前,用Conv Block转换一下维度,这样后面就可以连续接Identity Block.

Identity Block:

Conv Block: 

Conv Block 的不同之处在于:
其实就是在shortcut path的地方加上一个conv2D layer(1*1 filter size),
然后在main path改变dimension,并与shortcut path对应起来.

3 如何搭建一个跨越三层的Conv Block

1 main path
第一: Conv-BatchNorm-ReLU block
conv2d: filter=F1, kernel_size=1, stride=s, padding=valid
output shape变小
起名,random seed=0, BatchNorm axis=3 貌似是tf keras的

第二: Conv-BatchNorm-ReLU block
conv2d: filter=F2, kernel_size=f, stride=1, padding=same
output shape不变
起名,random seed=0, BatchNorm axis=3 貌似是tf keras的

第三: Conv-BatchNorm-ReLU block
conv2d: filter=F3, kernel_size=1, stride=1, padding=valid
output shape不变
得到最终的X_output

2 skip-connection
Conv-BatchNorm block
conv2d: filter=F3, kernel_size=1, stride=s, padding=valid 
shape与X_output一致
axis=3
返回X_skip

3 X_skip + X_output 通过ReLU函数

4 如何搭建一个跨越三层Identity Block


1 main path
第一: Conv-BatchNorm-ReLU block
conv2d: kernel_size=1, stride=1, padding=valid
output shape不变
起名,random seed=0, BatchNorm axis=3 貌似是tf keras的

第二: Conv-BatchNorm-ReLU block
conv2d: kernel_size=f, stride=1, padding=same
output shape不变
起名,random seed=0, BatchNorm axis=3 貌似是tf keras的

第三: Conv-BatchNorm block
conv2d: 同第一
output shape不变
得到最终的X_output

2 skip-connection

3 X_identity = X + X_output 通过ReLU函数

4 整体结构:


zera-padding:
(3x3)上下左右各添加3像素

stage1:
Conv:             filters=64, kernel_size=7x7, stride=2x2
BatchNorm: 
RELU:
MaxPooling:  windows=3x3, stride=2x2

stage2:
1xConv Block: named a

3set: [64, 64, 256], k_s=3x3, stride=1x1
2xID Block: named b,c
3set: [64, 64, 256], k_s=3x3,

stage3:
1xConv Block: named a

3set: [128, 128, 512], k_s=3x3, stride=2x2
3xID Block: named b,c,d
3set: [128, 128, 512], k_s=3x3

stage4:
1xConv Block: named a

3set: [256, 256, 1024], k_s=3x3, stride=2x2
5xID Block: named b,c,d,e,f
3set: [256, 256, 1024], k_s=3x3

stage5:
1xConv Block: named a

3set: [512, 512, 2048], k_s=3x3, stride=2x2
2xID Block: named b,c
3set: [512, 512, 2048], k_s=3x3

Average Pooling: named avg_pool
windows=(2x2)
Flatten:
Fully Connected(Dense) layer:
named 'fc'

5 resnet50文字详解

block_sizes=[3, 4, 6, 3]指的是stage1(first pool)之后的4个layer的block数, 分别对应res2,res3,res4,res5,
    每一个layer的第一个block在shortcut上做conv+BN, 即Conv Block
inputs: (1, 720, 1280, 3)
initial_conv:
    conv2d_fixed_padding()
    1. kernel_size=7, 先做padding(1, 720, 1280, 3) -> (1, 726, 1286, 3)
    2. conv2d kernels=[7, 7, 3, 64], stride=2, VALID 卷积. 7x7的kernel, padding都为3, 为了保证左上角和卷积核中心点对其
       (1, 726, 1286, 3) -> (1, 360, 640, 64)
    3. BN, Relu (只有resnetv1在第一次conv后面做BN和Relu)
initial_max_pool:
    k=3, s=2, padding='SAME', (1, 360, 640, 64) -> (1, 180, 320, 64)
以下均为不使用bottleneck的building_block
block_layer1:
    (有3个block, layer间stride=1(上一层做pool了), 64个filter, 不使用bottleneck(若使用bottleneck 卷积核数量需乘4))
    1. 第一个block:
    Conv Block有projection_shortcut, 且strides可以等于1或者2
    Identity Block没有projection_shortcut, 且strides只能等于1
        `inputs = block_fn(inputs, filters, training, projection_shortcut, strides, data_format)`
        shortcut做[1, 1, 64, 64], stride=1的conv和BN, shape不变
        然后和主要分支里input做3次卷积后的结果相加, 一起Relu, 注意block里最后一次卷积后只有BN没有Relu
        input:    conv-bn-relu-conv-bn-relu-conv-bn  和shortcut相加后再做relu
        shortcut: conv-bn                            
        shortcut: [1, 1, 64, 64], s=1, (1, 180, 320, 64) -> (1, 180, 320, 64)
        input做两次[3, 3, 64, 64], s=1的卷积, shape不变(1, 180, 320, 64) -> (1, 180, 320, 64) -> (1, 180, 320, 64)
        inputs += shortcut, 再relu
    2. 对剩下的2个block, 每个block操作相同:
        `inputs = block_fn(inputs, filters, training, None, 1, data_format)`
        shortcut直接和input卷积结果相加, 不做conv-bn
        input做两次[3, 3, 64, 64], s=1的卷积, shape不变(1, 180, 320, 64) -> (1, 180, 320, 64) -> (1, 180, 320, 64)
        inputs += shortcut, 再relu
block_layer2/3/4同block_layer1, 只是每个layer的identity block数量不同, 卷积核数量和layer间stride也不同, 不过仍然只有第一个conv block的shortcut做conv-bn
block_layer2: 4个block, 128个filter, layer间stride=2 (因为上一层出来后没有pool)
    1. 第一个block:
        对shortcut做kernel=[1, 1, 64, 128], s=2的conv和BN, (1, 180, 320, 64) -> (1, 90, 160, 128)
        对主要分支先做kernel=[3, 3, 64, 128], s=2的卷积, padding='VALID', (1, 180, 320, 64) -> (1, 90, 160, 128)
                再做kernel=[3, 3, 128, 128], s=1的卷积, padding='SAME', (1, 90, 160, 128) -> (1, 90, 160, 128)
    2. 剩下的3个block, 每个block操作相同:
        shortcut不操作直接和结果相加做Relu
        对主要分支做两次[3, 3, 128, 128], s=1的卷积, padding='SAME', (1, 90, 160, 128) -> (1, 90, 160, 128) -> (1, 90, 160, 128)
block_layer3: 6个block, 256个filter, layer间stride=2
    1. 第一个block:
        对shortcut做kernel=[1, 1, 128, 256], s=2的conv和BN, (1, 90, 160, 128) -> (1, 45, 80, 256)
        对主要分支先做kernel=[3, 3, 128, 256], s=2的卷积, padding='VALID', (1, 90, 160, 128) -> (1, 45, 80, 256)
                再做kernel=[3, 3, 256, 256], s=1的卷积, padding='SAME', (1, 45, 80, 256) -> (1, 45, 80, 256)
    2. 剩下的5个block, 每个block操作相同:
        shortcut不操作直接和结果相加做Relu
        对主要分支做两次[3, 3, 256, 256], s=1的卷积, padding='SAME', (1, 45, 80, 256) -> (1, 45, 80, 256) -> (1, 45, 80, 256)
block_layer4: 3个block, 512个filter, layer间stride=2
    1. 第一个block:
        对shortcut做kernel=[1, 1, 256, 512], s=2的conv和BN, (1, 45, 80, 256) -> (1, 23, 40, 512)
        对主要分支先做kernel=[3, 3, 256, 512], s=2的卷积, padding='VALID', (1, 45, 80, 256) -> (1, 23, 40, 512)
                再做kernel=[3, 3, 512, 512], s=1的卷积, padding='SAME', (1, 23, 40, 512) -> (1, 23, 40, 512)
    2. 剩下的2个block, 每个block操作相同:
        shortcut不操作直接和结果相加做Relu
        对主要分支做两次[3, 3, 512, 512], s=1的卷积, padding='SAME', (1, 23, 40, 512) -> (1, 23, 40, 512)
avg_pool, 7*7
FC, output1000
softmax
输出prediction

6 resnet50图解


 

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

庖丁解牛-Resnet50 深度剖析,细致讲解,深入理解 的相关文章

  • C++ primer 第十一章习题

    chapter11 关联容器 文章目录 chapter11 关联容器 练习 11 1 节练习 练习11 1 练习11 2 练习11 3 练习11 4 11 2 1 节练习 练习11 5 练习11 6 练习11 7 练习11 8 11 2 2

随机推荐

  • 脏牛提权(cve-2016-5159)

    漏洞范围 大于2 6 22版本 2007年发行 到2016年10月18日修复 危害 低权限的用户可利用这一漏洞在本地进行提权 原理 linux内核的子系统在处理写入时复制至产生了竞争条件 恶意用户可利用此漏洞来获取高权限 对只读内存映射进行
  • 如何快速选择开源许可证License,看这三个就够了

    开源License很多 如果你不想在License耗费太多精力 那么推荐你重点了解这三种 GPL Apache License及MIT 这三种在开源License中很具代表性 使用广泛 且简洁易理解 同时 这三种license是经过OSI
  • MySQL数据库学习

    目录 从管理员cmd页面打开数据库 创建一个用户 数据库的基本操作 数据完整性 完整性约束管理 表的基本操作 判断关键字 聚合函数 多表连接查询 嵌套查询 联合查询 事务 锁 索引 视图 存储过程 函数 与存储过程类似 光标 触发器 JAV
  • lazarus调用http接口解析json(迎接云计算适应微服务)

    lazarus 跨平台free pascal语言ide工具 社区 http www fpccn com 下载 ftp freepascal dfmk hu pub lazarus 号称一次编码 到处编译 window linux macos
  • 制造业数据治理白皮书(2022版)

    全书基于双方赋能一线制造业企业数字化转型过程的实操践行 经验沉淀和所感所悟 分别从背景及趋势 现状与挑战 实施途径 典型案例等角度揭示了当下制造业数据治理的重要性 关注公众号 互联互通社区 回复 DATA176 获取全部报告内容 精彩推荐
  • ES集群宕机后处理——重新分配shards,负载均衡

    ES集群5台机器 由于同时读写导致其中一台机器宕机 原本每天的索引shard数设定为10 这样5台机器每台分配2个shard 但是一旦集群宕机 重启集群后 5号机器宕机导致它上面的shard会转移到其他1 4号机器上 如果此时往ES里写数据
  • UE4_DatatTable数据保存

    UE4 提供了很多数据持久的工具 很多 1 2 3 网上使用UE4 c 操作DataTable的也很多 不接入别人的链接了 使用C 操作DataTable修改数据也没啥大的问题 坑爹的地方 修改完数据之后 重启编辑器之后 修改的数据恢复之前
  • 线性、非线性分类器&数据的线性、非线性

    线性 非线性分类器 数据的线性 非线性 一 线性分类器 有无数个可划分这两个线性可分类的超平面 在二维空间里面 一个线性分类器是一条线 图14 8展示了五个分类例子 这些线有一个函数形式w1x1 w2 x2 b 线性分类器的分类规则是 如果
  • Unity如何使用手机进行调试(真机)

    文章目录 手机操作 具体步骤 Unity操作 错误处理 没有检测到手机 手机操作 首先打开手机的 USB调试 开关 具体步骤 这里以华为手机举例 手机的系统是EMUI10 具体操作如下 首先打开手机 gt 进入 设置 找到 关于手机 连续点
  • linux内核模块作用,Linux内核模块(二)

    ko kernel object so shared object root rhel6 ls lib modules uname r kernel arch x86 kvm kvm amd ko kvm intel ko kvm ko 通
  • 强化学习奖励和状态设计

    奖励 1 稀疏奖励问题 2 奖励模式化问题 3 奖励不能太过于全局化 4 记住一些常用的奖励设置方式 5 逆向强化学习自动涉及回报函数 6 避免奖励异常问题 贪婪 来回踱步 胆怯 不敢走 主线奖励太小 鲁莽 惩罚不够 7 采用reward
  • Excel文件导出总结,包含大数据量的分批导出方式

    文章目录 更新记录 需求背景 参考内容 导出方式 代码实现 Excel4J 普通导出 POI原生方式 普通导出 大数据量分批导出 2023 08更新 实际应用记录 依赖版本 实现思路 POI工具类 数据写入 调用测试 测试结果 一个小意外
  • 云原生Kubernetes:K8S实用插件和工具

    目录 一 理论 1 Kubectl插件 2 kubens 3 krew 二 实验 1 kubectl插件 2 kubens 3 krew 一 理论 1 kubectl插件 1 概念 kubectl插件其实就是以kubectl 为前缀的任意可
  • 最喜欢的科技资讯类英文网站

    最喜欢的科技资讯类英文网站 1 手机类 http www phonearena com 喜欢原因 全球主要机型的手机都有罗列 新闻更新速度非常之快 上市未上市机型都能涵盖 2 计算机类 http www computerworld com
  • 史上最简单的SpringCloud教程

    在上一篇文章 讲了服务的注册和发现 在微服务架构中 业务都会被拆分成一个独立的服务 服务与服务的通讯是基于http restful的 Spring cloud有两种服务调用方式 一种是ribbon restTemplate 另一种是feig
  • C语言———打印100—200之间的素数并统计素数个数的三种写法

    素数 除了1和它本身以外再无其他因子 1 试除法 判断i是否时素数 则用2 gt i 1个数去整除i 若可以整除 则说明i不是素数 int main int i 0 用i记录100 200之间的数 int count 0 用count统计1
  • Java架构直通车——点赞功能用Mysql还是Redis?

    文章目录 引入 使用Mysql实现点赞功能 使用Redis实现点赞功能 使用什么数据格式最合适 方案 引入 最近遇到一个需求 就是做联盟链做存证上 部分交易对外公开 或者是对指定人可见 之前一直在思考用Mysql怎么存合适 想来想去也没找出
  • js表达式的结果

    delete 1 return true delete return true 将0和 看作一个表达式 并尝试删除它的求值结果 x 1 delete x return true var a name csdn delete a name r
  • kettle中null值的处理方式

    今天在用kettle对mysql插入空值 时 发现对空值的处理在插入mysql时 会自动转转换为null值 在网上找一下 需要在kettle properties文件中添加如下参数 就不会自动转换了 windows下文件的位置 C User
  • 庖丁解牛-Resnet50 深度剖析,细致讲解,深入理解

    背景介绍 ResNet 50侧边输出形状 假设输入为352 则 output2 256x88x88 output3 512x44x44 output4 1024x22x22 output5 2048x11x11 VGG 16侧边输出形状 假