【问题标题】:How can I print the values of Keras tensors?如何打印 Keras 张量的值?
【发布时间】:2017-09-12 20:49:16
【问题描述】:

我正在实现自己的 Keras 损失函数。如何访问张量值?

我尝试过的

def loss_fn(y_true, y_pred):
    print y_true

打印出来

Tensor("target:0", shape=(?, ?), dtype=float32)

是否有任何 Keras 函数可以访问 y_true 值?

【问题讨论】:

  • 如何打印它的值?我这样做了,没有任何结果。使用 TensorFlow 后端。

标签: python neural-network keras tensor


【解决方案1】:

通常,y_true 您会提前知道 - 在准备火车语料库时...

但是,查看y_true 和/或y_pred 中的值有一个技巧。 Keras 让您有机会编写各自的callback 来打印神经网络的输出。 它看起来像这样:

def loss_fn(y_true, y_pred):
    return y_true # or y_pred
...
import keras.callbacks as cbks
class CustomMetrics(cbks.Callback):

    def on_epoch_end(self, epoch, logs=None):
        for k in logs:
            if k.endswith('loss_fn'):
               print logs[k]

这里loss_fn 是您在模型编译期间将其传递给model.compile(...,metrics=[loss_fn],) 函数时的损失函数的名称。

所以,最后,您必须将此 CustomMetrics 回调作为参数传递给 model.fit()

model.fit(x=train_X, y=train_Y, ... , callbacks=[CustomMetrics()])

P.S.:如果你在 Keras 中使用 Theano(或 TensorFlow),你可以编写一个 Python 程序,然后编译并执行它。因此,在您的示例中,y_true - 只是一个张量变量,用于进一步编译和损失函数计数。

这意味着无法查看其中的值。例如,在 Theano 中,您可以在执行相应的 eval() 函数后查看唯一所谓的共享变量。有关更多信息,请参阅this question

【讨论】:

    【解决方案2】:

    您不能直接从张量符号变量中获取值。你需要编写一个 theano 函数来提取值。不要忘记选择 theano 作为 Keras 的后端。

    查看笔记本链接以获取一些基本的 theano 变量和函数:get tensor value in call function of own layers

    【讨论】:

      【解决方案3】:

      Keras 的后端有print_tensor,它使您能够做到这一点。你可以这样使用它:

      import keras.backend as K
      
      def loss_fn(y_true, y_pred):
          y_true = K.print_tensor(y_true, message='y_true = ')
          y_pred = K.print_tensor(y_pred, message='y_pred = ')
          ...
      

      函数返回一个相同的张量。当评估该张量时,它将打印其内容,前面是message。 来自Keras docs

      请注意,print_tensor 返回一个与 x 相同的新张量,应在以下代码中使用。否则在评估期间不考虑打印操作。

      所以,请确保之后使用张量。

      【讨论】:

      • 这看起来不错,但较长的张量不会被完整打印(例如:softmax = [[0.0599291697 0.0380649045 0.0828271]...])。您是否知道一种将它们全部打印出来的方法(或者至少控制它们的打印时间?)
      • @Pablo 我找不到对此功能的任何引用。使用tensorflow后端,print_tensor的实现使用tf.Print,它接收可以提供这个功能的summarize参数,但是Keras的print_tensor不转发那个参数。您可以尝试手动将summarize 参数添加到print_tensor
      • 是的,这可能是唯一的方法 (github.com/keras-team/keras/issues/10566)
      【解决方案4】:

      如果你使用的是TensorFlow的keras,可以开启Eager Execution

      import tensorflow as tf 
      tf.enable_eager_execution()
      

      之后,您可以在损失函数中打印张量。

      如果您收到错误消息“ValueError:Eager 模式仅支持 TF 原生优化器”。例如,您已使用“adam”作为优化器,您可以将模型的编译参数更改为

      model.compile(optimizer = tf.train.AdamOptimizer(), loss = loss_fn, ...)
      

      更新:TensorFlow 2.x

      您只需要为 Keras 模型的 Eager Execution 启用“run_eagerly”参数,如Keras debugging tip 3 所述:

      model.compile(..., run_eagerly = True)
      

      之后,您可以使用print(y_true)tf.print(y_true)K.print_tensor(y_true) 在自定义损失函数中输出张量。

      【讨论】:

      • 这对我不起作用。损失函数中的print()tf.print()K.print_tensor 都不起作用
      • @Rylan:我已经更新了我对 TensorFlow 2 的回答。希望它对你有用!
      【解决方案5】:

      我用

      print("y_true = " + str(y_true.eval()))
      

      用于调试。

      【讨论】:

        【解决方案6】:

        您可以重新定义损失函数以返回值:

        def loss_fn(y_true, y_pred):
            return y_true
        

        让我们创建一些张量:

        from keras import backend as K
        
        a = K.constant([1,2,3])
        b = K.constant([4,5,6])
        

        并使用keras.backend.eval() API 评估您的损失函数:

        loss = loss_fn(a,b)
        K.eval(loss)
        # array([1., 2., 3.], dtype=float32)
        

        【讨论】:

          【解决方案7】:

          要打印张量的值,您需要张量具有价值 例如:

          import tensorflow as tf
          
          aa = tf.constant([1,5,3])
          bb = keras.layers.Dense(4, name="my_tensor")
          print('aa:',aa)
          print('bb:',bb)
          
          
          aa: tf.Tensor([1 5 3], shape=(3,), dtype=int32)
          bb: <tensorflow.python.keras.layers.core.Dense object at 0x000001D4B0137048>
          

          如果我想打印 b 我需要给他一个输入 像这样:

          aa = tf.constant([[1,5,3]])
          bb = keras.layers.Dense(4, name="my_tensor")
          print('bb.weights before a assign:',bb.weights,'\n')
          print('bb:',bb(aa),'\n')                               
          print('bb.weights:',bb.weights)
          

          输出:

          bb.weight before a assign: [] 
          
          bb: tf.Tensor([[1.0374807 3.4536252 1.5064619 2.1762671]], shape=(1, 4), dtype=float32) 
          
          bb.weight: [<tf.Variable 'my_tensor/kernel:0' shape=(3, 4) dtype=float32, numpy=
          array([[ 0.885918  , -0.88332534, -0.40944284, -0.04479438],
                 [-0.27336687,  0.34549594, -0.11853147,  0.15316617],
                 [ 0.50613236,  0.8698236 ,  0.83618736,  0.4850769 ]],
                dtype=float32)>, <tf.Variable 'my_tensor/bias:0' shape=(4,) dtype=float32, numpy=array([0., 0., 0., 0.], dtype=float32)>]
          

          如果 bb 是模型内的张量或输入大小固定的张量,则此操作无效

          inputs = keras.Input(shape=(3,), name="inputs")
          b = keras.layers.Dense(4, name="my_tensor")(inputs)
          
          a = tf.constant([[1,5,3]])
          print('b:',b(a),'\n')
          

          输出:

          TypeError: 'tensorflow.python.framework.ops.EagerTensor' object is not callable
          

          我使用 feature_extractor 来修复它:

          inputs = keras.Input(shape=(3,), name="inputs")
          bb = keras.layers.Dense(4, name="my_tensor")(inputs)
          
          feature_extractor = keras.Model(
              inputs=inputs,
              outputs=bb,
          )
          
          aa = tf.constant([[1,5,3]])
          print('feature_extractor:',feature_extractor(aa),'\n')
          

          输出:

          feature_extractor: tf.Tensor([[-4.9181094  4.956725  -1.8055304  2.6975303]], shape=(1, 4), dtype=float32) 
          
          
          
          

          【讨论】:

            【解决方案8】:

            要获得任意层 keras 张量的输出值(“如何打印 Keras 张量的值?”),似乎需要不同的解决方案。打印单层的输出(来自https://stackoverflow.com/a/65288168/2585501):

            from tensorflow.keras import backend as K
            layerIndex = 1
            func = K.function([model.get_layer(index=0).input], model.get_layer(index=layerIndex).output)
            layerOutput = func([input_data])  # input_data is a numpy array
            print(layerOutput)
            

            【讨论】:

              猜你喜欢
              • 2021-12-16
              • 2020-01-17
              • 2023-01-11
              • 2020-01-08
              • 2018-06-26
              • 2019-07-28
              • 2017-01-14
              • 2019-08-13
              相关资源
              最近更新 更多