【问题标题】:Confusion about keras Model: __call__ vs. call vs. predict methods关于 keras 模型的困惑:__call__ vs. call vs. predict 方法
【发布时间】:2020-03-24 19:26:49
【问题描述】:

我意识到我不太明白调用 Keras 模型的 __call__callpredict 方法之间的区别。

例如,我们有一个经过训练的 keras 模型。调用代码后:

# After training.
y_pred_1 = model(X_new)
y_pred_2 = model.call(X_new)
y_pred_3 = model.predict(X_new)

我预计y_pred_1y_pred_2y_pred_3 都是一样的。 但事实证明它们并不相同。

你能解释一下区别吗?

【问题讨论】:

  • 嗨@Dmitry Kabanov,请提供有关此的更多信息,可能是屏幕截图或可重现的代码。谢谢!
  • @TF_Support,原来这个错误在我的代码中。抱歉,忘记关闭此问题。

标签: tensorflow keras


【解决方案1】:

只是为了补充答案,因为我也在寻找这个。当您需要为推理阶段指定模型的训练标志时,例如model(X_new, training=False),当您有批量归一化层时,例如,predictpredict_on_batch 在执行时都已经这样做了。

所以,model(X_new, training=False)model.predict_on_batch(X_new) 是等价的。

predictpredict_on_batch 之间的区别在于,后者运行在单个批次上,而前者运行在一个数据集上,该数据集被分成多个批次,结果合并以产生最终的 numpy 预测数组。

除了@Dmitry Kabanov 提到的差异之外,这些函数会生成不同类型的输出, __call__ 生成一个张量,predictpredict_on_batch 生成 numpy.ndarray,和 according to the documentation__call__predict 函数更快,适用于小规模输入,即适合一批。

【讨论】:

    【解决方案2】:

    除了@Dmitry Kabanov,它们很相似,但并不完全相同。如果您关心性能,则需要研究它们之间的关键差异。

    model.predict model(x)
    loops over the data in batches which means means that predict() calls can scale to very large arrays. happens in-memory and doesn't scale
    not differentiable differentiable
    use this if you just need the output value use this when you need to retrieve the gradients
    Output is NumPy value Output is a Tensor
    use this if you have batches of data to be predicted use this for small dataset
    relatively slower for small data relatively faster for small data

    更详细的解释请查看Keras FAQs

    【讨论】:

      【解决方案3】:

      2021 年 12 月 18 日更新。请参阅下面@TFer2 的答案以获得更好和更全面的答案。


      我自己的旧答案只发现数据类型的差异(tf.Tensor vs np.ndarray)

      我的错,这是我的代码中的一个错误。

      原来这三种方法没有本质区别。

      唯一的区别是call 只接受张量,而其他两种方法也接受 NumPy 数组。

      这是一个玩具代码,显示三个方法是相同的:

      import numpy as np
      import tensorflow as tf
      
      
      model = tf.keras.Sequential(
          [
              tf.keras.layers.InputLayer(input_shape=(2, )),
              tf.keras.layers.Dense(2),
          ]
      )
      model.compile(loss='mse')
      
      W = model.trainable_variables[0]
      W.assign(np.array([[1.0, 0.0], [0.0, 1.0]]).T)
      
      input = np.array([[1.0, 2.0], [3.0, 4.0], ], dtype=np.float32)
      
      print("__call__:")
      print(model(input))
      
      print("Call:")
      print(model.call(tf.convert_to_tensor(input)))
      
      print("Predict:")
      print(model.predict(input))
      

      【讨论】:

        【解决方案4】:

        我认为当您使用其中一个特定层时会有所不同:DropOut()BatchNormalization()。事实上,无论是在训练模式还是测试/评估模式下,这些层的作用都不同。

        call()predict() 之间的区别在于,call() 在训练模式下给出预测,predict() 在测试模式下给出预测。这两者之间的区别在于,每次使用call()predict() 时,预测都不相同。训练和测试模式类似于Pytorch 库的训练和测试模式。

        【讨论】:

          猜你喜欢
          • 2018-07-15
          • 2013-08-03
          • 1970-01-01
          • 1970-01-01
          • 2021-06-27
          • 1970-01-01
          • 2015-04-28
          • 2013-09-09
          • 2021-01-06
          相关资源
          最近更新 更多