【问题标题】:Function works in a session but not as Keras loss function函数在会话中工作,但不能作为 Keras 损失函数
【发布时间】:2019-10-12 00:25:39
【问题描述】:

我正在 keras 中编写自定义损失函数。

def custom_loss(y_true, y_pred):
    c1 = (0.01 ** 2)
    c2 = (0.03 ** 2)

    y_true = tf.transpose(y_true, [0, 2, 3, 1])
    y_pred = tf.transpose(y_pred, [0, 2, 3, 1])

    patches_true = tf.extract_image_patches(y_true, [1, 8, 8, 1], [1, 8, 8, 1], [1, 1, 1, 1], "SAME")
    patches_pred = tf.extract_image_patches(y_pred, [1, 8, 8, 1], [1, 8, 8, 1], [1, 1, 1, 1], "SAME")

    # Get mean
    u_true = K.mean(patches_true, axis=-1)
    u_pred = K.mean(patches_pred, axis=-1)
    # Get variance
    var_true = K.var(patches_true, axis=-1)
    var_pred = K.var(patches_pred, axis=-1)
    # Get std dev
    std_true = K.sqrt(var_true)
    std_pred = K.sqrt(var_pred)
    covar_true_pred = std_pred * std_true

    ssim = (2 * u_true * u_pred + c1) * (2 * covar_true_pred + c2)
    denom = (K.square(u_true) + K.square(u_pred) + c1) * (var_pred + var_true + c2)
    ssim /= denom  

    return K.mean((1.0 - ssim) / 2.0)

运行如下:

test = tf.Variable(np.full((1,1, 32, 32), 10)/255.0)
test_1 = tf.concat([test, tf.Variable(np.full((1,1, 32, 32), 15)/255.0)], 0)
test_1 = tf.concat([test_1, tf.Variable(np.full((1,1, 32, 32), 20)/255.0)], 0)
test_1 = tf.cast(test_1, tf.float32)

test = tf.Variable(np.full((1,1, 32, 32), 30)/255.0)
test_2 = tf.concat([test, tf.Variable(np.full((1,1, 32, 32), 40)/255.0)], 0)
test_2 = tf.concat([test_2, tf.Variable(np.full((1,1, 32, 32), 50)/255.0)], 0)
test_2 = tf.cast(test_2, tf.float32)
test =  custom_loss(test_1, test_2)
init_op = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init_op) #execute init_op
    print (sess.run(test))

工作正常,其中 test_1 和 test_2 是我创建的测试变量。

但是,当我将该函数设置为 Keras 模型的自定义损失时:

model.compile(optimizer=SGD(lr=0.01, momentum=0.9, decay=0.0, nesterov=False),
              loss=custom_loss, 
              metrics = ['mse', 'mae', PSNR, SSIM])

我收到一个错误:

Traceback (most recent call last):
  File "kerasmodel_const_init_customloss.py", line 434, in <module>
    model.fit(x=[np.array(training_data_LR), np.array(training_data_MC)], y=[np.array(training_data_HR)], batch_size=128, epochs=2, verbose=1, validation_data=([np.array(validation_data_LR), np.array(validation_data_MC)], np.array(validation_data_HR)), shuffle=True, callbacks=[log_callback, checkpoint_callback])
  File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 965, in fit
    validation_steps=validation_steps)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1646, in fit
    self._make_train_function()
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 970, in _make_train_function
    loss=self.total_loss)
  File "/usr/local/lib/python2.7/dist-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/keras/optimizers.py", line 162, in get_updates
    grads = self.get_gradients(loss, params)
  File "/usr/local/lib/python2.7/dist-packages/keras/optimizers.py", line 78, in get_gradients
    grads = K.gradients(loss, params)
  File "/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.py", line 2512, in gradients
    return tf.gradients(loss, variables, colocate_gradients_with_ops=True)
  File "/home/joe/.local/lib/python2.7/site-packages/tensorflow/python/ops/gradients_impl.py", line 609, in gradients
    grad_scope, op, func_call, lambda: grad_fn(op, *out_grads))
  File "/home/joe/.local/lib/python2.7/site-packages/tensorflow/python/ops/gradients_impl.py", line 375, in _MaybeCompile
    return grad_fn()  # Exit early
  File "/home/joe/.local/lib/python2.7/site-packages/tensorflow/python/ops/gradients_impl.py", line 609, in <lambda>
    grad_scope, op, func_call, lambda: grad_fn(op, *out_grads))
  File "/home/joe/.local/lib/python2.7/site-packages/tensorflow/python/ops/array_grad.py", line 733, in _ExtractImagePatchesGrad
    rows_out = int(ceil(rows_in / stride_r))
TypeError: unsupported operand type(s) for /: 'NoneType' and 'long'

这是 Keras 中的一些错误还是我的错误?有什么问题?

【问题讨论】:

  • 您应该显示出现问题的代码段以及没有出现问题的位置
  • 嗨,刚刚更新了问题。基本上我只是将它设置为我的模型的损失函数,如图所示。谢谢
  • 我看到整个堆栈跟踪都在 Keras 和 TF 中,除了第一次调用。您是否检查了model.fit 调用的所有参数是否正确?特别是,所有数组都包含合理的数据,并且大小合适?
  • 嗨 9000。如果我将损失设置为 Keras 的损失函数之一,该模型可以正常工作。此外,当我使用我编写的另一个函数时,它不会返回任何错误,该函数计算 PSNR(当前用作指标)
  • @9000 ,堆栈跟踪可能指向 model.fit 函数,因为它是入口点,不是吗?

标签: python python-2.7 tensorflow keras deep-learning


【解决方案1】:

这个问题真的很棘手。出于某种原因 - 输出张量的形状具有(None, None, 1) 的输出,即使它可能是从之前的层计算的。添加Reshape(appropriate_size) 修复了一个问题。这可能是keras 的问题,应该报告。

【讨论】:

    猜你喜欢
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 2020-06-06
    • 2023-03-05
    • 1970-01-01
    • 2019-09-28
    • 2019-12-11
    相关资源
    最近更新 更多