首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于slim的残差网络

基于slim的残差网络

作者头像
狼啸风云
修改2022-09-04 21:09:22
1.5K0
修改2022-09-04 21:09:22
举报

slim中给出了resnet、vgg卷积网络的快速实现方法,定义的位置为:D:\anaconda\envs\tensorflow\Lib\site-packages\tensorflow\contrib\slim\python\slim\nets,构建残差网络主要使用的模块为resnet_utils.py、resnet_v1.py、resnet_v2.py。下面

def resnet_v1(inputs,
              blocks,
              num_classes=None,
              is_training=True,
              global_pool=True,
              output_stride=None,
              include_root_block=True,
              reuse=None,
              scope=None):
  with variable_scope.variable_scope(
      scope, 'resnet_v1', [inputs], reuse=reuse) as sc:
    end_points_collection = sc.original_name_scope + '_end_points'
    with arg_scope(
        [layers.conv2d, bottleneck, resnet_utils.stack_blocks_dense],
        outputs_collections=end_points_collection):
      with arg_scope([layers.batch_norm], is_training=is_training):
        net = inputs
        if include_root_block:
          if output_stride is not None:
            if output_stride % 4 != 0:
              raise ValueError('The output_stride needs to be a multiple of 4.')
            output_stride /= 4
          net = resnet_utils.conv2d_same(net, 64, 7, stride=2, scope='conv1')
          net = layers_lib.max_pool2d(net, [3, 3], stride=2, scope='pool1')
        net = resnet_utils.stack_blocks_dense(net, blocks, output_stride)
        if global_pool:
          # Global average pooling.
          net = math_ops.reduce_mean(net, [1, 2], name='pool5', keepdims=True)
        if num_classes is not None:
          net = layers.conv2d(
              net,
              num_classes, [1, 1],
              activation_fn=None,
              normalizer_fn=None,
              scope='logits')
        # Convert end_points_collection into a dictionary of end_points.
        end_points = utils.convert_collection_to_dict(end_points_collection)
        if num_classes is not None:
          end_points['predictions'] = layers_lib.softmax(
              net, scope='predictions')
        return net, end_points
resnet_v1.default_image_size = 224

该函数生成一系列ResNet v1模型。有关特定的模型实例化,请参见resnet_v1_*()方法,该方法通过选择产生不同深度的resnet的不同块实例化获得。

Imagenet上的图像分类训练通常使用[224,224]输入,对于[1]中定义的、标称步长为32的ResNet,在最后一个ResNet块的输出生成[7,7]特征图。对于密集预测任务,建议使用空间维度为32 + 1的倍数的输入,例如[321,321]。在这种情况下,ResNet输出处的特征映射将具有空间形状[(height - 1) / output_stride + 1, (width - 1) / output_stride + 1]和与输入图像角完全对齐的角,这极大地促进了特征与图像的对齐。使用作为输入的[225,225]图像在最后一个ResNet块的输出处生成[8,8]feature map。

对于密集预测任务,ResNet需要在全卷积(FCN)模式下运行,global_pool需要设置为False。

[1,2]中的ResNets都有公称stride= 32,在FCN模式下,一个很好的选择是使用output_stride=16,以便在较小的计算和内存开销下增加计算特性的密度,cf. http://arxiv.org/abs/1606.00915。

参数:

  • inputs  尺寸为[batch, height_in, width_in, channels]的张量。
  • blocks:  长度等于ResNet块数量的列表。每个元素都是一个resnet_utils。块对象描述块中的单元。
  • num_classes:  用于分类任务的预测类的数量。如果没有,则返回logit层之前的特性。
  • is_training:   batch_norm层是否处于训练模式。
  • global_pool:  如果为真,则在计算日志之前执行全局平均池。图像分类设为真,预测密度设为假。
  • output_stride:  如果没有,那么输出将在标称网络步长处计算。如果output_stride不为None,则指定请求的输入与输出空间分辨率之比。
  • include_root_block:  如果为真,则包含初始卷积后的最大池,如果为假则排除它。
  • reuse:  是否应该重用网络及其变量。为了能够重用“范围”,必须给出。
  • scope:  可选variable_scope。

返回:

  • net:  一个大小为[batch, height_out, width_out, channels_out]的秩-4张量。如果global_pool是假的,那么与各自的height_in和width_in相比,height_out和width_out将减少一个output_stride因子,否则height_out和width_out都等于1。如果num_classes为None,则net是最后一个ResNet块的输出,可能在全局平均池之后。如果num_classes不是None, net包含pre-softmax激活。
  • end_points:从网络组件到相应激活的字典。

可能产生的异常:

  •  ValueError: If the target output_stride is not valid.
def resnet_v1_block(scope, base_depth, num_units, stride):

  return resnet_utils.Block(scope, bottleneck, [{
      'depth': base_depth * 4,
      'depth_bottleneck': base_depth,
      'stride': 1
  }] * (num_units - 1) + [{
      'depth': base_depth * 4,
      'depth_bottleneck': base_depth,
      'stride': stride
  }])

用于创建resnet_v1 bottleneck的Helper函数。 参数:

  • scope:  块的范围。
  • base_depth:  每个单元的瓶颈层的深度。
  • num_units:  块中的单元数。
  • stride:  块体的跨步,作为最后一个单元的跨步执行。所有其他单位都有stride=1。

返回值:

  • 一个resnet_v1的bottleneck块。
def resnet_v1_50(inputs,
                 num_classes=None,
                 is_training=True,
                 global_pool=True,
                 output_stride=None,
                 reuse=None,
                 scope='resnet_v1_50'):
  """ResNet-50 model of [1]. See resnet_v1() for arg and return description."""
  blocks = [
      resnet_v1_block('block1', base_depth=64, num_units=3, stride=2),
      resnet_v1_block('block2', base_depth=128, num_units=4, stride=2),
      resnet_v1_block('block3', base_depth=256, num_units=6, stride=2),
      resnet_v1_block('block4', base_depth=512, num_units=3, stride=1),
  ]
  return resnet_v1(
      inputs,
      blocks,
      num_classes,
      is_training,
      global_pool,
      output_stride,
      include_root_block=True,
      reuse=reuse,
      scope=scope)

[1]的ResNet-50模型。有关arg和返回描述,请参见resnet_v1()。 

def resnet_v1_50(inputs,
                 num_classes=None,
                 is_training=True,
                 global_pool=True,
                 output_stride=None,
                 reuse=None,
                 scope='resnet_v1_50'):
  """ResNet-50 model of [1]. See resnet_v1() for arg and return description."""
  blocks = [
      resnet_v1_block('block1', base_depth=64, num_units=3, stride=2),
      resnet_v1_block('block2', base_depth=128, num_units=4, stride=2),
      resnet_v1_block('block3', base_depth=256, num_units=6, stride=2),
      resnet_v1_block('block4', base_depth=512, num_units=3, stride=1),
  ]
  return resnet_v1(
      inputs,
      blocks,
      num_classes,
      is_training,
      global_pool,
      output_stride,
      include_root_block=True,
      reuse=reuse,
      scope=scope)
def conv2d_same(inputs, num_outputs, kernel_size, stride, rate=1, scope=None):
  if stride == 1:
    return layers_lib.conv2d(
        inputs,
        num_outputs,
        kernel_size,
        stride=1,
        rate=rate,
        padding='SAME',
        scope=scope)
  else:
    kernel_size_effective = kernel_size + (kernel_size - 1) * (rate - 1)
    pad_total = kernel_size_effective - 1
    pad_beg = pad_total // 2
    pad_end = pad_total - pad_beg
    inputs = array_ops.pad(
        inputs, [[0, 0], [pad_beg, pad_end], [pad_beg, pad_end], [0, 0]])
    return layers_lib.conv2d(
        inputs,
        num_outputs,
        kernel_size,
        stride=stride,
        rate=rate,
        padding='VALID',
        scope=scope)

  """

用'SAME'padding进行2-D卷积。如果stride > 1,然后明确的执行零填充,然后是一个'VALID'填充的二维卷积。

注意 

net = conv2d_same(inputs, num_outputs, 3, stride=stride)等于

net = tf.contrib.layers.conv2d(inputs, num_outputs, 3, stride=1,padding='SAME') net = subsample(net, factor=stride)

  然而

net = tf.contrib.layers.conv2d(inputs, num_outputs, 3, stride=stride,padding='SAME')当输入的高度或宽度为偶数时,则不同,这就是我们添加当前函数的原因。

参数:

  • inputs:  一个大小为[batch, height_in, width_in, channels]的4-D张量
  • num_output:  一个整数,输出滤波器的数量
  • kernel_size:  带有过滤器的kernel_size的int
  • stride:  一个整数,输出步长
  • rate:  一个整数,用于无阶卷积的速率
  • scope:  范围

返回值:

  • output:  一个具有卷积输出的大小为[batch, height_out, width_out, channels]的4-D张量。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月05日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
批量计算
批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档