tf.contrib.slim arg_scope
缘由
最近一直在看深度学习的代码,又一次看到了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 time def 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 _contextlib from tensorflow.python.util import tf_decorator def 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 time class MyTimer(object): def __init__(self, verbose = False): self.verbose = verbose def __enter__(self): self.start = time.time() return self def __exit__(self, *unused): self.end = time.time() self.secs = self.end - self.start self.msecs = self.secs * 1000 if 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>" % name yield print "</%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_kwargs else: current_scope[key] = kwargs.copy() _get_arg_stack().append(current_scope) yield current_scope finally: _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
tf.contrib.slim arg_scope的更多相关文章
- tf.contrib.slim模块简介
原文连接:https://blog.csdn.net/MOU_IT/article/details/82717745 1.简介 对于tensorflow.contrib这个库,tensorflow官方 ...
- tf.contrib.slim add_arg_scope
上一篇文章中我们介绍了arg_scope函数,它在每一层嵌套中update当前字典中参数形成新的字典,并入栈.那么这些参数是怎么作用到代码块中的函数的呢?比如说如下情况: with slim.arg_ ...
- tf.contrib.slim.data数据加载(1) reader
reader: 适用于原始数据数据形式的Tensorflow Reader 在库中parallel_reader.py是与reader相关的,它使用多个reader并行处理来提高速度,但文件中定义的类 ...
- tf.contrib.slim.data数据加载 综述
TF-Slim为了方便加载各种数据类型(如TFRocords或者文本文件)的数据,创建了这个库. Dataset 这里的数据库与通常意义下数据库是不同的,这里数据库是python一个类,它负责将原始数 ...
- tf.contrib.slim
https://blog.csdn.net/mao_xiao_feng/article/details/73409975
- 图融合之加载子图:Tensorflow.contrib.slim与tf.train.Saver之坑
import tensorflow as tf import tensorflow.contrib.slim as slim import rawpy import numpy as np impor ...
- slim.arg_scope()的使用
[https://blog.csdn.net/u013921430 转载] slim是一种轻量级的tensorflow库,可以使模型的构建,训练,测试都变得更加简单.在slim库中对很多常用的函数进行 ...
- 使用多块GPU进行训练 1.slim.arg_scope(对于同等类型使用相同操作) 2.tf.name_scope(定义名字的范围) 3.tf.get_variable_scope().reuse_variable(参数的复用) 4.tf.py_func(构造函数)
1. slim.arg_scope(函数, 传参) # 对于同类的函数操作,都传入相同的参数 from tensorflow.contrib import slim as slim import te ...
- 学习笔记TF044:TF.Contrib组件、统计分布、Layer、性能分析器tfprof
TF.Contrib,开源社区贡献,新功能,内外部测试,根据反馈意见改进性能,改善API友好度,API稳定后,移到TensorFlow核心模块.生产代码,以最新官方教程和API指南参考. 统计分布.T ...
随机推荐
- css实现背景模糊,但不影响背景上的内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- jmeter使用csv传参进行并发测试验证
1.获取到注册接口,添加HTTP信息头管理器.HTTP请求,设置好入参,且检查使用csv文件传参的入参 2.创建csv文件,写入需要传的入参 3.添加CSV Data Set Config 设置配置 ...
- Java SE API —— 【Math 】之【BigInteger】类
目录 概述 构造方法 BigInteger(byte[] val) 概述 不可变的任意精度的整数.提供了模算术.GCD 计算.质数测试.素数生成.位操作以及一些其他操作. 算术运算的语义完全模仿 Ja ...
- Selenium-ActionChainsApi--鼠标连贯操作
ActionChains UI自动化测试过程中,经常遇到那种,需要鼠标悬浮后,要操作的元素才会出现的这种场景,那么我们就要模拟鼠标悬浮到某一个位置,做一系列的连贯操作,Selenium给我们提供了Ac ...
- 【3】学习C++之const关键字的使用
在C++中,const关键字是控制变量是否可以变化的,是否能够用好const关键字是区别小白和大佬的重要指标(大雾). 1.const与基本数据类型 ; //a是变量,a的值可以在后续操作中进行更改. ...
- 获取iframe 内容
parent.$.find("iframe")[0].contentWindow.getvalue(); h.find("iframe")[0].content ...
- DC综合简单总结(1)
DC综合简单总结(1) *****************set_dont_touch和set_dont_touch_network**************** ? 在综合的过程中,为了不让D ...
- 【easy】189. Rotate Array
题目标签:Array 题目给了我们一个数组 和 k. 让我们 旋转数组 k 次. 方法一: 这里有一个很巧妙的方法: 利用数组的length - k 把数组 分为两半: reverse 左边和右边的数 ...
- pwnable.tw silver_bullet
产生漏洞的原因 int __cdecl power_up(char *dest) { char s; // [esp+0h] [ebp-34h] size_t new_len; // [esp+30h ...
- Java版InfluxDB工具类
InfluxDB工具类 package com.influxdb.test; import java.util.Map; import org.influxdb.InfluxDB; import or ...