如何在取像输出的keras网络中正确定义损失函数?

3yhwsihp  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(144)

我试图建立一个模型,采用灰度图像,并生成另一个图像作为输出的残差CNN使用keras。这里的关键思想是,非白色像素的数量远远小于白色像素的数量。因此,每个非白色像素的误差在损失函数中的权重应该大于白色像素的权重。像素越暗,误差应该越大。这就是我如何我现在已经做了。这里,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
xsuvu9jc

xsuvu9jc1#

您尝试构建的损失函数应该具有两个属性:
1.每个非白色像素中的误差应比白色像素中的误差具有更大的权重
1.像素越暗,误差越大
因此,为了简化计算,如果将暗像素归为白色像素,则希望误差更大,但对于将白像素归为暗像素,但仍希望它们对损失函数有贡献的情况,不必太担心。此外,您还希望确保损失与像素的强度成正比(像素越暗,误差越大)。
我已经提出了下面的损失函数,它符合这两个性质:

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对应的情况是,我们预测白色像素为暗像素,这对我们来说还不错,因此损失值为0.98039216,其不像前一情况那样高。这对应于属性1
类似地,如果您查看像素13,两种情况下的误差幅度相同(相差50),但像素1比像素3暗得多,因此我们希望像素1上的误差高于像素3,这就是我们在误差向量中观察到的。
在真实值和预测值匹配的情况下,我们有0误差。

相关问题