损失函数
在GAN出现之前,使用的更多是MSE,PSNR,SSIM来衡量图像相似度,同时也使用他们作为损失函数。
MSE
MSE(Mean Squared Error)
表面上MSE直接决定了PSNR,MSE:
但是这些引以为傲的指标,有时候也不是那么靠谱:
https://arxiv.org/pdf/1809.07517
MSE对于大的误差更敏感,所以结果就是会倾向于收敛到期望附近,表现为丢失高频信息。
https://arxiv.org/pdf/1609.04802
同时根据实验,MSE的收敛效果也差于L1:
MAE
MAE(Mean Absolute Error)
MAE相比于MSE,对所有像素一视同仁,能保留更多高频信息,所以更符合人眼。
但是只使用L1也有问题,现在通常的做法是多种损失混合使用,比如MS-SSIM+L1,还有基于DCT的loss。
在目前超分辨率的论文中不使用MSE,而使用L1或者Perceptual loss的原因是什么? - 知乎
SMAPE Loss
SMAPE Loss,即对称平均百分比误差(Symmetric Mean Absolute Percentage Error),是一种基于百分比误差的损失函数,用于衡量预测值与实际值之间的差异。
可以看出,SMAPE包含了MAE,是MAE基础上的升级。
原始的MAE因为有绝对值的关系,其实本来就是对称的,label和output交换位置不影响loss的计算。但是考虑到人眼的非线性的影响,还需要有一个分母来归一化,这样label取值很小的情况也会被考虑到。而为了仍然保证交换性,所以分母是二者的均值。
Charbonnier loss
也是L1 loss的一种改进。在零点附近由于常数的存在,梯度不会变成零,避免梯度消失。函数曲线近似L1损失,相比L2损失而言,对异常值不敏感,避免过分放大误差。
class L1_Charbonnier_loss(torch.nn.Module):
"""L1 Charbonnierloss."""
def __init__(self):
super(L1_Charbonnier_loss, self).__init__()
self.eps = 1e-6
def forward(self, X, Y):
diff = torch.add(X, -Y)
error = torch.sqrt(diff * diff + self.eps)
loss = torch.mean(error)
return loss
</