摘要:我正在尝试为MNIST重新训练一个简单的CNN,而无需使用高级API。我已经通过重新培训整个网络而成功地做到了这一点,但是我目前的目标是仅重新培训最后一层或两个完全连接层。
目前为止的工作: 假设我有一个具有以下结构的CNN
我的目标是重新训练最后一个完全连接层或最后两个完全连接层。
卷积层的示例:
W_conv1 = tf.get_variable("W", [5, 5, 1, 32],
initializer=tf.truncated_normal_initializer(stddev=np.sqrt(2.0 / 784)))
b_conv1 = tf.get_variable("b", initializer=tf.constant(0.1, shape=[32]))
z = tf.nn.conv2d(x_image, W_conv1, strides=[1, 1, 1, 1], padding='SAME')
z += b_conv1
h_conv1 = tf.nn.relu(z + b_conv1)
完全连接层的示例:
input_size = 7 * 7 * 64
W_fc1 = tf.get_variable("W", [input_size, 1024], initializer=tf.truncated_normal_initializer(stddev=np.sqrt(2.0/input_size)))
b_fc1 = tf.get_variable("b", initializer=tf.constant(0.1, shape=[1024]))
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
我的假设:在新数据集上进行反向传播时,我只需确保将权重W和b(来自W * x + b)固定在未完全连接的图层中。
关于如何执行此操作的第一个想法:保存W和b,执行向后传播步骤,然后在我不想更改的图层中用旧的W和b替换新的W和b 。
我对第一种方法的想法:
我的问题 :
PS 。完全了解如何使用高级API来做到这一点。示例:https://towardsdatascience.com/how-to-train-your-model-dramatically-faster-9ad063f0f718。只是不想让神经网络变得神奇,我想知道实际发生的事情
答案 0 :(得分:1)
优化器的Minimal函数具有一个可选参数,用于选择要训练的变量,例如:
optimizer_step = tf.train.MomentumOptimizer(learning_rate, momentum, name='MomentumOptimizer').minimize(loss, var_list=training_variables)
您可以使用tf.trainable_variables()获得要训练的图层的变量:
vars1 = tf.trainable_variables()
# FC Layer
input_size = 7 * 7 * 64
W_fc1 = tf.get_variable("W", [input_size, 1024], initializer=tf.truncated_normal_initializer(stddev=np.sqrt(2.0/input_size)))
b_fc1 = tf.get_variable("b", initializer=tf.constant(0.1, shape=[1024]))
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
vars2 = tf.trainable_variables()
training_variables = list(set(vars2) - set(vars1))
编辑:实际上,在这种情况下使用tf.trainable_variables可能会过大,因为您直接拥有W_fc1和b_fc1。例如,如果您使用tf.layers.dense来创建一个密集层(在该层中您没有明确的变量),这将非常有用。