如何正确定义拍摄图像并输出图像的Keras网络中的损失函数?

时间:2019-09-20 20:31:21

标签: python keras conv-neural-network

我正在尝试建立一个模型,该模型可以拍摄灰度图像,并通过使用keras的残留CNN生成另一个图像作为输出。这里的关键思想是非白色像素的数量要比白色像素的数量小得多。因此,每个非白色像素中的误差在损失函数中的权重应大于白色像素中的误差。像素越暗,误差应该越大。 这就是我目前所做的。 在这里,total_pred_score表示所有正确猜测的像素,其权重由某个int系数定义,total_true_score表示该训练集中的所有图像和像素的总预期分数。 但是我不确定这是正确的。你能帮我吗?

def custom_loss(y_true, y_pred):
    y_true1, y_pred1 = (255 - y_true) / 255, (255 - y_pred) / 255
    dif = (1 - K.abs(y_true1 - y_pred1))
    weight = (coeff - 1) * y_true1 + 1 
    total_true_score = K.sum(weight, axis = [0,1,2,3])
    total_pred_score = K.sum(multiply([dif,weight]), axis = [0,1,2,3])
    return K.abs(total_true_score - total_pred_score) / total_true_score

1 个答案:

答案 0 :(得分:0)

您要构建的损失函数应具有两个属性:

  1. 每个非白色像素的误差应比白色像素的权重更大
  2. 像素越暗,误差应该越大

因此,为了简化起见,如果您将暗像素分类为白色像素,则希望误差更大,但实际上不必过多担心将白像素分类为黑色像素的情况,但是您仍然希望它们有助于您的损失功能。另外,您还要确保损失与像素强度成正比(像素越暗,误差越大)。

我想出了以下损失函数,它们遵循这两个属性:

def custom_loss(y_true, y_pred, coeff):
    y_true1, y_pred1 = (255 - y_true) / 255, (255 - y_pred) / 255
    dif = y_true1 - y_pred1
    temp1 = K.l2_normalize(K.cast(K.greater(dif, 0),"float32")*y_true1,axis=-1) * coeff
    temp2 = K.cast(K.less(dif, 0),"float32")
    weight = temp1 + temp2  
    loss = K.abs(weight*dif)
    average_loss = K.mean(loss)   ##you need to return this when you use in your code
    return K.eval(loss)

因此,基本上,我们在进行归一化并乘以dif(对应于较暗像素)-temp1中仅与正值成正比的权重之后,找到了真值和预测值之间的差异。然后,我们仅将1的权重添加到对应于负值(对应于白色)的像素。

  

样品输出

coeff = 5
y_t = np.array([0,250,30,0,255,160,210,0,2,4])
y_p = np.array([50,0,80,10,255,160,210,250,2,80])
custom_loss(y_t,y_p,coeff ) 

array([0.449957, 0.98039216, 0.39702088, 0.08999141, 0., 0., 0., 2.249785, 0., 0.67320627],dtype=float32)

在这里,如果您仔细查看像素28处的像素,像素8对应于以下情况:我们将暗像素预测为一阵子像素,这对我们来说非常糟糕因此,损耗值确实很高2.249785,同样,像素2对应于我们将白色像素预测为暗像素的情况,这对我们来说还可以,因此损耗值为{{ 1}},不如前一种情况高。这对应于属性0.98039216

同样,如果您将像素11看作两种情况下的误差大小相同(它们之间相差3),但是像素50比像素1暗得多,因此我们希望像素3上的误差高于像素1,这就是我们在误差向量中观察到的。

在我们的真实值和预测值匹配的情况下,我们将发生3错误。

希望这会有所帮助!