TensorFlow实现部分参数梯度更新:变量作用域与Stop Gradient详解
本文介绍在TensorFlow中实现部分模型参数梯度更新的两种方法。第一种通过变量作用域筛选需优化的变量,第二种利用tf.stop_gradient()函数冻结特定层。结合矩阵部分行或列更新的示例,详细解析如何在迁移学习和Embedding场景中保持预训练参数不变并微调特定层。
迁移学习与部分参数更新背景
在深度学习领域,迁移学习是一种广泛应用的技术。通常的做法是将预训练于大数据集上的模型迁移至特定任务,此时往往需要保持模型的大部分参数不变,仅对与目标任务相关的模型层进行微调。
本文将重点介绍在TensorFlow框架下,如何实现仅更新模型部分参数的方法。
基于变量作用域的梯度更新方法
方法一:根据Variable scope剔除需要固定参数的变量
变量筛选代码实现
def get_variable_via_scope(scope_lst):
vars = []
for sc in scope_lst:
sc_variable = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope=scope)
vars.extend(sc_variable)
return vars
trainable_vars = tf.trainable_variables()
no_change_scope = ['your_unchange_scope_name']
no_change_vars = get_variable_via_scope(no_change_scope)
for v in no_change_vars:
trainable_vars.remove(v)
grads, _ = tf.gradients(loss, trainable_vars)
optimizer = tf.train.AdamOptimizer(lr)
train_op = optimizer.apply_gradient(zip(grads, trainable_vars), global_step=global_step)
基于Stop Gradient的梯度更新方法
方法二:使用tf.stop_gradient()函数
在构建计算图(Graph)的过程中使用该函数,可以非常简洁地避免使用scope来获取和筛选参数。
矩阵部分行或列的参数更新场景
方法三:实现矩阵中部分行或列参数的更新
在实际场景中,如果一个矩阵仅有部分行或列需要更新参数,而其余部分保持不变,这种情况十分常见。例如,在Word Embedding中,一些预定义的领域相关词保持不变(使用领域相关的Word Embedding初始化),而另一些通用词则允许变化。
部分更新代码示例
import tensorflow as tf
import numpy as np
def entry_stop_gradients(target, mask):
mask_h = tf.abs(mask-1)
return tf.stop_gradient(mask_h * target) + mask * target
mask = np.array([1., 0, 1, 1, 0, 0, 1, 1, 0, 1])
mask_h = np.abs(mask-1)
emb = tf.constant(np.ones([10, 5]))
matrix = entry_stop_gradients(emb, tf.expand_dims(mask,1))
parm = np.random.randn(5, 1)
t_parm = tf.constant(parm)
loss = tf.reduce_sum(tf.matmul(matrix, t_parm))
grad1 = tf.gradients(loss, emb)
grad2 = tf.gradients(loss, matrix)
print matrix
with tf.Session() as sess:
print sess.run(loss)
print sess.run([grad1, grad2])
以上关于TensorFlow实现部分参数梯度更新的操作内容,就是小编分享给大家的全部信息。希望这些内容能对大家有所帮助,也欢迎大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













