【问题标题】:Keras custom loss function - how to access actual truth values and predictionsKeras 自定义损失函数 - 如何访问实际的真值和预测
【发布时间】:2020-12-08 02:06:03
【问题描述】:

我正在使用 Keras LSTM 进行时间序列预测。我采用该系列的最后 n_input_steps 次出现并尝试预测向前迈出的一步。例如,如果我的时间序列是 [1, 2, 3, 4] 并且 n_input_steps = 2,那么监督学习数据集将是:

[1,2]--> 3

[2,3]--> 4

因此,要预测的序列 (y_true) 将是 [3,4]。

现在我有一个 Keras 模型来预测这种类型的系列:

        model = Sequential()
        model.add(LSTM(neurons, activation='relu', input_shape=(n_steps_in, 1)))
        model.add(RepeatVector(1))
        model.add(LSTM(neurons, activation='relu', return_sequences=True))
        model.add(TimeDistributed(Dense(1)))
        model.compile(optimizer='adam', loss=my_loss,run_eagerly=True)
        hist=model.fit(trainX, trainY, epochs=epochs, verbose=2,validation_data=(testX,testY))

而我的损失函数是:

def my_loss(y_true,y_pred):
    print(kbe.shape(y_true))
    y_true_c = kbe.cast(y_true,'float32')
    y_pred_c = kbe.cast(y_pred,'float32')
    ytn = y_true_c.numpy()
    print(ytn.shape)
    # Do some complex calculation requiring the elements of y_true_c and y_pred_c. 
    # ...
    return result

据我所知,如果我调用model.fit(trainX, trainY,...),其中 trainX 对应于 [[1, 2], [2, 3]](一个适当形状的数组),trainY 对应于 [3, 4],则my_loss 中的 y_true 应该是对应于 [3, 4] 的张量。然而,这不是我发现的。我的损失函数(张量和数组的形状)的打印输出是:

tf.Tensor([32  1  1], shape=(3,), dtype=int32)
(32, 1, 1)

不管输入数组的大小。如果我打印数组的值,它们不会记住原始值。即使我删除了模型的所有层,保持一个裸露的 Sequential,我也会得到相同的形状。因此,我完全迷失了。

【问题讨论】:

  • 您不能在损失函数中使用 numpy 数组。您必须使用 tensorflow/keras 操作。这是自动微分(反向传播)所必需的。
  • 默认情况下,Keras 使用的批量大小等于 32(除非您设置另一个),也许这就是您在这里所缺少的。因此,您打印的不是一个样品的形状,而是一批更大尺寸(在本例中为 32 个)。
  • 感谢您的回复。事实上,主要问题是批量大小,但最重要的是,数据是打乱的,这就是它变得更加混乱的原因。因此,出于我的目的,我将尝试在 model.fit() 中使用 batch_size=len(trainX) 和 shuffle=False。我会检查我的模型是否有效,我可能会发布这个问题的答案。

标签: python tensorflow keras


【解决方案1】:

根据上面的 cmets,我做了进一步的搜索,发现响应中有一个默认的批量大小规则,正如 Jorge Avila 所指出的那样。默认长度为 32 由 Keras 使用。真值数据和预测数据分批进入这个大小,所以我应该在对model.fit() 的调用中使用batch_size=len(trainX)。此外,最重要的是,数据是打乱的,这就是它变得更加混乱的原因。所以,我必须在model.fit() 中也使用shuffle=False

但是,正如 Jakub 所指出的,即使进行了这些修改,我的预期损失函数也不会起作用,因为 Keras 需要函数的符号导数,而这不能通过需要 numpy 值的逻辑来实现。因此,我必须从头开始使用 Keras 可接受的另一个损失函数。

【讨论】:

    【解决方案2】:

    根据您的数据,将 batch_sizes 保持在 32-1024 的倍数,因为 2** of 始终有效,因为它很常见,但您不必使用 shuffle,因为 TimeseriesGenrator 是需要更改的地方不合适。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 2021-12-16
      • 2018-12-28
      • 1970-01-01
      • 2018-05-25
      • 2018-11-24
      • 2020-12-19
      相关资源
      最近更新 更多