[英]Confusion with custom loss for tensorflow keras
我正在尝试遵循为 tensorflow.keras 创建自定义损失 function 的多种变化
我已经成功创建了一个似乎有效的自定义指标,现在我想在计算损失时使用该指标。
这是自定义指标,它计算 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)
我不知道如何将其直接与损失联系起来,所以我想我将按照文档中的示例开始,这些示例建议创建 function 并将其传递给编译。 所以我复制了上面的代码,并通过从 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 :
model.compile(optimizer='Adam', loss=correlation_loss, metrics=[Correlation()])
但是,当我尝试训练 model 时,我收到关于No gradients provided for any variable
的ValueError
我很想知道我做错了什么。 更具体地说,是否有推荐的方法在损失计算中使用不涉及第二次重新计算的度量?
感谢您在仔细阅读后将我指向另一篇文章,我调整了我的 function 以确保每一层都被标记,这似乎纠正了问题。
我的 function 还有一个问题,它没有正确计算 Spearman Rank 相关性。 我在这里发布了我的代码的解决方案,其中排名部分已注释掉,因此它将返回标准的 Pearson 相关性,但这似乎至少适用于训练循环。
def correlation_loss(y_true, y_pred):
y_true_flat = layers.Flatten(name="Y_TRUE_FLAT")(y_true)
y_pred_flat = layers.Flatten(name="Y_PRED_FLAT")(y_pred)
##-## I can't seem to get the proper ranking for Spearman Correlation
##-## Just to have something that functions, I've commented these out for now
#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_flat, y_pred_flat, sample_axis=0, event_axis=None, name="COVARIANCE")
std_y_trueR = tfp.stats.stddev(y_true_flat, sample_axis=0, keepdims=False, name="LOSS_STD_TRUE")
std_y_predR = tfp.stats.stddev(y_pred_flat, sample_axis=0, keepdims=False, name="LOSS_STD_PRED")
corr = tf.math.divide(cov,tf.math.multiply(std_y_trueR,std_y_predR, name="MULT_STDs"), name="CORRELATION")
loss = tf.math.subtract(1.0,corr[0], name="CORR_LOSS")
return loss
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.