我在TensorFlow中训练一个多目标神经网络,使用我自己的损失函数,但找不到关于批处理如何与该功能交互的文档说明。
例如,以下是我损失函数的一个片段,它接受预测的张量/列表,并确保它们的绝对值总和不超过一:
def fitness(predictions,actual): absTensor = tf.abs(predictions) sumTensor = tf.reduce_sum(absTensor) oneTensor = tf.constant(1.0) isGTOne = tf.greater(sumTensor,oneTensor) def norm(): return predictions/sumTensor def unchanged(): return predictions predictions = tf.cond(isGTOne,norm,unchanged) etc...
但当我传入一批估计值时,我感觉这个损失函数会将整个输入集归一化,使其总和为1,而不是使每个独立的集合总和为1。例如,
[[.8,.8],[.8,.8]] -> [[.25,.25],[.25,25]]
而不是我想要的
[[.8,.8],[.8,.8]] -> [[.5,.5],[.5,.5]]
有谁能澄清或打消我的疑虑吗?如果我的函数目前是这样工作的,我应该如何更改它?
回答:
您必须为缩减操作指定一个缩减轴,否则所有轴都会被缩减。传统上,这是您的张量的第一个维度。因此,第2行应该如下所示:
sumTensor = tf.reduce_sum(absTensor, 0)
进行此更改后,您将遇到另一个问题。sumTensor
将不再是标量,因此不再适合作为 tf.cond 的条件(即,批次中每个条目的分支意味着什么?)。您真正想要的是 tf.select,因为您并不真正想根据批次中的每个条目来分支逻辑。如下所示:
isGTOne = tf.greater(sumTensor,oneTensor)norm = predictions/sumTensorpredictions = tf.select(isGTOne,norm,predictions)
但是,现在看这个,我甚至不会费心有条件地归一化条目。由于您现在是在批次的粒度上操作,我认为您无法通过一次归一化批次的一个条目来获得性能提升。特别是,因为除法并不是一个真正昂贵的副作用。不妨直接这样做:
def fitness(predictions,actual): absTensor = tf.abs(predictions) sumTensor = tf.reduce_sum(absTensor, 0) predictions = predictions/sumTensor etc...
希望这对您有帮助!