ResNet(Residual Neural Network),微软研究院 Kaiming He等4名华人提出。通过Residual Unit训练152层深神经网络,ILSVRC 2015比赛冠军,3.57% top-5错误率,参数量比VGGNet低,效果非常突出。ResNet结构,极快加速超深神经网络训练,模型准确率非常大提升。Inception V4,Inception Module、ResNet结合。ResNet推广性好。

瑞十教授Schmidhuber(LSTM网络发明者,1997年)提出Highway Network。解决极深神经网络难训练问题。修改每层激活函数,此前激活函数只是对输入非线性变换y=H(x,WH),Highway NetWork保留一定比例原始输入x,y=H(x,WH)·T(x,WT)+x·C(x,WC),T变换系数,C保留系数,令C=1-T。前面一层信息,一定比例不经过矩阵乘法和非线性变换,直接传输下一层。Highway Network,gating units学习控制网络信息流,学习原始信息应保留比例。gating机制,Schmidhuber教授早年LSTM循环神经网络gating。几百上千层深Highway Network,直接梯度下降算法训练,配合多种非线性激活函数,学习极深神经网络。Highway Network允许训练任意深度网络,优化方法与网络深度独立。

ResNet 允许原始输入信息直接传输到后层。Degradation问题,不断加深神经网络深度,准确率先上升达到饱和,再下降。ResNet灵感,用全等映射直接将前层输出传到后层。神经网络输入x,期望输出H(x),输入x直接传到输出作初始结果,学习目标F(x)=H(x)-x。ResNet残差学习单元(Residual Unit),不再学习完整输出H(x),只学习输出输入差别H(x)-x,残差。

ResNet,很多旁路支线,输入直接连到后层,后层直接学习残差,shortcut或connections。直接将输入信息绕道传到输出,保护信息完整性,整个网络只学习输入、输出差别,简化学习目标、难度。

两层残新式学习单元包含两个相同输出通道数3x3卷积。三层残差网络用Network In Network和Inception Net 1x1卷积。在中间3x3卷积前后都用1x1卷积,先降维再升维。如果输入输出维度不同,对输入x线性映射变换维度,再接后层。

layername outputsize 18-layer 34-layer 50-layer 101-layer 152-layer
conv1 112x112 7x7,64,stride 2
conv2_x 56x56 3x3 max pool,stride 2
3x3,64x2 3x3,64x3 1x1,64x3 1x1,64x3 1x1,64x3
3x3,64 3x3,64 3x3,64 3x3,64 3x3,64
1x1,256 1x1,256 1x1,256
conv3_x 28x28 3x3,128x2 3x3,128x4 1x1,128x4 1x1,128x4 1x1,128x8
3x3,128 3x3,128 3x3,128 3x3,128 3x3,128
1x1,512 1x1,512 1x1,512
conv4_x 14x14 3x3,256x2 3x3,256x6 1x1,256x6 1x1,256x23 1x1,256x36
3x3,256 3x3,256 3x3,256 3x3,256 3x3,256
1x1,1024 1x1,1024 1x1,1024
conv5_x 7x7 3x3,512x2 3x3,512x3 1x1,512x3 1x1,512x3 1x1,512x3
3x3,512 3x3,512 3x3,512 3x3,512 3x3,512
1x1,2048 1x1,2048 1x1,2048
1x1 average pool,1000-d fc,softmax
FLOPs 1.8x10^9 3.6x10^9 3.8x10^9 7.6x10^9 11.3x10^9

ResNet结构,消除层数不断加深训练集误差增大现象。ResNet网络训练误差随层数增大逐渐减小,测试集表现变好。Google借鉴ResNet,提出Inception V4和Inception-ResNet-V2,ILSVRC错误率3.08%。《Identyty Mappings in Deep Residual Networks》提出ResNet V2。ResNet残差学习单元传播公式,前馈信息和反馈信号可直接传输。skip connection 非线性激活函数,替换Identity Mappings(y=x)。ResNet每层都用Batch Normalization。

Schmidhuber教授,ResNet,没有gates LSTM网络,输入x传递到后层过程一直发生。ResNet等价RNN,ResNet类似多层网络间集成方法(ensemble)。

《The Power of Depth for Feedforward Neural Networks》,理论证明加深网络比加宽网络更有效。

Tensorflow实现ResNet。contrib.slim库,原生collections。collections.namedtuple设计ResNet基本Block模块组named tuple,创建Block类,只有数据结构,没有具体方法。典型Block,三个参数,scope、unit_fn、args。
Block('block1', bottleneck, [(256, 64, 1)] * 2 + [(256, 64, 2)]),block1是Block名称(或scope),bottleneck是ResNet V2残差学习单元。最后参数是Block args,args是列表,每个元素对应bottleneck残差学习单元。前面两个元素(256, 64, 1),第三元素(256, 64, 2),每个元素都是三元tuple(depth,depth_bottleneck,stride)。(256, 64, 3)代表bottleneck残差学习单元(三个卷积层),第三层输出通道数depth 256,前两层输出通道数depth_bottleneck 64,中间层步长stride 3。残差学习单元结构[(1x1/s1,64),(3x3/s3,64),(1x1/s1,256)]。

降采样subsample方法,参数inputs(输入)、factor(采样因子)、scope。fator1,不做修改直接返回inputsx,不为1,用slim.max_pool2d最大池化实现。1x1池化尺寸,stride步长,实现降采样。

定义conv2d_same函数创建卷积层,如果stride为1,用slim.conv2d,padding模式SAME。stride不为1,显式pad zero。pad zero总数kernel_size-1 pad_beg为pad//2,pad_end为余下部分。tf.pad补零输入变量。已经zero padding,只需padding模式VALID的slim.conv2d创建此卷积层。

定义堆叠Blocks函数,参数net输入,blocks是Block class 列表。outputs_collections收集各end_points collections。两层循环,逐个Block,逐个Residual Unit堆叠。用两个tf.variable_scope命名残差学习单元block/unit_1形式。第2层循环,每个Block每个Residual Unit args,展开depth、depth_bottleneck、stride。unit_fn残差学习单元生成函数,顺序创建连接所有残差学习单元。slim.utils.collect_named_outputs函数,输出net添加到collection。所有Block所有Residual Unit堆叠完,返回最后net作stack_blocks_dense函数结果。

创建ResNet通用arg_scope,定义函数参数默认值。定义训练标记is_training默认True,权重衰减速度weight_decay默认0.001。BN衰减速率默认0.997,BN epsilon默认1e-5,BN scale默认True。先设置好BN各项参数,通过slim.arg_scope设置slim.conv2d默认参数,权重正则器设L2正则,权重初始化器设slim.variance_scaling_initializer(),激活函数设ReLU,标准化器设BN。最大池化padding模式默认设SAME(论文中用VALID),特征对齐更简单。多层嵌套arg_scope作结果返回。

定义核心bottleneck残差学习单元。ResNet V2论文Full Preactivation Residual Unit 变种。每层前都用Batch Normalization,输入preactivation,不在卷积进行激活函数处理。参数,inputs输入,depth、depth_bottleneck、stride,outputs_collections收集end_points collection,scope是unit名称。用slim.utils.last_dimension函数获取输入最后维度输出通道数,参数min_rank=4限定最少4个维度。slim.batch_norm 输入 Batch Normalization,用ReLU函数预激活Preactivate。

定义shorcut,直连x,如果残差单元输入通道数depth_in、输出通道数depth一致,用subsample,步长stride,inputs空间降采样,确保空间尺寸和残差一致,残差中间层卷积步长stride;如果不一致,用步长stride 1x1卷积改变通道数,变一致。

定义residual(残差),3层,1x1尺寸、步长1、输出通道数depth_bottleneck卷积,3x3尺寸、步长stride、输出通道数depth_bottleneck卷积,1x1尺寸、步长1、输出通道数depth卷积,得最终residual,最后层没有正则项没有激活函数。residual、shorcut相加,得最后结果output,用slim.utils.collect_named_outputs,结果添加collection,返回output函数结果。

定义生成ResNet V2主函数。参数,inputs输入,blocks为Block类列表,num_classes最后输出类数,global_pool标志是否加最后一层全局平均池化,include_root_block标志是否加ResNet网络最前面7x7卷积、最大池化,reuse标志是否重用,scope整个网络名称。定义variable_scope、end_points_collection,通过slim.arg_scope设slim.con2d、bottleneck、stack_block_dense函数的参数outputs_collections默认end_points_colletion。根据include_root_block标记,创建ResNet最前面64输出通道步长2的7x7卷积,接步长2的3x3最大池化。两个步长2层,图片尺寸缩小为1/4。用stack_blocks_dense生成残差学习模块组,根据标记添加全局平均池化层,用tf.reduce_mean实现全局平均池化,效率比直接avg_pool高。根据是否有分类数,添加输出通道num_classes1x1卷积(无激活函数无正则项),添加Softmax层输出网络结果。用slim.utils.convert_to_dict 转化collection为Python dict。最后返回net、end_points。

50层ResNet,4个残差学习Blocks,units数量为3、4、6、3,总层数(3+4+6+3)x3+2=50。残差学习模块前,卷积、池化把尺寸缩小4倍,前3个Blocks包含步长2层,总尺寸缩小4x8=32倍。输入图片尺寸最后变224/32=7。ResNet不断用步长2层缩减尺寸,输出通道数持续增加,达到2048。

152层ResNet,第二Block units数8,第三Block units数36。

200层ResNet,第二Block units数23,第三Block units数36。

评测函数time_tensorflow_run测试152层ResNet forward性能。图片尺寸224x224,batch size 32。is_training FLAG设False。resnet_v2_152创建网络,time_tensorflow_run评测forward性能。耗时增加50%,实用卷积神经网络结构,支持超深网络训练,实际工业应用forward性能不差。

参考资料:
《TensorFlow实战》

欢迎付费咨询(150元每小时),我的微信:qingxingfengzi

学习笔记TF033:实现ResNet的更多相关文章

  1. ResNet学习笔记

    ResNet学习笔记 前言 这篇文章实在看完很多博客之后写的,需要读者至少拥有一定的CNN知识,当然我也不知道需要读者有什么水平,所以可能对一些很入门的基本的术语进行部分的解释,也有可能很多复杂的术语 ...

  2. tensorflow学习笔记——图像识别与卷积神经网络

    无论是之前学习的MNIST数据集还是Cifar数据集,相比真实环境下的图像识别问题,有两个最大的问题,一是现实生活中的图片分辨率要远高于32*32,而且图像的分辨率也不会是固定的.二是现实生活中的物体 ...

  3. 官网实例详解-目录和实例简介-keras学习笔记四

    官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras   版权声明: ...

  4. CTR学习笔记&代码实现5-深度ctr模型 DeepCrossing -> DCN

    之前总结了PNN,NFM,AFM这类两两向量乘积的方式,这一节我们换新的思路来看特征交互.DeepCrossing是最早在CTR模型中使用ResNet的前辈,DCN在ResNet上进一步创新,为高阶特 ...

  5. CTR学习笔记&代码实现6-深度ctr模型 后浪 xDeepFM/FiBiNET

    xDeepFM用改良的DCN替代了DeepFM的FM部分来学习组合特征信息,而FiBiNET则是应用SENET加入了特征权重比NFM,AFM更进了一步.在看两个model前建议对DeepFM, Dee ...

  6. fpn(feature-Pyramid-network)学习笔记

    FPN(特征金字塔网络)学习笔记 论文 在物体检测里面,有限计算量情况下,网络的深度(对应到感受野)与 stride 通常是一对矛盾的东西,常用的网络结构对应的 stride 一般会比较大(如 32) ...

  7. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  8. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  9. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

随机推荐

  1. Learning-Python【3】:Python中的基本运算符

    一.算数运算 二.比较(关系)运算 比较运算只能在同类型之间进行,其中 int 与 float 同属于数字类型 三.赋值运算 1.增量赋值 2.链式赋值 3.交叉赋值 交换两个数的值,通常要借助第三个 ...

  2. 5、zabbix使用进阶(01)

    详细描述user parameters.定义主机发现规则实现自动发现.如何定义和实现自动注册方式 zabbix常用术语 1.主机(host):要监控的网络设备,可有IP或DNS名称指定: 2.主机组( ...

  3. 【转载】URL编码与两次encodeURI

    当使用地址栏提交查询参数时,如果不编码,非英文字符会按照操作系统的字符集进行编码提交到服务器,服务器会按照配置的字符集进行解码,所以如果两者不一致就会导致乱码. encodeURI函数采用UTF-8对 ...

  4. JAVA深入研究——Method的Invoke方法(转)

    原文地址:http://www.cnblogs.com/onlywujun/p/3519037.html 在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一 ...

  5. Windows 用bat脚本带配置启动redis,并用vb脚本使其在后台运行。

    最近,在Windows上用开发PHP程序,需要用到Redis,每天要打开一个运行redis-server.exe的窗口这样比较烦,因为窗口就一直打开着,不能关闭. 所以就想着通过写脚本的方式,让他在后 ...

  6. Android 虹软2.0人脸识别,注册失败问题 分析synchronized的作用

    人脸识别需要init初始化(FaceServer中),离开时需要unInit销毁:当一个含有人脸识别的界面A跳向另一个含有人脸识别的界面B时,由于初始化和销毁都是对FaceServer类加锁(sync ...

  7. springboot添加多数据源 以及 动态添加数据源动态切换数据源

    <!-- Druid 数据连接池依赖 --> <dependency> <groupId>com.alibaba</groupId> <artif ...

  8. webapi研究说明

    首先定义公共的返回对象 /// <summary> /// 返回数据对象 /// </summary> public class ResponseItem<T> { ...

  9. postman(二):使用postman发送get or post请求

    总结一下如何使用postman发送get或post请求 请求 一.GET请求 通常用于请求服务器发送某个资源,请求的数据会附在URL之后,以?分割URL和传输数据,多个参数用&连接 1.请求方 ...

  10. ubuntu 16.04 的IP地址变更

    网上google 出来的,全是让你变更 /etc/network/interfaces 这个文件. 可是,我以前设置过的静态地址,全没反映在这个文件里. 这回再变更的话,肯定也不是这个. 然后进入/e ...