43

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

我试过的

def loss_fn(y_true, y_pred):
    print y_true

它打印

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

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

4

8 回答 8

31

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 文档

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

因此,请确保之后使用张量。

于 2018-04-18T14:18:05.667 回答
5

通常,y_true您会提前知道-在准备火车公司时...

但是,有一个技巧可以查看y_true和/或y_pred. Keras 让您有机会编写相应的回调来打印神经网络的输出。它看起来像这样:

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()])

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

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

于 2017-04-17T09:41:49.717 回答
3

如果你使用 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 调试技巧 3中所述:

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

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

于 2018-11-15T15:16:50.840 回答
3

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

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)
于 2019-07-16T15:13:52.953 回答
1

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

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) 



于 2020-11-25T14:31:40.817 回答
0

我用

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

用于调试。

于 2019-02-25T13:46:03.383 回答
0

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

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

于 2017-05-01T07:00:37.427 回答
0

要获得任意层 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)
于 2020-12-19T08:33:13.563 回答