当前位置: 首页 > 知识库问答 >
问题:

[1]中的Keras自定义损失函数InvalidArgumentError:不是矩阵。相反,它具有形状[]

隆璞
2023-03-14

我试图使用斯皮尔曼秩相关系数来编写一个自定义损失函数。我想计算每对y_true和y_pred样本之间的Spearman秩相关系数(每个样本是由8个元素组成的数组;例如,[1 2 3 4 5 6 7 8]和[3 2 1 4 5 6 7])。

我遵循了这个答案的指示(如何在Tensorflow中计算Spearman相关性)和Keras留档(https://keras.io/api/losses/),但是对于计算损失的输出形状,我必须跳过一些东西。

使用此自定义函数训练模型会产生以下错误:

model.compile(loss=spearman_correlation, optimizer=tf.keras.optimizers.Adam())
model.fit(train_x, train_y,batch_size=64, epochs=2, validation_data=(test_x, test_y), callbacks=[model_checkpoint])

InvalidArgumentError:  In[1] is not a matrix. Instead it has shape []
     [[node gradient_tape/model_19/dense_19/MatMul_1 (defined at <ipython-input-46-7e6fc7cd1b39>:12) ]] [Op:__inference_train_function_300522]

我尝试了一种巧妙的方法来解决这个问题,我使用了一个Keras损失函数的工作示例,我只是用损失函数中计算的值来修改结果。通过这种方式,培训功能工作,然而,我不认为这是正确的做事方式,但我不认为问题出在哪里。查看自定义函数中的打印输出,可以看出my loss output对象和tensorflow的loss function output对象的形状和类型是相同的。

这是我计算损失的方法:

def get_rank(y_pred):
    temp = sorted(y_pred, reverse=False)
    res = [temp.index(i) for i in y_pred]
    res = np.array(res)+1
    return(res)

def custom_spearman_correlation(y_true, y_pred):
    s_coefs = tf.map_fn(lambda k: 1-stats.spearmanr(k[0], get_rank(k[1]))[0], tf.stack([y_true, y_pred], 1), dtype=tf.float32)

    loss = s_coefs
    print("CUSTOM LOSS: ")
    print("Shape: " + str(loss.shape))
    print(type(loss))

    print("WORKING LOSS")
    squared_difference = tf.square(y_true - y_pred)
    w_loss = tf.reduce_mean(squared_difference, axis=-1)
    print("Shape: " + str(w_loss.shape))
    print(type(w_loss))

    print("TRICKY ANSWER: ")
    t_loss = w_loss*0 + loss
    print("Shape: " + str(t_loss.shape))
    print(type(t_loss))
    return loss
    #return w_loss
    #return t_loss

def spearman_correlation(y_true, y_pred):
    sp = tf.py_function(custom_spearman_correlation, [tf.cast(y_true, tf.float32), tf.cast(y_pred, tf.float32)], Tout = tf.float32)
    return (sp)

这是输出:

CUSTOM LOSS: 
Shape: (64,)
<class 'tensorflow.python.framework.ops.EagerTensor'>
WORKING LOSS
Shape: (64,)
<class 'tensorflow.python.framework.ops.EagerTensor'>
TRICKY ANSWER: 
Shape: (64,)

共有1个答案

申屠秦斩
2023-03-14

虽然我不确定,但我认为上述解决方案不允许正确更新模型中不同参数的权重,因此我的模型没有学习。我一直在工作,直接实现Spearman排名相关系数后,这个网站(https://rpubs.com/aaronsc32/spearman-rank-correlation)的定义,我已经达到了以下代码(我分享它,以防有人发现它很有用)。

@tf.function
def get_rank(y_pred):
  rank = tf.argsort(tf.argsort(y_pred, axis=-1, direction="ASCENDING"), axis=-1)+1 #+1 to get the rank starting in 1 instead of 0
  return rank

@tf.function
def sp_rank(x, y):
  cov = tfp.stats.covariance(x, y, sample_axis=0, event_axis=None)
  sd_x = tfp.stats.stddev(x, sample_axis=0, keepdims=False, name=None)
  sd_y = tfp.stats.stddev(y, sample_axis=0, keepdims=False, name=None)
  return 1-cov/(sd_x*sd_y) #1- because we want to minimize loss

@tf.function
def spearman_correlation(y_true, y_pred):
    #First we obtain the ranking of the predicted values
    y_pred_rank = tf.map_fn(lambda x: get_rank(x), y_pred, dtype=tf.float32)
    
    #Spearman rank correlation between each pair of samples:
    #Sample dim: (1, 8)
    #Batch of samples dim: (None, 8) None=batch_size=64
    #Output dim: (batch_size, ) = (64, )
    sp = tf.map_fn(lambda x: sp_rank(x[0],x[1]), (y_true, y_pred_rank), dtype=tf.float32)
    #Reduce to a single value
    loss = tf.reduce_mean(sp)
    return loss
 类似资料:
  • 嗨,我一直试图使一个自定义损失函数在kerasdice_error_coefficient。它有它的实现在张量板和我尝试使用相同的函数在keras与张量流但它不断返回一个NoneType当我使用model.train_on_batch或model.fit在那里,因为它给适当的值时,使用在模型中的指标...能不能请人帮帮我我该怎么办?我尝试过跟随像Keras-FCN这样的库,在那里他使用了自定义损失

  • 我手头有一个问题,它优化了一个损失函数,而不是y_pred和y_true的函数。通过Keras留档后,我发现所有自定义损失函数必须是y_pred和y_true的函数。 在Keras中是否有其他方法实现我的损失函数?

  • 我正在尝试使用Keras创建自定义损失函数。我想根据输入计算损失函数并预测神经网络的输出。 我尝试在Keras中使用自定义loss函数。我认为y_true是我们为训练提供的输出,y_pred是神经网络的预测输出。下面的损失函数与 Keras 中的“mean_squared_error”损失相同。 我想使用神经网络的输入也计算自定义损失函数除了mean_squared_error损失。有没有办法将输

  • 我有一个NN,它有两个相同的CNN(类似于暹罗网络),然后合并输出,并打算在合并的输出上应用自定义损失函数,如下所示: 在我的自定义损失函数中,我需要将y垂直分解为两块,然后对每一块应用分类交叉熵损失。但是,我不断从我的损失函数得到dtype错误,例如: ()中的ValueError回溯(最近一次调用)---- /usr/local/lib/python3。5/地区包/KERA/发动机/培训。编译

  • 我需要一些帮助与keras损失函数。我一直在Tensorflow后端的keras上实现自定义损失功能。 我已经在numpy中实现了自定义损失函数,但如果能将其转换为keras损失函数,那就太好了。丢失函数采用数据帧和用户id序列。如果用户id不同,则相同用户id的欧氏距离为正和负。函数返回数据帧的合计标量距离。 我试图实现到keras损失函数。我提取Numpy数组从y_true和y_pred张量对

  • 我试图在Keras中构造一个自定义损失函数-这是用于生存分析中的删失数据。 这种损失函数本质上是二元交叉熵,即多标签分类,但是损失函数中的求和项需要根据Y_true标签的可用性而变化。见下面的例子: 示例1:Y_可用的所有标签均为True Y_true=[0,0,0,1,1] Y_pred=[0.1,0.2,0.2,0.8,0.7] 损失=-1/5(log(0.9)log(0.8)log(0.8)