如何在keras模型中计算和打印皮尔逊相关系数作为度量?



我有一个keras模型,我试图做回归。我想打印出模型预测的y值和每个历元后的实际y值之间的相关性。model.fit()函数默认只打印训练和验证损失。我该如何实现这个自定义指标?

model = keras.Sequential(...some layers...) 
...
model.fit(
X,
y, 
metrics = [correlation_fn]
) 

因此,在每个epoch之后的训练过程中,它打印出类似

的内容
50261/50261 [==============================] - 100s 2ms/step - loss: 20.6613 - val_loss: 13.3205 - pearson correlation: 0.56 

我自己想出了办法!这个解决方案的唯一问题是我用来计算minibatch大小的方法,它看起来很难看,我不知道是否有更好的方法来做到这一点。

class CorrelationMetric(keras.metrics.Metric): 
def __init__(self, name="correlation", **kwargs): 
super(CorrelationMetric, self).__init__(name=name, **kwargs)
self.correlation = self.add_weight(name="correlation", initializer="zeros")
self.n = self.add_weight(name="n", initializer="zeros")
self.x = self.add_weight(name="x", initializer="zeros")
self.x_squared = self.add_weight(name="x_squared", initializer="zeros")
self.y = self.add_weight(name="y", initializer="zeros")
self.y_squared = self.add_weight(name="y_squared", initializer="zeros")
self.xy = self.add_weight(name="xy", initializer="zeros")

def update_state(self, y_true, y_pred, sample_weight=None): 
self.n.assign_add(tf.reduce_sum(tf.cast((y_pred == y_true), "float32")))
self.n.assign_add(tf.reduce_sum(tf.cast((y_pred != y_true), "float32")))
self.xy.assign_add(tf.reduce_sum(tf.multiply(y_pred, y_true)))
self.x.assign_add(tf.reduce_sum(y_pred))
self.y.assign_add(tf.reduce_sum(y_true))
self.x_squared.assign_add(tf.reduce_sum(tf.math.square(y_pred)))
self.y_squared.assign_add(tf.reduce_sum(tf.math.square(y_true)))

def result(self): 
return (self.n * self.xy - self.x * self.y)/tf.math.sqrt((self.n * self.x_squared - tf.math.square(self.x)) * (self.n * self.y_squared - tf.math.square(self.y)))

def reset_state(self): 
self.n.assign(0.0)
self.x.assign(0.0)
self.x_squared.assign(0.0)
self.y.assign(0.0)
self.y_squared.assign(0.0)
self.xy.assign(0.0)
self.correlation.assign(0.0)
#later, use this metric in a model 
model.compile(X, y, ..args.., metrics=[CorrelationMetric()]) 

最新更新