【问题标题】:How to reuse an existing neural network to train a new one using TensorFlow?如何重用现有的神经网络来使用 TensorFlow 训练新的神经网络?
【发布时间】:2016-12-23 01:39:25
【问题描述】:

我想通过重用现有神经网络(已经训练过)的较低层来使用 TensorFlow 训练一个新的神经网络。我想删除现有网络的顶层并用新层替换它们,并且我还想锁定最低层以防止反向传播修改它们。这里有一点 ascii 艺术来总结一下:

*Original model*           *New model*

Output Layer                Output Layer (new)
     |                          |
Hidden Layer 3             Hidden Layer 3 (copied)
     |             ==>          |
Hidden Layer 2             Hidden Layer 2 (copied+locked)
     |                          |
Hidden Layer 1             Hidden Layer 1 (copied+locked)
     |                          |
   Inputs                     Inputs

有什么好的方法可以做到这一点?

编辑

我原来的网络是这样创建的:

X = tf.placeholder(tf.float32, shape=(None, 500), name="X")
y = tf.placeholder(tf.int64, shape=(None), name="y")

hidden1 = fully_connected(X, 300, scope="hidden1")
hidden2 = fully_connected(hidden1, 100, scope="hidden2")
hidden3 = fully_connected(hidden2, 50, scope="hidden3")
output = fully_connected(hidden3, 5, activation_fn=None, scope="output)

xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, y)
loss = tf.reduce_mean(xentropy, name="loss")
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
training_op = optimizer.minimize(loss)

init = tf.initialize_all_variables()
saver = tf.train.Saver()

# ... Train then save the network using the saver

加载此网络、锁定 2 个较低隐藏层并替换输出层的代码是什么?如果可能的话,最好能够为每个输入缓存顶部锁定层(hidden2)的输出,以加快训练速度。

更多细节

我查看了retrain.py 和相应的How-To(非常有趣的读物)。该代码基本上加载了原始模型,然后计算每个输入的瓶颈层(即输出层之前的最后一个隐藏层)的输出。然后它创建一个全新的模型并使用瓶颈输出作为输入对其进行训练。这基本上回答了我对复制+锁定层的问题:我只需要在整个训练集上运行原始模型并存储最顶层锁定层的输出。但我不知道如何处理复制但未锁定(即可训练)的层(例如,我图中的隐藏层 3)。

谢谢!

【问题讨论】:

  • 您好,您找到解决方案了吗?我和你处理同样的问题。

标签: neural-network tensorflow


【解决方案1】:

TensorFlow 可让您对在每个训练步骤中更新的参数集 (Variables) 进行精细控制。例如,在您的模型中,假设所有层都是全连接层。然后你会有一个 weights 参数和每个层的 biases 参数。假设您在W1b1W2b2W3b3Woutputboutput 中有相应的Variable 对象。假设您使用的是Optimizer 接口,并且假设loss 是您要最小化的值,您只能通过执行以下操作训练隐藏层和输出层:

opt = GradientDescentOptimizer(learning_rate=0.1)
grads_and_vars = opt.compute_gradients(loss, var_list=[W3, b3, Woutput, boutput])
train_op = opt.apply_gradients(grads_and_vars)

注意opt.minimize(loss, var_list) 的作用与上述相同,但我将其一分为二来说明细节。

opt.compute_gradients 计算与特定模型参数集相关的梯度,您可以完全控制您认为的模型参数。请注意,您必须从旧模型初始化隐藏层 3 参数,并随机初始化输出层参数。您可以通过从原始模型恢复您的新模型来做到这一点,该模型将从原始模型中复制所有参数,并添加额外的tf.assign 操作以随机初始化输出层参数。

【讨论】:

  • 太棒了!但是,我仍然有两个问题:(1)如果我使用fully_connected() 之类的东西创建图层中的变量列表,如何获取它?我希望能够写一些简单的东西,比如get_variables_in_scope("hidden3")。 (2) 如何更换顶层?另外,我不确定这个解决方案是否允许我缓存锁定层的输出。
  • 嗨 - 你有这个想法吗?我想做类似的事情,但遇到了同样的问题。
猜你喜欢
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 2018-08-19
  • 2019-05-19
  • 1970-01-01
  • 2017-05-23
  • 2010-11-20
相关资源
最近更新 更多