【发布时间】:2021-04-03 07:39:30
【问题描述】:
我正在尝试为 tensorflow.keras 创建自定义损失函数的多种变体
我已经成功创建了一个似乎有效的自定义指标,现在我想在计算损失时使用该指标。
这是自定义指标,用于计算 y_true 和 y_pred 之间的 spearman 等级相关性...
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import tensorflow_probability as tfp
class Correlation(keras.metrics.Metric):
def __init__(self, name="Correlation", **kwargs):
super(Correlation, self).__init__(name=name, **kwargs)
self.metric = self.add_weight(name='correlation_01', initializer='zeros')
def update_state(self, y_true, y_pred, sample_weight=None):
y_true_flat = layers.Flatten()(y_true)
y_pred_flat = layers.Flatten()(y_pred)
y_true_rank = tf.cast(tf.argsort(y_true_flat, axis=0, direction="ASCENDING"), 'float32')
y_pred_rank = tf.cast(tf.argsort(y_pred_flat, axis=0, direction="ASCENDING"), 'float32')
cov = tfp.stats.covariance(y_true_rank, y_pred_rank, sample_axis=0, event_axis=None)
std_y_trueR = tfp.stats.stddev(y_true_rank, sample_axis=0, keepdims=False, name="STD_TRUE")
std_y_predR = tfp.stats.stddev(y_pred_rank, sample_axis=0, keepdims=False, name="STD_PRED")
#corr = cov/(std_y_trueR * std_y_predR)
corr = tf.math.divide(cov,tf.math.multiply(std_y_trueR,std_y_predR))
self.metric.assign(corr[0])
def result(self):
return self.metric
def reset_states(self):
# reset state of metric at the start of each epoch
self.metric.assign(0.0)
我不知道如何将其直接与 loss 联系起来,所以我想我会按照文档中的示例开始,这些示例建议创建一个函数并将其传递给编译。所以我复制了上面的代码,并通过从 1.0 中减去它来将相关性转换为损失
def correlation_loss(y_true, y_pred):
y_true_flat = layers.Flatten()(y_true)
y_pred_flat = layers.Flatten()(y_pred)
y_true_rank = tf.cast(tf.argsort(y_true_flat, axis=0, direction="ASCENDING"), 'float32')
y_pred_rank = tf.cast(tf.argsort(y_pred_flat, axis=0, direction="ASCENDING"), 'float32')
cov = tfp.stats.covariance(y_true_rank, y_pred_rank, sample_axis=0, event_axis=None)
std_y_trueR = tfp.stats.stddev(y_true_rank, sample_axis=0, keepdims=False, name="LOSS_STD_TRUE")
std_y_predR = tfp.stats.stddev(y_pred_rank, sample_axis=0, keepdims=False, name="LOSS_STD_PRED")
corr = tf.math.divide(cov,tf.math.multiply(std_y_trueR,std_y_predR))
loss = tf.math.subtract(1.0,corr[0])
return loss
我用以下方法编译了模型:
model.compile(optimizer='Adam', loss=correlation_loss, metrics=[Correlation()])
但是,当我尝试训练模型时,我得到一个关于 No gradients provided for any variable 的 ValueError
我很想知道我做错了什么。更具体地说,是否有推荐的方法在不涉及第二次重新计算的损失计算中使用度量?
【问题讨论】:
-
可以分享模型吗?
compile方法还会引发Error或fit方法吗?看看这里。您的错误可能是语法错误。看这里:stackoverflow.com/questions/61249708/…
标签: python tensorflow keras