【问题标题】:Error passing tensor/vector to a custom loss_function in keras将张量/向量传递给 keras 中的自定义 loss_function 时出错
【发布时间】:2019-10-09 08:53:56
【问题描述】:

我想在 keras 中定义一个自定义损失函数,它接受额外的参数作为 cor_weight_tensor。但是由于 cor_weight_tensor 的长度等于训练集中数据点的数量,这比批量大小要大得多。我收到错误。有人可以告诉我,我如何在每次迭代中使用长度与批量大小相同的 cor_weight_tensor。下面给出了我的代码,后跟错误消息。

from keras.models import Sequential
from keras.layers import Dense
from keras import backend

###############
##custom function to calculate loss
def custom_loss(wt):

    def loss(y_true,y_pred):
        return backend.sqrt(backend.mean(backend.square(y_pred - y_true), axis=-1))*wt
    # Return a function
    return loss
###############
###############

def rmse(y_true, y_pred):
    return backend.sqrt(backend.mean(backend.square(y_pred - y_true), axis=-1))

classifier = Sequential()
classifier.add(Dense(output_dim = 128,init ='uniform',activation = 'relu',input_dim=19))
classifier.add(Dense(output_dim =128,init ='uniform',activation = 'relu'))
classifier.add(Dense(output_dim =64,init ='uniform',activation = 'relu'))
classifier.add(Dense(output_dim =64,init ='uniform',activation = 'relu'))
classifier.add(Dense(output_dim = 1 ,init ='uniform',activation = 'relu'))

classifier.compile(optimizer = 'adam' , loss = custom_loss(cor_weight_tensor), metrics = [rmse])
H = classifier.fit(X_train,Y_train,batch_size = 64 ,epochs=10, validation_split=0.2)

我的示例输入训练特征 (X_train) 集如下所示(6 个示例数据点)。现在让我们说数据实例 1-2 来自一个来源,3-4 来自第二个来源,5-6 来自第三个来源。所以我想根据他们的来源给他们分配权重。所以,我创建了一个长度为 6 的权重向量。创建权重向量的原因是在计算来自不同来源的样本的损失时给予更多的权重。

cor_weight_tensor = [1,1,0.75,0.75,0.66,0.66]

X_train

1 0.23,6.69871783,3.09982644
2 0.88,5.90097192,3.09413889
3 0.93,5.22863582,3.00215503
4 0.47,4.99313908,2.89293094
5 0.39,4.81252967,2.70707414
6 0.77,4.79805324,2.59780939

样本输出特征变量为

Y_train

0.45
0.95
0.99
0.77
0.65
0.89

我得到的错误消息是有道理的,但我该如何解决这个错误。

InvalidArgumentError (see above for traceback): Incompatible shapes: [64] vs. [308025]
         [[Node: loss/dense_5_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:GPU:0"](metrics/rmse/Sqrt, loss/dense_5_loss/mul/y)]]
         [[Node: metrics/rmse/Mean_1/_121 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_662_metrics/rmse/Mean_1", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

【问题讨论】:

  • 你应该取损失的平均值,我认为输出维度是错误的
  • 错误是 cor_weight_tensor 我在 custom_loss 函数的代码的倒数第二行中传递。问题是 cor_weight_tensor 的长度等于数据点的数量(308025),但 batch_size 仅为 64,因此 custom_loss 函数期望每批中的 cor_weight_tensor 长度为 64。但是如何在每次批量迭代时更改它?

标签: python tensorflow keras tf.keras


【解决方案1】:

由于您既没有说明这个 cor_weight_tensor 是如何定义的,也没有说明它的含义,所以很难提供准确的答案。

无论如何,为了调整该张量的形状,您可以通过将其减少到单个标量来计算其均值(如果张量具有训练数据长度,那么我可能会认为它是对数据集的某种统计)或适应它以某种方式达到批量大小(取决于它的定义方式)。

无论哪种方式,如果此值来自数据集,您可以将其视为模型的新输入。出于这个原因,我建议使用 Keras 功能 API,它允许您轻松指定多个输入,以便您可以在将其传递给损失函数之前将其调整为张量上的批量大小。

【讨论】:

  • 我已经用样本训练集和权重向量以及简要说明更新了我的问题
  • 在这种情况下,由于您知道输入数据的来源(因此有关联的权重),您的数据集应该将权重作为输入数据的新列输出(y_train 可以是列表或一本字典)。这会很方便,因为您已经将权重嵌入到数据中,并且它们会被完全打乱,而且您的权重批次将始终与训练批次的大小相同,从而允许按元素相乘。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 1970-01-01
  • 2017-07-06
相关资源
最近更新 更多