首页 > 解决方案 > 批量计算损失函数的有效方法?

问题描述

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

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

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

Python

 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 个小时。encrypted_dataset 是一个变量,它将主存储器中的整个数据集作为一个数据帧。我正在使用 Azure VM 实例。 K.eval(loss_function(y_true,y_pred)是找到批次的每一行的损失所以 y_true 将是大小(batch_size,2000),所以 y_pred K.eval(loss_function(y_true,y_pred)会给我一个输出

(batch_size,1)评估 y_true 和 y_pred 每一行的二元交叉熵

标签: tensorflowkerasbigdata

解决方案


移自评论:

我的怀疑是,ae1.predict并且K.eval(loss_function)正在以意想不到的方式表现。ae1.predict通常应该用于输出损失函数值以及y_pred. 创建模型时,指定损失值是另一个输出(您可以有多个输出的列表),然后只需在此处调用一次 predict 即可在一次调用中获取两个y_pred损失值。

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

答案取决于损失函数是如何实现的。两种方式都在 TF 中产生完全有效且相同的结果。您可以在对损失进行梯度计算之前对批次的损失进行平均,或者将梯度作为损失向量。如果您使用后一种方法,TF 中的梯度操作将为您执行损失的平均(请参阅关于采用每个样本梯度的 SO 文章,实际上很难做到)。

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

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


推荐阅读