【问题标题】:An Efficient way to Calculate loss function batchwise?批量计算损失函数的有效方法?
【发布时间】:2019-10-08 19:29:30
【问题描述】:

我正在使用自动编码器进行异常检测。所以,我已经完成了模型的训练,现在我想计算数据集中每个条目的重建损失。这样我就可以将异常分配给具有高重建损失的数据点。

这是我当前计算重建损失的代码 但这真的很慢。据我估计,遍历数据集需要 5 个小时,而训练一个 epoch 大约需要 55 分钟。 感觉转换成张量运算是代码的瓶颈,但是找不到更好的办法。

我已尝试更改批量大小,但没有太大区别。我必须使用转换为张量的部分,因为如果我正常执行,K.eval 会引发错误。

蟒蛇

 for i in range(0, encoded_dataset.shape[0], batch_size):    
    y_true = tf.convert_to_tensor(encoded_dataset[i:i+batch_size].values,
 np.float32)
     y_pred= tf.convert_to_tensor(ae1.predict(encoded_dataset[i:i+batch_size].values),
 np.float32)
    # Append the batch losses (numpy array) to the list
    reconstruction_loss_transaction.append(K.eval(loss_function( y_true, y_pred))) 

我能够在每个 epoch 55 分钟内进行训练。所以我觉得每个时期的预测不应该花费 5 个小时。 encoded_dataset 是一个变量,它将主内存中的整个数据集作为一个数据框。 我正在使用 Azure VM 实例。 K.eval(loss_function(y_true,y_pred)是找batch的每一行的loss 所以 y_true 的大小将是 (batch_size,2000),y_pred 也是如此 K.eval(loss_function(y_true,y_pred) 会给我一个输出

(batch_size,1) 在 y 的每一行上评估二元交叉熵 _true 和 y_pred

【问题讨论】:

  • 我已经删除了我之前的答案,你能编辑你的问题来解释一下K.eval(loss_function( y_true, y_pred)) 是什么吗?我对我们在那里看到的内容感到困惑。
  • 我已经做出了改变。
  • ae1.predict 怎么会和y_true 获取相同的数据?两者都将encoded_dataset[i:i+batch_size].values 作为输入。如果您执行预测,您将传入输入数据,但似乎您正在使用标签进行预测。然后我假设values 以某种方式包含数据和标签,这在代码 sn-p 中并不明显。在这种情况下,您可能会多次移动完整的输入数据。不过还不是很清楚。
  • 很好的问题。答案取决于损失函数是如何实现的。两种方式都在 TF 中产生完全有效且相同的结果。您可以在获取梯度 w.r.t 之前对批次的损失进行平均。损失,或取梯度 w.r.t.损失向量。如果您使用后一种方法,TF 中的梯度操作将为您执行损失的平均(请参阅关于采用每批梯度的 SO 文章,实际上很难做到)。
  • 如果 keras 使用内置的 reduce_mean 来实现损失,您可以定义自己的损失。如果您使用平方损失,请将'mean_squared_error' 替换为lambda y_true, y_pred: tf.square(y_pred - y_true)。这将产生平方误差而不是 MSE(与梯度没有差异),但请在此处查找包括均值在内的变体:stackoverflow.com/questions/41338509。在任何情况下,只要您不使用tf.reduce_mean,这都会产生每个样本的损失,这在损失中纯粹是可选的。让我知道这是否解决了问题,我会将讨论转移到答案。

标签: tensorflow keras bigdata


【解决方案1】:

从 cmets 移出:

我怀疑ae1.predictK.eval(loss_function) 的行为方式出乎意料。 ae1.predicty_pred 通常应该用于输出损失函数值。创建模型时,指定损失值是另一个输出(您可以有多个输出的列表),然后只需在此处调用一次 predict 即可在一次调用中同时获取 y_pred 损失值。

但我想要每一行的损失。 predict 方法返回的 loss 不会是整批的平均 loss 吗?

答案取决于损失函数是如何实现的。两种方式都在 TF 中产生完全有效且相同的结果。您可以在获取梯度 w.r.t 之前对批次的损失进行平均。损失,或取梯度 w.r.t.损失向量。如果您使用后一种方法,TF 中的梯度操作将为您执行损失的平均(请参阅SO articles on taking the per-sample gradient,实际上很难做到)。

如果 Keras 在损失中内置 reduce_mean 来实现损失,您可以定义自己的损失。如果您使用平方损失,请将 'mean_squared_error' 替换为 lambda y_true, y_pred: tf.square(y_pred - y_true)。这将产生平方误差而不是 MSE(与梯度没有区别),但 look here for the variant including the mean

在任何情况下,只要您不使用tf.reduce_mean,这都会产生每个样本的损失,这在损失中纯粹是可选的。另一种选择是简单地将损失与您优化的内容分开计算,并将其作为模型的输出,也完全有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    相关资源
    最近更新 更多