• tensorflow slim实现resnet_v2


    resnet_v1:    Deep Residual Learning for Image Recognition

    Conv--> bn--> relu

    对于上面 7x7卷积和maxpooling,注意这个卷积是不能进行bn和relu的,因为version2的顺讯是 bn->relu->conv所以 bn和relu要留到conv2层

    stack_blocks_dense是把4个block都进行展开,最后一个block后要进行额外的 bn->relu    reduce_mean([1,2])表示 [batch_size, 7,7,2048]  变成  [batch_size,1,1,2048] 每个7x7进行取均值

    ??最后一个为什么stride是1,因为不需要downsampling,代替的是average pool

    bottleneck结构如下:   {because of concerns on the training time that we can afford,所以改成了bottleneck结构}

    一下两个结构有相同的复杂度,但是发下左边的维度是64  右边是256  其实就是4倍的关系

     

     resnet_v2  : Identity Mappings in Deep Residual Networks

    (a)就是第一篇论文采取的结构

    这篇文章侧重在想创造一条直接的通路用来传播信息,不仅仅是在一个残差单元内,而是考虑在整个网络中。

    论文发现当h(x)和f(y)都是自映射,信号能直接传播到下个单元,无论是前向传播或是后向传播,所以设计了上图(b)的结构

    实验发现h(x)使用1x1卷积或者gate 都不如直接自映射得到的结果好

    由post-activation  变成了 pre-activation   之前是relu在conv后,  现在relu在conv前

    (1)  任何一层的输出都可以由之前某个底层的输出及一个残差结构表示

    (2) 

          任何一层的输出都可以由原始输入和到它的所有残差输出之和表示, 而以前的网络都是层与层的积表示

    (3) 对loss求导发现

      

         求和那项不会永远都为-1,所以梯度不会弥散 vanish, 即使当weights任意小的时候

     对比了不同的shortcut方式,发现就是简单的identity比较好,1x1conv效果更差,可以用来对不同维度的数据进行处理

    对比了不同的relu,bn,conv的组合方式,发现以下的full pre-activation的结构效果最好

            

     Appendix:

    对于第一个residual结构的输入,因为前面是一个单独的conv层,我们需要对conv层的结果进行activation

    对于最后一个residual结构,在addition之后要额外进行一个activation

    以上为论文解读。接下来是代码实现。

    代码实现

    def resnet_v2_50:

      block = ......

      return resnet_v2(block)

    def  resnet_v2():

      net = conv2d(64,6,stride=2, scope="conv1")

      net = max_pool2d(net, [3,3] stride=2, scope="pool1")

      net = stack_blocks_dense(blocks)

      net = batch_norm(net, activation_fn=tf.nn.relu, scope="postnorm")

       return net

    def stack_blocks_dense(blocks):

      for block in blocks:

        bottlenect(block)

    def bottleneck(block):   #图如下

      preact = batch_norm(inputs, tf.nn.relu)

      if depth_in == depth:   #当残差结构输入的维度和经过block的维度一样的话

        shortcut = subsample(inputs, stride)    #只需要进行downsampling

      else:

        shortcut = conv2d(preact,depth,[1,1],stride,normalizer_fn=None,activation_fn=None)

      residual = conv2d(preact, depth_bottleneck, [1,1],stride=1)

      residual = conv2d_same(residual, depth_bottleneck, 3,stride)

      residual = conv2d(residual, depth,[1,1],stride=1,normalizer_fn=None,activation_fn=None)

      output = shortcut + residual

      return output

     

     

      

  • 相关阅读:
    TFS 2013”无法移除仍为团队管理员身份的标识”
    如何在TFS的过程模板中添加报表
    集成TFS Build生成与SonarQube获取代码分析结果
    TFS 2015 Update 2功能探索
    使用Azure Automation(自动化)定时关闭和启动虚拟机
    TFS 与活动目录AD(Active Directory)的同步机制
    Eclipse 常用快捷键
    JMeter网站并发性测试
    docker安装配置GitLab
    javaWeb项目在用maven启动时必须要用到的坐标
  • 原文地址:https://www.cnblogs.com/lainey/p/8280094.html
Copyright © 2020-2023  润新知