TensorFlow训练后如何阻止变量更新并测试当前权重与偏差?
嘿,我懂你的需求——训练完模型后想牢牢固定住当前的权重和偏差,只用来做测试计算,完全不让它们再被更新对吧?之前试的方法没踩对路子,我给你几个靠谱的方案:
最直接的方式:测试阶段不碰优化器操作
不管你用的是TensorFlow 1.x还是2.x,核心逻辑都很简单:训练时执行优化器的更新操作,测试时只跑前向传播的计算,完全不触发更新相关的步骤。
如果你用TF1.x的会话模式:
训练时你会定义类似train_op = tf.train.AdamOptimizer().minimize(loss)的更新操作,训练阶段跑sess.run(train_op);测试的时候只调用前向输出的操作(比如sess.run(prediction, feed_dict={x: test_data})),绝对不要碰train_op,权重就会纹丝不动。如果你用TF2.x的 eager 模式或函数式API:
训练阶段你会用梯度带计算梯度并更新权重,比如:with tf.GradientTape() as tape: predictions = model(x) loss = loss_fn(predictions, y) gradients = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(gradients, model.trainable_variables))测试的时候直接调用
model(test_data)就行,别用梯度带,也别执行apply_gradients这一步,模型权重就会保持训练后的状态。
强制设置变量为不可训练
要是怕不小心触发更新操作,可以把所有可训练变量的trainable属性改成False,这样优化器会自动忽略它们:
TF2.x里,直接遍历模型的可训练变量修改:
for var in model.trainable_variables: var.trainable = False之后不管怎么跑优化器,这些变量都不会被更新。之后要是还要继续训练,再改回
True就行。TF1.x里,定义变量时可以指定
trainable=False,如果是训练完之后要改,也能直接修改变量属性:var = tf.get_variable("weights", shape=[...], trainable=True) # 训练完成后修改 var._trainable = False
获取权重的具体数值用于计算
你说用inspect_checkpoint.print_tensors_in_checkpoint_file只能看不能用,其实直接拿变量数值超简单:
- TF2.x:直接调用变量的
numpy()方法,比如model.layers[0].kernel.numpy()就能拿到第一层卷积核的权重数组,直接用来计算就行。 - TF1.x:在会话里运行变量,比如
weights_val = sess.run(var),得到的就是numpy数组,能直接参与各种计算。
另外提一句,你之前试的tf.variable_scope.reuse_variables是用来共享变量的(比如多任务模型里复用同一组权重),和阻止更新完全不搭边,所以用错地方啦~
内容的提问来源于stack exchange,提问作者Raute

