Tensorflow slim resnet v2源码阅读笔记

本文详细解读了Tensorflow Slim库中ResNet V2的实现,涵盖了resnet_v2.py和resnet_utils.py的关键代码。通过阅读,了解了arg_scope、variable_scope及outputs_collections等概念在模型构建中的应用,旨在为深度学习和计算机视觉领域的开发者提供参考。
摘要由CSDN通过智能技术生成

主要涉及:
https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v2.py
https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_utils.py

首先建议阅读Tensorflow和slim的官方文档,获取arg_scope,variable_scope,outputs_collections等的基础知识。

本文主要是记录一下代码的大概逻辑,备忘。

resnet_utils.py

'''
需了解collections.namedtuple,相当于一个命名了的元组,且可以通过属性的名字访问属性值。
'''
class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])):

'''
简单,用最大池化来降采样(其实是通过stride)
'''
def subsample(inputs, factor, scope=None):

'''
1. net = conv2d_same(inputs, num_outputs, 3, stride=stride)
2. net = slim.conv2d(inputs, num_outputs, 3, stride=1, padding='SAME')
   net = subsample(net, factor=stride)
3. net = slim.conv2d(inputs, num_outputs, 3, stride=stride, padding='SAME')
1和2是等价的,当inputs的高或宽是偶数时3与1,2不一样。

"VALID" only ever drops the right-most columns (or bottom-most rows).
默认的"SAME" tries to pad evenly left and right, but if the amount of columns to be added is odd, it will add the extra column to the right, as is the case in this example (the same logic applies vertically: there may be an extra row of zeros at the bottom).
在testConv2DSameEven中可以清楚看出来由于对偶数大小的边进行pad会造成最终结果的不同,细节不写了。

所以在这个函数中先手动进行padding,然后再调用conv2d。
'''
def conv2d_same(inputs, num_outputs, kernel_size, stride, rate=1, scope=None):

'''
比较核心的函数,作用是将不同的block(一般一共四个)组装起来,当然肚子里也将同一个block的bottleneck组装起来。block.unit_fn调用的就是该block的bottleneck,原因见 class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args']))。
'''
@slim.add_arg_scope
def stack_blocks_dense(net, blocks, output_stride=None,
                       outputs_collections=None):

'''
为resnet定义了arg_scope,方便定义各种层的时候少写代码。
'''
def resnet_arg_scope(weight_decay=0.0001,
                     batch_norm_decay=0.997,
                     batch_norm_epsilon=1e-5,
                     batch_norm_scale=True,
                     activation_fn=tf.nn.relu,
                     use_batch_norm=True):
resnet_v2.py

'''
Bottleneck residual unit variant with BN before convolutions.
就是三个连续的卷积层(BN和relu都被arg_scope定义了),另外当通道数变化时会有一个额外的shortcut卷积层,利用1*1卷积修正通道数,使得shortcut过来的输入可以直接和三个卷积分支的输出相加。
'''
def bottleneck(inputs, depth, depth_bottleneck, stride, rate=1,
               outputs_collections=None, scope=None)

'''构建整个resnet的函数。
看懂这个就知道end_points为什么可以获取各层输出了:
with slim.arg_scope([slim.conv2d, bottleneck,
                         resnet_utils.stack_blocks_dense],
                        outputs_collections=end_points_collection)
这个函数调用了resnet_utils.stack_blocks_dense,上面介绍过,用来组装四个大block。
'''
def resnet_v2(inputs,
              blocks,
              num_classes=None,
              is_training=True,
              global_pool=True,
              output_stride=None,
              include_root_block=True,
              spatial_squeeze=True,
              reuse=None,
              scope=None)

'''这个函数就是封装了创建class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args']))对象的代码。
'''
def resnet_v2_block(scope, base_depth, num_units, stride)

'''这个函数全抄过来了,是对外的接口,主要调用了resnet_v2_block和resnet_v2这两个函数。
'''
def resnet_v2_152(inputs,
                  num_classes=None,
                  is_training=True,
                  global_pool=True,
                  output_stride=None,
                  spatial_squeeze=True,
                  reuse=None,
                  scope='resnet_v2_152'):
  blocks = [
      resnet_v2_block('block1', base_depth=64, num_units=3, stride=2),
      resnet_v2_block('block2', base_depth=128, num_units=8, stride=2),
      resnet_v2_block('block3', base_depth=256, num_units=36, stride=2),
      resnet_v2_block('block4', base_depth=512, num_units=3, stride=1),
  ]
  return resnet_v2(inputs, blocks, num_classes, is_training=is_training,
                   global_pool=global_pool, output_stride=output_stride,
                   include_root_block=True, spatial_squeeze=spatial_squeeze,
                   reuse=reuse, scope=scope)
resnet_v2_152.default_image_size = resnet_v2.default_image_size
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值