分批计算损失函数的有效方法?

时间:2019-05-22 10:21:47

标签: tensorflow keras bigdata

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

这是我当前用于计算重建损失的代码 但这确实很慢。据我估计,整个数据集将花费5个小时,而训练一个历时大约需要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))) 

我每个时期能训练55分钟。因此,我认为预测不应该每个纪元花费5个小时。 encode_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

1 个答案:

答案 0 :(得分:1)

已从评论中移出:

我怀疑ae1.predictK.eval(loss_function)的行为异常。通常应使用ae1.predicty_pred输出损失函数值。创建模型时,指定损耗值是另一个输出(您可以具有多个输出的列表),然后只需在此处调用一次预测即可一次调用两个y_pred损耗值。

  

但是我希望每一行都有损失。预测方法返回的损失不是整个批次的平均损失吗?

答案取决于损失函数的实现方式。两种方式在引擎盖下的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,这都会产生每个样本的损失,这在损失中纯粹是可选的。另一种选择是简单地将损失与您优化的结果分开计算,并使模型的输出也完全有效。