神经网络之ResNet模型的实现(Python+TensorFlow)

各种层数的残差网络:

34-layer的残差网络结构:

 

ResNet 的核心结构——bottleneck残差模块

在通道数相同情况下,bottleneck残差模块要比朴素残差模块节省大量的参数,一个单元内的参数少了,就可以做出更深的结构。从上面两个图可以看到,bottleneck残差模块将两个3*3换成了1*1、3*3、1*1的形式,这就达到了减少参数的目的。和Inception中的1*1卷积核作用相同。

这种结构也称为 shortcut 或 skip connection。

 

# -*- coding:UTF-8 -*-

import collections
import tensorflow as tf

from tf.contrib.layers.python.layers import utils

slim = tf.contrib.slim


class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])):
  '''
  使用collections.namedtuple设计ResNet基本block模块组的named tuple,
  定义一个典型的Block需要输入三个参数:
  scope:  Block的名称
  unit_fn:ResNet V2中的残差学习单元 
  args:   它决定该block有几层,格式是[(depth, depth_bottleneck, stride)]

  示例:Block('block1', bottleneck, [(256,64,1),(256,64,1),(256,64,2)])
  '''

def subsample(inputs, factor, scope=None): 
  if factor == 1:
    return inputs
  else:
    return slim.max_pool2d(inputs, [1, 1], stride=factor, scope=scope)


def conv2d_same(inputs, num_outputs, kernel_size, stride, scope=None): 
  """
  if stride>1, then we do explicit zero-padding, followed by conv2d with 'VALID' padding
  """
  if stride == 1:
    return slim.conv2d(inputs, num_outputs, kernel_size, stride=1, padding='SAME', scope=scope)
  else:
    pad_total = kernel_size - 1
    pad_beg = pad_total // 2
    pad_end = pad_total - pad_beg
    inputs = tf.pad(inputs, [[0, 0], [pad_beg, pad_end], [pad_beg, pad_end], [0, 0]])
    return slim.conv2d(inputs, num_outputs, kernel_size, stride=stride, padding='VALID', scope=scope)


#---------------------定义堆叠Blocks的函数-------------------
@slim.add_arg_scope
def stack_blocks_dense(net, blocks, outputs_collections=None):
  • 4
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值