【问题标题】:Altering the tensorflow graph and resuming training更改张量流图并恢复训练
【发布时间】:2023-03-04 04:33:01
【问题描述】:

我正在尝试加载 MCnet model 的预训练权重并继续训练。此处提供的预训练模型使用参数K=4, T=7 进行训练。但是,我想要一个参数为K=4,T=1 的模型。我不想从头开始训练,而是想从这个预训练模型中加载权重。但由于图表发生了变化,我无法加载预训练模型。

InvalidArgumentError (see above for traceback): Restoring from checkpoint failed. This is most likely due to a mismatch between the current graph and the graph from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint. Original error:

Assign requires shapes of both tensors to match. lhs shape= [5,5,15,64] rhs shape= [5,5,33,64]
     [[node save/Assign_13 (defined at /media/nagabhushan/Data02/SNB/IISc/Research/04_Gaming_Video_Prediction/Workspace/VideoPrediction/Literature/01_MCnet/src/snb/mcnet.py:108) ]]

是否可以使用新图加载预训练模型?

我的尝试
以前,我想将预训练模型从旧版本的 tensorflow 移植到新版本。我在 SO 中得到了this answer,这帮助我移植了模型。这个想法是创建新图表并从保存的图表中加载新图表中存在的变量。

with tf.Session() as sess:
    _ = MCNET(image_size=[240, 320], batch_size=8, K=4, T=1, c_dim=3, checkpoint_dir=None, is_train=True)
    tf.global_variables_initializer().run(session=sess)

    ckpt_vars = tf.train.list_variables(model_path.as_posix())
    ass_ops = []
    for dst_var in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES):
        for (ckpt_var, ckpt_shape) in ckpt_vars:
            if dst_var.name.split(":")[0] == ckpt_var and dst_var.shape == ckpt_shape:
                value = tf.train.load_variable(model_path.as_posix(), ckpt_var)
                ass_ops.append(tf.assign(dst_var, value))

    # Assign the variables
    sess.run(ass_ops)
    saver = tf.train.Saver()
    saver.save(sess, save_path.as_posix())

我在这里尝试了同样的方法,它成功了,这意味着我为K=4,T=1 获得了一个新的训练模型。但我不确定它是否有效!我的意思是,权重有意义吗?这是正确的做法吗?

有关模型的信息
MCnet 是用于视频预测的模型,即给定 K 过去的帧,它可以预测下一个 T 帧。

感谢任何帮助

【问题讨论】:

  • 你可以从原始模型中加载权重,并可能添加零或一(或一些权重初始化器)来填充其余部分。
  • 这里正好相反。我的新模型的参数较少(我猜)。由于该模型使用 LSTM,我不确定丢弃一些权重是否可以,或者会对我产生负面影响。
  • 哦,我明白了,您可以列出权重矩阵吗?这样(如果可能的话)人们可以弄清楚要有意义地降低哪些权重
  • 你的意思是在这里列出参数?估计会太多了。

标签: python tensorflow


【解决方案1】:

MCnet 模型有一个生成器和一个鉴别器。生成器基于 LSTM,因此通过改变时间步数T 来加载权重没有问题。然而,正如他们编码的那样,鉴别器是卷积的。为了在视频上应用卷积层,它们在通道维度上连接帧。使用K=4,T=7,您可以获得长度为113 频道的视频。当你沿着通道维度连接它们时,你会得到一个带有33 通道的图像。当他们定义鉴别器时,他们将鉴别器的第一层定义为具有33 输入通道,因此权重具有相似的维度。但是对于K=4,T=1,视频长度为5,最终图像具有15 通道,因此权重将有15 个通道。这是您观察到的不匹配错误。要解决此问题,您可以仅从前 15 个通道中选择权重(我想不出更好的方法)。代码如下:

with tf.Session() as sess:
    _ = MCNET(image_size=[240, 320], batch_size=8, K=4, T=1, c_dim=3, checkpoint_dir=None, is_train=True)
    tf.global_variables_initializer().run(session=sess)

    ckpt_vars = tf.train.list_variables(model_path.as_posix())
    ass_ops = []
    for dst_var in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES):
        for (ckpt_var, ckpt_shape) in ckpt_vars:
            if dst_var.name.split(":")[0] == ckpt_var:
                if dst_var.shape == ckpt_shape:
                    value = tf.train.load_variable(model_path.as_posix(), ckpt_var)
                    ass_ops.append(tf.assign(dst_var, value))
                else:
                    value = tf.train.load_variable(model_path.as_posix(), ckpt_var)
                    if dst_var.shape[2] <= value.shape[2]:
                        adjusted_value = value[:, :, :dst_var.shape[2]]
                    else:
                        adjusted_value = numpy.random.random(dst_var.shape)
                        adjusted_value[:, :, :value.shape[2], ...] = value
                    ass_ops.append(tf.assign(dst_var, adjusted_value))

    # Assign the variables
    sess.run(ass_ops)
    saver = tf.train.Saver()
    saver.save(sess, save_path.as_posix())  

【讨论】:

    猜你喜欢
    • 2021-12-04
    • 1970-01-01
    • 2017-09-14
    • 2020-12-29
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    相关资源
    最近更新 更多