Я пытаюсь написать собственную функцию потерь для очень простой модели TensorFlow2.0, используя Keras в качестве бэкэнда.
Моя цель - заменить каждый элемент во входном тензоре на 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))
Никаких ошибок не появляется. Я немного запутался по этому поводу. Почему tf.where должен что-то изменить? Что мне не хватает? Спасибо за любую помощь.
Вот минимальный рабочий пример:
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'].