TensorFlow训练过程中如何将conv_layer_2设置为常量?
实现训练中冻结conv_layer_2的方案
没问题,这个需求可以通过分阶段控制训练变量或者固定层参数为常量来实现,下面给你具体的操作步骤和代码示例:
方法一:分阶段训练(推荐)
这种方法不需要修改计算图,只需要构建两个训练操作:一个用于前期训练所有层,另一个用于后期只训练除conv_layer_2之外的层。
步骤说明
- 先获取conv_layer_2对应的所有可训练变量(因为你给该层命名了
name="conv_2",可以通过scope精准筛选) - 构建两个优化操作:全量训练操作(原有代码的训练逻辑)、冻结conv_layer_2的训练操作
- 在训练循环中,前N步使用全量训练,之后切换为冻结conv_layer_2的训练
修改后的完整代码
import tensorflow as tf # The neural network input = tf.placeholder(dtype=tf.float32, shape=(None,5,5,1), name="input") conv_layer_1 = tf.layers.conv2d(input, 3, (1,1), activation=tf.nn.leaky_relu, name="conv_1") conv_layer_2 = tf.layers.conv2d(conv_layer_1, 3, (1,1), activation=tf.nn.leaky_relu, name="conv_2") conv_layer_3 = tf.layers.conv2d(conv_layer_2, 1, (1,1), activation=tf.nn.leaky_relu, name="conv_3") # Trainingsstuff prediction = tf.placeholder(dtype= tf.float32, shape = (None, 5,5,1)) loss = tf.losses.mean_squared_error(conv_layer_3, prediction) # 1. 获取conv_2层的所有可训练变量 conv2_trainable_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope="conv_2") # 2. 构建全量训练操作(原有逻辑) train_step_full = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) # 3. 构建冻结conv_2的训练操作:只更新除conv_2外的变量 train_step_frozen = tf.train.AdamOptimizer(learning_rate=0.001).minimize( loss, var_list=[var for var in tf.trainable_variables() if var not in conv2_trainable_vars] ) # 训练循环示例 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 假设前1000步训练所有层,后续冻结conv_2 total_steps = 2000 freeze_step = 1000 for step in range(total_steps): # 这里替换成你的实际batch数据 batch_x = ... batch_y = ... if step < freeze_step: _, current_loss = sess.run([train_step_full, loss], feed_dict={input: batch_x, prediction: batch_y}) else: _, current_loss = sess.run([train_step_frozen, loss], feed_dict={input: batch_x, prediction: batch_y}) if step % 100 == 0: print(f"Step {step}, Current Loss: {current_loss:.4f}")
方法二:将conv_layer_2设为常量(完全固定层输出)
如果你需要彻底把conv_layer_2变成常量(不仅不更新参数,连前向传播都使用固定值),可以在训练到指定步数后,将该层的权重和偏置赋值为当前固定值,之后不再更新。
核心代码片段
在训练到冻结步骤后执行:
with tf.Session() as sess: # ... 前期全量训练代码 ... # 当训练到freeze_step时,获取conv_2的当前参数值 conv2_kernel = sess.run(tf.get_default_graph().get_tensor_by_name("conv_2/kernel:0")) conv2_bias = sess.run(tf.get_default_graph().get_tensor_by_name("conv_2/bias:0")) # 将conv_2的参数赋值为固定值 assign_kernel = tf.assign(tf.get_default_graph().get_tensor_by_name("conv_2/kernel:0"), conv2_kernel) assign_bias = tf.assign(tf.get_default_graph().get_tensor_by_name("conv_2/bias:0"), conv2_bias) sess.run([assign_kernel, assign_bias]) # 后续训练使用冻结conv_2的操作(同方法一的train_step_frozen) # ... 后续训练循环 ...
注意事项
- tf.layers.conv2d生成的参数命名规则为
{层name}/kernel:0(权重)和{层name}/bias:0(偏置),要确保名称和你定义的层name一致 - 这种方法会将参数固定为冻结时刻的值,后续即使误操作更新该层,参数也不会变化
内容的提问来源于stack exchange,提问作者SebastianH
相关产品推荐
相关产品推荐

