【问题标题】:Tensorflow load pre-trained model use different optimizerTensorFlow 加载预训练模型使用不同的优化器
【发布时间】:2017-11-26 09:42:25
【问题描述】:

我想加载一个预训练模型(由 AdadeltaOptimizer 优化)并继续使用 SGD(GradientDescentOptimizer)进行训练。模型使用tensorlayer API保存和加载:

保存模型:

import tensorlayer as tl
tl.files.save_npz(network.all_params,
                  name=model_dir + "model-%d.npz" % global_step)

加载模型:

load_params = tl.files.load_npz(path=resume_dir + '/', name=model_name)
tl.files.assign_params(sess, load_params, network)

如果我继续使用 adadelta 进行训练,训练损失(交叉熵)看起来很正常(从加载模型的接近值开始)。但是,如果我将优化器更改为 SGD,训练损失将与新初始化的模型一样大。

我查看了来自tl.files.save_npzmodel-xxx.npz 文件。它只将所有模型参数保存为 ndarray。我不确定优化器或学习率是如何在这里涉及的。

【问题讨论】:

    标签: optimization tensorflow pre-trained-model


    【解决方案1】:

    https://tensorlayer.readthedocs.io/en/latest/user/get_start_advance.html#pre-trained-cnn

    vgg = tl.models.vgg16(pretrained=True)
    img = tl.vis.read_image('data/tiger.jpeg')
    img = tl.prepro.imresize(img, (224, 224)).astype(np.float32) / 255
    output = vgg(img, is_train=False)
    

    2.0版本用这个

    【讨论】:

      【解决方案2】:

      您可能必须将张量导入一个变量,该变量是之前输入 Adam 优化器的损失函数/交叉熵。现在,只需通过您的 SGD 优化器将其提供给它。

      saver = tf.train.import_meta_graph('filename.meta')
      saver.restore(sess,tf.train.latest_checkpoint('./'))
      graph = tf.get_default_graph()
      cross_entropy = graph.get_tensor_by_name("entropy:0") #Tensor to import
      
      optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)
      

      在这种情况下,我在使用名称entropy 训练我的预训练模型之前标记了交叉熵张量,因此

      tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv), name = 'entropy')
      

      如果您无法对预训练模型进行更改,您可以从graph 获取模型中的 Tensor 列表(导入后),然后推断您需要哪个 Tensor。我没有使用 Tensorlayer 的经验,因此本指南旨在提供更多的理解。你可以看看Tensorlayer-Layers,他们应该解释如何获得你的张量。由于 Tensorlayer 建立在 Tensorflow 之上,因此大部分功能应该仍然可用。

      【讨论】:

      • 感谢您的回答。但我很困惑为什么我必须导入张量“它在你的 Adam Optimizer 上计算先前的损失”。无论优化器如何,考虑到相同的模型参数,损失应该是相同的,对吧?
      • 我已经对我的答案进行了更改,希望这更清楚。如此有效,我只是将优化器的类型从 Adam 更改为 SGD。
      【解决方案3】:

      您可以指定要保存在检查点文件中的参数。

      save_npz([save_list, name, sess])
      

      save_list 中,您只指定了不包含优化器参数的网络参数,因此没有学习率或任何其他优化器参数。

      如果您想保存当前的学习率(以便在恢复模型时使用相同的准确学习率),您必须将其添加到save_list,如下所示:

      save_npz(network.all_params.extend([learning_rate])
      

      (我猜all_params是一个数组,我猜我的猜想是对的。

      由于您要更改优化器,我建议您仅将learning_rate 保存为优化器参数,而不是优化器创建的任何其他变量。 这样,您将能够更改优化器并恢复模型,否则(如果您将检查点放入任何其他变量)您将尝试恢复的图形将找不到放置保存值的变量而且您将无法更改它。

      【讨论】:

      • 面对我只保存了network.all_params,它不包含adadelta创建的任何其他变量,对吧?我也没有保存学习率,而是在恢复模型后为 SGD 分配初始学习率。
      猜你喜欢
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 2017-05-15
      相关资源
      最近更新 更多