Keras:处理自定义皮尔逊相关指标的批量大小维度
Keras: handling batch size dimension for custom pearson correlation metric
我想为皮尔逊相关性创建自定义指标as defined here
我不确定如何将其应用于 y_pred
和 y_true
的批次
我做了什么:
def pearson_correlation_f(y_true, y_pred):
y_true,_ = tf.split(y_true[:,1:],2,axis=1)
y_pred, _ = tf.split(y_pred[:,1:], 2, axis=1)
fsp = y_pred - K.mean(y_pred,axis=-1,keepdims=True)
fst = y_true - K.mean(y_true,axis=-1, keepdims=True)
corr = K.mean((K.sum((fsp)*(fst),axis=-1))) / K.mean((
K.sqrt(K.sum(K.square(y_pred -
K.mean(y_pred,axis=-1,keepdims=True)),axis=-1) *
K.sum(K.square(y_true - K.mean(y_true,axis=-1,keepdims=True)),axis=-1))))
return corr
我是否有必要使用 keepdims
并手动处理批次维度并取平均值?或者 Keras 是否以某种方式自动执行此操作?
当您在没有轴的情况下使用 K.mean
时,Keras 会自动计算整个批次的平均值。
而且后端已经有了标准差函数,所以使用它们可能更干净(也许更快)。
如果你的真实数据的形状像 (BatchSize,1)
,我会说 keep_dims 是不必要的。否则我不确定,测试结果会很好。
(我不明白为什么要用split
,但好像也没有必要)
所以,我会尝试这样的事情:
fsp = y_pred - K.mean(y_pred) #being K.mean a scalar here, it will be automatically subtracted from all elements in y_pred
fst = y_true - K.mean(y_true)
devP = K.std(y_pred)
devT = K.std(y_true)
return K.mean(fsp*fst)/(devP*devT)
如果对每个特征进行损失而不是将它们全部放在同一组中是相关的:
#original shapes: (batch, 10)
fsp = y_pred - K.mean(y_pred,axis=0) #you take the mean over the batch, keeping the features separate.
fst = y_true - K.mean(y_true,axis=0)
#mean shape: (1,10)
#fst shape keeps (batch,10)
devP = K.std(y_pred,axis=0)
devt = K.std(y_true,axis=0)
#dev shape: (1,10)
return K.sum(K.mean(fsp*fst,axis=0)/(devP*devT))
#mean shape: (1,10), making all tensors in the expression be (1,10).
#sum is only necessary because we need a single loss value
十个特征求和或者取平均值是一样的,是一个乘以另一个的10倍(这个和keras模型关系不大,只影响学习率,但是很多优化器很快发现他们的绕过这个)。
我想为皮尔逊相关性创建自定义指标as defined here
我不确定如何将其应用于 y_pred
和 y_true
我做了什么:
def pearson_correlation_f(y_true, y_pred):
y_true,_ = tf.split(y_true[:,1:],2,axis=1)
y_pred, _ = tf.split(y_pred[:,1:], 2, axis=1)
fsp = y_pred - K.mean(y_pred,axis=-1,keepdims=True)
fst = y_true - K.mean(y_true,axis=-1, keepdims=True)
corr = K.mean((K.sum((fsp)*(fst),axis=-1))) / K.mean((
K.sqrt(K.sum(K.square(y_pred -
K.mean(y_pred,axis=-1,keepdims=True)),axis=-1) *
K.sum(K.square(y_true - K.mean(y_true,axis=-1,keepdims=True)),axis=-1))))
return corr
我是否有必要使用 keepdims
并手动处理批次维度并取平均值?或者 Keras 是否以某种方式自动执行此操作?
当您在没有轴的情况下使用 K.mean
时,Keras 会自动计算整个批次的平均值。
而且后端已经有了标准差函数,所以使用它们可能更干净(也许更快)。
如果你的真实数据的形状像 (BatchSize,1)
,我会说 keep_dims 是不必要的。否则我不确定,测试结果会很好。
(我不明白为什么要用split
,但好像也没有必要)
所以,我会尝试这样的事情:
fsp = y_pred - K.mean(y_pred) #being K.mean a scalar here, it will be automatically subtracted from all elements in y_pred
fst = y_true - K.mean(y_true)
devP = K.std(y_pred)
devT = K.std(y_true)
return K.mean(fsp*fst)/(devP*devT)
如果对每个特征进行损失而不是将它们全部放在同一组中是相关的:
#original shapes: (batch, 10)
fsp = y_pred - K.mean(y_pred,axis=0) #you take the mean over the batch, keeping the features separate.
fst = y_true - K.mean(y_true,axis=0)
#mean shape: (1,10)
#fst shape keeps (batch,10)
devP = K.std(y_pred,axis=0)
devt = K.std(y_true,axis=0)
#dev shape: (1,10)
return K.sum(K.mean(fsp*fst,axis=0)/(devP*devT))
#mean shape: (1,10), making all tensors in the expression be (1,10).
#sum is only necessary because we need a single loss value
十个特征求和或者取平均值是一样的,是一个乘以另一个的10倍(这个和keras模型关系不大,只影响学习率,但是很多优化器很快发现他们的绕过这个)。