神经网络验证集的loss比训练集的loss要小

这种现象的可能原因在这篇文章Why is my validation loss lower than my training loss?里已经总结了比较全面。

以下内容,再做个补充。

当训练时,使用权重,会对loss的结果有很大影响。以使用class_weight为例,

#权重小的情况
{0: 0.00041631973355537054, 1: 1.955072435433733e-05, 2: 1.887112905965164e-05, 3: 0.00021570319240724764}#训练中的loss也很小,验证集的loss相对就大了
Epoch 1/256
61/61 [==============================] - 35s 569ms/step - loss: 2.2395e-05 - r_square: -3.1537 - val_loss: 0.0016 - val_r_square: -2.6213
Epoch 2/256
61/61 [==============================] - 35s 583ms/step - loss: 1.6514e-05 - r_square: -2.0511 - val_loss: 0.0013 - val_r_square: -1.8394
Epoch 3/256
61/61 [==============================] - 35s 582ms/step - loss: 1.3883e-05 - r_square: -1.5352 - val_loss: 0.0010 - val_r_square: -1.3170#权重大的情况
{0: 22.06997084548105, 1: 1.0360131383436302, 2: 1.0, 3: 11.432578209277239}#训练中的loss也大,验证集的loss相对就小了
61/61 [==============================] - 44s 620ms/step - loss: 8.8743 - r_square: -393.1525 - val_loss: 0.0035 - val_r_square: -6.9620
Epoch 2/256
61/61 [==============================] - 35s 584ms/step - loss: 0.1281 - r_square: -5.0076 - val_loss: 0.0021 - val_r_square: -3.8056
Epoch 3/256
61/61 [==============================] - 35s 584ms/step - loss: 0.0883 - r_square: -3.2262 - val_loss: 0.0017 - val_r_square: -2.8306

原因,以keras源码中的loss计算为例,

     if loss_weight is not None:loss_value *= loss_weightloss_metric_value *= loss_weight

loss的值直接乘以权重作为最终的loss值。如果权重值很大,最终loss的值可能也会很大。所以,合适大小的权重表述对评估很重要。

另外再说下,keras的sample_weight和class_weight的区别。

理论上,sample_weight是对每条训练数据的权重标记,class_weight是对目标结果分类分布权重的标记,但在keras的源码中,class_weight也是转化成sample_weight来使用的,参见keras权重的计算。所以,不用刻意区分,只要看那种方式,数据容易准备就行。

个人对权重值的处理,是转化为sample_weight后的批次权重值为1。这个方式的合理性,有待商榷验证。