缘由

  最近一直在看深度学习的代码,又一次看到了slim.arg_scope()的嵌套使用,具体代码如下:

with slim.arg_scope([slim.conv2d, slim.separable_conv2d],weights_initializer=tf.truncated_normal_initializer(stddev=weights_initializer_stddev),activation_fn=activation_fn,normalizer_fn=slim.batch_norm if use_batch_norm else None):with slim.arg_scope([slim.batch_norm], **batch_norm_params):with slim.arg_scope([slim.conv2d],weights_regularizer=slim.l2_regularizer(weight_decay)):with slim.arg_scope([slim.separable_conv2d],weights_regularizer=depthwise_regularizer) as arg_sc:return arg_sc

  由上述代码可以看到,第一层argscope有slim.conv2d参数,第三层也有这个参数,那么不同层的参数是如何相互补充,作用到之后的代码块中,就是这篇博文的出发点。

准备工作

  我们先看一下arg_scope的函数声明:

@tf_contextlib.contextmanager
def arg_scope(list_ops_or_scope, **kwargs):

  有函数修饰符@tf_contextlib.contextmanager修饰arg_scope函数,我们先研究下这个函数修饰符。

@的作用

  @之后一般接一个可调用对象(tf_contextlib.contextmanager),一起构成函数修饰符(装饰器),这个可调用对象将被修饰函数(arg_scope)作为参数,为其执行一系列辅助操作,我们来看一个demo:

import timedef my_time(func):print(time.ctime())return func()@my_time  # 从这里可以看出@time 等价于 time(xxx()),但是这种写法你得考虑python代码的执行顺序
def xxx():print('Hello world!')运行结果:
Wed Jul 26 23:01:21 2017
Hello world!

  在这个例子中,xxx函数实现我们的主要功能,打印Hello world!,但我们想给xxx函数添加一些辅助操作,让它同时打印出时间,于是我们用函数修饰符@my_time完成这个目标。整个例子的执行流程为调用my_time可调用对象,它接受xxx函数作为参数,先打印时间,再执行xxx函数。

上下文管理器

  既然arg_scope函数存在装饰器,那么我们应该了解一下@tf_contextlib.contextmanager装饰器提供了什么辅助功能,代码为:

import contextlib as _contextlibfrom tensorflow.python.util import tf_decoratordef contextmanager(target):"""A tf_decorator-aware wrapper for `contextlib.contextmanager`.Usage is identical to `contextlib.contextmanager`.Args:target: A callable to be wrapped in a contextmanager.Returns:A callable that can be used inside of a `with` statement."""context_manager = _contextlib.contextmanager(target)return tf_decorator.make_decorator(target, context_manager, 'contextmanager') #会在下一篇介绍这个return语句的功能

上下文管理器——contextlib库

  可以看到导入了contextlib库,这个库提供了contextmanager函数,这也是一个装饰器,它使被修饰的函数具有上下文管理器的功能。上下文管理器使我们能在执行一段代码块之前做一些准备工作,执行完代码块之后做一些收尾工作,同样先来看一个上下文管理器的例子:

import timeclass MyTimer(object):def __init__(self, verbose = False):self.verbose = verbosedef __enter__(self):self.start = time.time()return selfdef __exit__(self, *unused):self.end = time.time()self.secs = self.end - self.startself.msecs = self.secs * 1000if self.verbose:print "elapsed time: %f ms" %self.msecs

with MyTimer(True):  print('Hello world!')

  类MyTimer中的__enter__和__exit__方法分别是准备工作和收尾工作。整个代码的执行过程为:先执行__enter__方法,__enter__方法中的返回值(这个例子中是self)可以用到代码块中,再执行语句块,这个例子中是print函数,最后执行__exit__方法,更多关于上下文管理器的内容可以看这,我的例子也是从那copy的。contextlib中实现上下文管理器稍有不同,一样来看个例子:

from contextlib import contextmanager@contextmanager
def tag(name):print "<%s>" % nameyieldprint "</%s>" % name>>> with tag("h1"):
...    print "foo"
运行结果:
<h1>
foo
</h1>

  tag函数中yield之前的代码相当于__enter__方法,yield产生的生成器相当于__enter__方法的返回值,yield之后的代码相当于__exit__方法。

arg_scope方法

  这里我把arg_scope方法中代码稍微做了一些精简,代码如下:

arg_scope = [{}]

@tf_contextlib.contextmanager
def arg_scope(list_ops_or_scope, **kwargs):   try:current_scope = current_arg_scope().copy()for op in list_ops_or_scope:key = arg_scope_func_key(op)if not has_arg_scope(op): # op是否用@slim.add_arg_scope修饰,这会在下一篇中介绍raise ValueError('%s is not decorated with @add_arg_scope',_name_op(op))if key in current_scope:current_kwargs = current_scope[key].copy()current_kwargs.update(kwargs)current_scope[key] = current_kwargselse:current_scope[key] = kwargs.copy()_get_arg_stack().append(current_scope)yield current_scopefinally:_get_arg_stack().pop()

# demo
with slim.arg_scope([slim.conv2d, slim.separable_conv2d],weights_initializer=tf.truncated_normal_initializer(stddev=weights_initializer_stddev),activation_fn=activation_fn,normalizer_fn=slim.batch_norm if use_batch_norm else None):with slim.arg_scope([slim.batch_norm], **batch_norm_params): with slim.arg_scope( [slim.conv2d], weights_regularizer=slim.l2_regularizer(weight_decay)): with slim.arg_scope( [slim.separable_conv2d], weights_regularizer=depthwise_regularizer) as arg_sc: return arg_sc

第一层

  之后的层的处理就很类似,留给大家思考。

结语

  回到我们开头提到的问题,不同层的参数是如何互相补充的?现在我们可以看到,参数存储在栈中,每叠加一层,就在原有参数基础上把新参数添加上去。

                                            最后编辑于15:46:26 2018-07-24

转载于:https://www.cnblogs.com/zzy-tf/p/9356883.html

tf.contrib.slim arg_scope相关推荐

  1. tf.nn.conv2d和tf.contrib.slim.conv2d的区别

    转自:http://blog.sina.com.cn/s/blog_6ca0f5eb0102wsuu.html 文中摘要: " 在上述的API中,可以看出去除掉初始化的部分,那么两者并没有什 ...

  2. TensorFlow学习——tf.nn.conv2d和tf.contrib.slim.conv2d的区别

    在查看代码的时候,看到有代码用到卷积层是tf.nn.conv2d,也有的使用的卷积层是tf.contrib.slim.conv2d,这两个函数调用的卷积层是否一致,在查看了API的文档,以及slim. ...

  3. tf.contrib.slim add_arg_scope

    上一篇文章中我们介绍了arg_scope函数,它在每一层嵌套中update当前字典中参数形成新的字典,并入栈.那么这些参数是怎么作用到代码块中的函数的呢?比如说如下情况: with slim.arg_ ...

  4. tf.contrib.slim常用方法

    slim是一个轻量级tensorflow库,封装了很多好用的api,常用方法如下: slim.arg_scope():为目标函数设置默认参数 slim.l2_regularizer() slim.co ...

  5. 【Tensorflow】slim.arg_scope()的使用

    [fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处] slim.arg_scope() 函数的使用 slim是一种轻量级的tensorflow库 ...

  6. slim.arg_scope()的使用

    slim.arg_scope() 函数的使用 slim是一种轻量级的tensorflow库,可以使模型的构建,训练,测试都变得更加简单.在slim库中对很多常用的函数进行了定义,slim.arg_sc ...

  7. tensorflow兼容处理 tensorflow.compat.v1 tf.contrib

    20201130 问题提出: v1版本中tensorflow中contrib模块十分丰富,但是发展不可控,因此在v2版本中将这个模块集成到其他模块中去了.在学习tensorflow经常碰到tf.con ...

  8. 第十六节,使用函数封装库tf.contrib.layers

    目录 一 tf.contrib.layers中的具体函数介绍 1.tf.contrib.layers.conv2d()函数的定义如下: 2.tf.contrib.layers.max_pool2d() ...

  9. 重磅 | TensorFlow 2.0即将发布,所有tf.contrib将被弃用

    作者 | 阿司匹林 出品 | AI科技大本营(公众号ID:rgznai100) 上周,谷歌刚刚发布了 TensorFlow 1.10.0 版本(详见<TensorFlow 版本 1.10.0 发 ...

最新文章

  1. python常用内置函数总结-python常用内置函数
  2. JavaScript高级程序设计(二):在HTML中使用JavaScript
  3. 漫谈Google的Native Client(NaCl)技术
  4. Linux指令类型(一)change指令
  5. electron 入坑记
  6. Tensorflow代码转pytorch代码 函数的转换
  7. no valid Qt versions found
  8. 现代操作系统原理与实践03:操作系统结构
  9. g hub安装失败_树莓派k8s集群安装mysql及监控
  10. 了解java虚拟机mdash;串行回收器(6)
  11. MSSQL SQL简繁转换函数
  12. 网站生成EXE文件运行——PHP网站打包工具PHPWAMP
  13. quartz 每月一次_Quartz 每月1号,执行规则表达式怎么列?
  14. C++自带string类的常用方法
  15. AC敏捷控制器及准入控制技术对比
  16. 解析DELLR710服务器迁移操作内容
  17. 安装VMware和安装Linux
  18. 网页密码查看器+原代码+windows密码查看
  19. 成都 顺兴茶馆 看变脸
  20. 博图中SCL程序的创建方式

热门文章

  1. docker快速搭建RabbitMQ集群
  2. mysql常用全局参数,设置一个持久的全局MySQL参数
  3. linux内核层是什么,从用户层到内核层 - Linux内核中的信号机制_Linux编程_Linux公社-Linux系统门户网站...
  4. matlab产生ofdm信号,Matlab 完成简单的OFDM 信号的产生与解调程序.pdf
  5. php添加开机启动脚本_centos 7.2 添加php7 的 php-fpm 开机启动
  6. tfds.load()和tf.data.Dataset的简介
  7. php 提取登录QQ,php QQ登录
  8. python如何记录运行时间_Python如何测量脚本运行时间
  9. mysql二进制日志内容说明_MySQL二进制日志相关问题详细说明
  10. powwr shell_Powershell Do While 循环