我正在尝试使用Keras作为后端的非常简单的TensorFlow2.0模型编写自定义损失函数。
我的目标是,如果输入张量中的每个元素大于阈值,则将其替换为1;如果低于阈值,则将其替换为0;对标签张量执行相同的操作,然后计算标准mse。
例如:
a = [0.34, 0.22, 0.86, 0.65]
b = [0.14, 0.32, 0.67, 0.99]
threshold = 0.3
# do stuff
transformed_a = [1, 0, 1, 1]
transformed_b = [0, 1, 1, 1]
# compute mse between transformed_a and transformed_b
因此我将自定义损失函数定义为:
def custom_mse(y_pred, y_true):
y_pred = tf.where(y_pred>0.2, tf.ones_like(y_pred), tf.zeros_like(y_pred))
y_true = tf.where(y_true<0.3, tf.ones_like(y_true), tf.zeros_like(y_true))
return tf.reduce_mean(tf.math.squared_difference(y_pred, y_true))
该功能可以正常工作。但是,当我尝试使用它来训练模型时,出现此错误:
ValueError: No gradients provided for any variable: ['sequential_12/dense_23/kernel:0', 'sequential_12/dense_23/bias:0', 'sequential_12/dense_24/kernel:0', 'sequential_12/dense_24/bias:0'].
但是,如果我将自定义损失用作:
def custom_mse(y_pred, y_true):
return tf.reduce_mean(tf.math.squared_difference(y_pred, y_true))
没有错误出现。我对此有些困惑。为什么要在哪里更改某些内容?我缺少什么?谢谢您的帮助。
这是一个最小的工作示例:
import numpy as np
import tensorflow as tf
def custom_mse(y_pred, y_true):
y_pred = tf.where(y_pred>0.2, tf.ones_like(y_pred), tf.zeros_like(y_pred))
y_true = tf.where(y_true<0.3, tf.ones_like(y_true), tf.zeros_like(y_true))
return tf.reduce_mean(tf.math.squared_difference(y_pred, y_true))
input = np.random.rand(1000,10)
labels = np.random.rand(1000,10)
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(5))
model.add(tf.keras.layers.Dense(10))
model.compile(optimizer='adam', loss=custom_mse)
model.fit(input, labels, epochs=1)
以及我得到的输出:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-71-4c747bcd54b7> in <module>()
----> 1 model.fit(input, labels, epochs=1)
10 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args,
**kwargs)
966 except Exception as e: # pylint:disable=broad-except
967 if hasattr(e, "ag_error_metadata"):
--> 968 raise e.ag_error_metadata.to_exception(e)
969 else:
970 raise
ValueError: in user code:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:571 train_function *
outputs = self.distribute_strategy.run(
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:951 run **
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2290 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2649 _call_for_each_replica
return fn(*args, **kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:541 train_step **
self.trainable_variables)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1807 _minimize
trainable_variables))
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py:521 _aggregate_gradients
filtered_grads_and_vars = _filter_grads(grads_and_vars)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py:1219 _filter_grads
([v.name for _, v in grads_and_vars],))
ValueError: No gradients provided for any variable: ['sequential_12/dense_23/kernel:0', 'sequential_12/dense_23/bias:0', 'sequential_12/dense_24/kernel:0', 'sequential_12/dense_24/bias:0'].