tensorflow冻结变量方法(tensorflow freeze variable)
最近由于项目需要,要对tensorflow构造的模型中部分变量冻结,然后继续训练,因此研究了一下tf中冻结变量的方法,目前找到三种,各有优缺点,记录如下:
1.名词解释
冻结变量,指的是在训练模型时,对某些可训练变量不更新,即仅参与前向loss计算,不参与后向传播,一般用于模型的finetuning等场景。例如:我们在其他数据上训练了一个resnet152模型,然后希望在目前数据上做finetuning,一般来讲,网络的前几层卷积是用来提取底层图像特征的,因此可以对前3个卷积层进行冻结,不改变其weight和bias的数值。
2.方法介绍
目前我找到了三种tf冻结变量的方法,各有优缺点,具体如下:
2.1 trainable=False
一切tf.Variable或tf.Variable的子类,在创建时,都有一个trainable参数,在tf官方文档(https://www.tensorflow.org/api_docs/python/tf/Variable)中有对这个参数的定义,
意思是,如果trainable设置为True,就会把变量添加到GraphKeys.TRAINABLE_VARIABLES集合中,如果是False,则不添加。而在计算梯度进行后向传播时,我们一般会使用一个optimizer,然后调用该optimizer的compute_gradients方法。在compute_gradients中,第二个参数var_list如果不传入,则默认为GraphKeys.TRAINABLE_VARIABLES。
总结下,trainable=False冻结变量的逻辑:trainable=False → 该变量不会放入GraphKeys.TRAINABLE_VARIABLES → 调用optimizer.compute_gradients方法时默认变量列表为GraphKeys.TRAINABLE_VARIABLES,该变量不在其中,因此不参与后向传播,值不进行更新,达到冻结变量效果。
优点:操作简单,只要在你创建变量时设置trainable=False即可
缺点:不知道大家发现没有,我上面的总结中,optimizer.compute_gradients方法默认变量列表是GraphKeys.TRAINABLE_VARIABLES,这句话还意味着,如果我不想用默认变量列表,而使用自定义变量列表,那么即使设置了trainable=False,只要把该变量加入到自定义变量列表中,变量还是会参与后向传播的,值也会更新。另外,tf.layers、tf.contrib.rnn等一些高度封装的API是不支持这个参数的,没法用该方法冻结变量。最后,如果我们在使用Saver保存ckpt时,一般调动tf.trainable_variables()方法只保存可训练参数,这时返回的变量列表,也有上面的问题,即设置了trainable=False的变量不会在里面。
2.2 tf.stop_gradient()
我们还可以通过在某个变量外面包裹一层tf.stop_gradient()函数来达到冻结变量的目的。例如我们想冻结w1,可以写成这样:
w1 = tf.stop_gradient(w1)
在后向传播时,w1的值就不会更新。下面说下优缺点。
优点:操作简单,针对想冻结的变量,添加上面这一行即可,而且相比于上一个方法,设置了tf.stop_gradient()的变量,不会从GraphKeys.TRAINABLE_VARIABLES集合中去除,因此不会影响梯度计算和保存模型
缺点:和上一个方法类似,tf.stop_gradient()的输入是Tensor,tf.layers、tf.contrib.rnn等一些高度封装的API的返回值没法作为参数传入,即不能用该方法冻结
2.3 optimizer.compute_gradients(loss,var_list=no_freeze_vars)
optimizer.compute_gradients在2.1中提到过,其实我们只需要在计算梯度时,指定变量列表,把希望冻结的变量去除,即可完成冻结变量。但这么做有一个前提,我们必须知道所有可训练变量的名字,并根据一些规则去除变量。获取所有可训练变量名字调用tf.trainable_variables()方法即可,但去除变量则需要我们在构建网络的时候,合理利用tf.variable_scope,对不同变量做区分。例如,我们如果想把可训练变量中所有卷积层变量冻结,可以这么写:
trainable_vars = tf.trainable_variables()
freeze_conv_var_list = [t for t in trainable_vars if not t.name.startswith(u'conv')]
grads = opt.compute_gradients(loss, var_list=freeze_conv_var_list)
下面总结下优缺点,
优点:没有2.1和2.2的缺点,是一种适用范围更加广泛的方法
缺点:相对2.1,2.2使用起来比较复杂,需要自己去除冻结变量,并且variable_scope不能随意改动,因为可能使去除变量的过滤操作无效化。例如:如果把原来'cnn' scope改为'vgg',那么上面的代码就无效了
3.总结
tf对于一些常用操作,往往会提供多种方法,但每种方法一般都是有区别的,并且操作原理和后面的逻辑也会有不同,要谨慎使用
tensorflow冻结变量方法(tensorflow freeze variable)的更多相关文章
- Tensorflow模型变量保存
Tensorflow:模型变量保存 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献Tensorflow实战Google深度学习框架 实验平台: Tensorflow1.4.0 pyt ...
- 111、TensorFlow 初始化变量
# 显式的初始化时非常有用的 # 因为它可以让你不用重复进行繁重的初始化工作 # 当你重新从checkpoint文件中加载一个模型的时候 # 当随机初始化变量被配置在分布式的配置文件中 # 为了在开始 ...
- 05 Tensorflow中变量的初始化
打开Python Shell,输入import tensorflow as tf,然后可以执行以下代码. 1.创建一个2*3的矩阵,并让所有元素的值为0.(类型为tf.float) a = tf.ze ...
- TF:Tensorflow定义变量+常量,实现输出计数功能—Jason niu
#TF:Tensorflow定义变量+常量,实现输出计数功能 import tensorflow as tf state = tf.Variable(0, name='Parameter_name_c ...
- Java获取系统环境变量(System Environment Variable)和系统属性(System Properties)以及启动参数的方法
系统环境变量(System Environment Variable): 在Linux下使用export $ENV=123指定的值.获取的方式如下: Map<String,String> ...
- [tensorflow in a nutshell] tensorflow简明教程 (第一部分)
原文链接: https://medium.com/@camrongodbout/tensorflow-in-a-nutshell-part-one-basics-3f4403709c9d#.31jv5 ...
- tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)
tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...
- tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)
续集请点击我:tensorflow学习笔记——使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...
- Tensorflow r1.12及tensorflow serving r1.12 GPU版本编译遇到的问题
1.git clone tensorflow serving 及tensorflow代码 2. ERROR: /root/.cache/bazel/_bazel_root/f71d782da17fd8 ...
随机推荐
- MySQL(九)
封装 观察前面的文件发现,除了sql语句及参数不同,其它语句都是一样的 创建MysqlHelper.py文件,定义类 #encoding=utf8 import MySQLdb class Mysql ...
- python网络编程(二)
UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地.由于UDP在传输 ...
- Java 多线程 高可用原则
高可用原则 1 降级 降级开关的设计思路如下: 1. 集中管理开关:把开关推送到各个应用. 2. 可降级的多级读服务:比如服务调用降级为只读本地缓存.只读分布式缓存.只读默认降级数据(如库存状态默认有 ...
- 【二分+拓扑排序】Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348
目录 Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348 PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 MEA ...
- 使用JfreeChart生成图表遇到的问题
生成的图片不显示 需要在web.xml中配置一个指定的Servlet <servlet> <servlet-name>DisplayChart</servlet-name ...
- Android的Databinding-需要使用控件id,listener以及布局有include的场景
主的布局xml文件: <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bin ...
- javascript 生成MD5加密
进行HTTP网络通信的时候,调用API向服务器请求数据,有时为了防止API调用过程中被黑客恶意篡改,所请求参数需要进行MD5算法计算,得到摘要签名.服务端会根据请求参数,对签名进行验证,签名不合法的请 ...
- requirejs amd module load example
person.js /** * This example make use of requireJS to provide a clean and simple way to split JavaSc ...
- Centos7中在线/离线安装DockerCE最新版
Docker在Centos7在线/离线安装 一.在线安装 1.检查系统是否支持,因为Docker 要求 CentOS 系统的内核版本高于 3.10 uname -r 2.确保 yum 包更新到最新 y ...
- 第二天学习笔记:(MDN HTML学习、web安全策略与常见攻击、语义化)
一:Web入门 1:web文件命名 在文件名中应使用连字符(-).搜索引擎把连字符当作一个词的分隔符, 但不会以这种方式处理下划线. 养成在文件夹和文件名中使用小写,并且使用短横线而不是空格来分隔的习 ...