侧边栏壁纸
    • 累计撰写 302 篇文章
    • 累计收到 527 条评论
    机器学习/深度学习-训练过程讲解acc/loss/val_acc/val_loss分析
    我的学记|刘航宇的博客

    机器学习/深度学习-训练过程讲解acc/loss/val_acc/val_loss分析

    刘航宇
    2024-01-20 / 0 评论 / 1,096 阅读 / 正在检测是否收录...

    计算loss是会把所有loss层的loss相加。

    从验证集误差是和测试集误差的角度分析
    其实你这个问题就是个伪命题,如果我们刻意的去在训练集上拟合模型,使其准确率达到很高的高度,或者说尽量在验证集合上表现的好,都是相悖的。
    因为我们不能为了某一特定数据集来刻意拟合,因为模型预测数据是不一定就在这个训练或者验证集合的空间中。
    还有,如果这个model预测集合acc20% 训练集合acc19% (即训练集精度低于测试集精度),那么这个模型肯定是不好的。
    还有一点需要注意,就是千万不能为了拟合测试集合而去更改模型,测试集合应该每次都有不同。

    那么如何选取一个较为理想的medel?

    首先,要有一个期望的准确率,通过不同模型的实验,找到最能接近的;
    然后,选定模型后进行参数调优;
    那么我们要尽可能的提高model的准确率,同时提高其泛化的能力,不能单一看某一指标,此时可参考 准确率、召回率、虚警率、F1Score等指标综合评判。或者采用多重验证随机划分训练、预测、验证集合,多次随机后找到最优参数。
    有时候训练集合误差很低,但是泛化能力极差,产生过拟合,
    有时候验证集合误差很低,但是可能验证集合无法代表所有的样本,有特殊性或者其他异常点较多。
    所以模型问题不能单一从你这两点来评判。
    一般而言,训练集loss < 验证集loss <测试集loss
    因为网络 [已见过] 所有训练集samples,故最低。而网络用验证集作为反馈来调节参数,相当于参考了验证集samples中的信息(间接 [已见过])。又因为网络没有任何测试集的信息,所以测试结果一般而言最差。
    不过这都不是绝对的,有不符合这个一般现象的task,而我们不可以说哪种情况更“好”。
    多数情况验证集上错误率更低一点。因为是选择在验证集上准确率最高的模型来进行测试。考虑到数据的随机性,在验证集上准确率最高的模型在测试集上不一定是最高的,所以算出来的指标通常验证集会比测试集上好一点。
    但是实际情况下都有可能,特别是数据量不太大的时候。样本集合的数据也只是近似整体的分布,肯定会有波动。
    一个好的网络,二者的差距应该是很低的。但一般情况下因为网络不可避免地存在一定程度上的过拟合,所以肯定是train_loss低于test_lost,但如果低太多,就得考虑是过拟合的问题还是因为样本的特征空间不统一的问题。
    一般训练集不大时,最终训练的网络及容易过拟合,也就是说train-loss一定会收敛,但是test-loss不会收敛;
    训练时的loss会低于test的loss大概1~2个数量级,通常是10倍左右。

    单独观察训练集loss曲线

      1)如果你的 learning_rate_policy 是 step 或者其他变化类型的话, loss 曲线可以帮助你选择一个比较合适的 stepsize;
      2)如果loss曲线表现出线性(下降缓慢)表明学习率太低;
      3)如果loss不再下降,表明学习率太高陷入局部最小值;
      4)曲线的宽度和batch size有关,如果宽度太宽,说明相邻batch间的变化太大,应该减小batch size。

    可能导致不收敛的问题(如loss为87.3365,loss居高不下等)的解决方案
      1)在caffe中可以在solver里面设置:debug_info: true,看看各个层的data和diff是什么值,一般这个时候那些值不是NAN(无效数字)就是INF(无穷大);
      2)检查数据标签是否从0开始并且连续;
      3)把学习率base_lr调低;
      4)数据问题,lmdb生成有误;
      5)中间层没有归一化,导致经过几层后,输出的值已经很小了,这个时候再计算梯度就比较尴尬了,可以尝试在各个卷积层后加入BN层和SCALE层;
      5)把base_lr调低,然后batchsize也调高;
      6)把data层的输入图片进行归一化,就是从0-255归一化到0-1,使用的参数是:

     transform_param {  
        scale: 0.00390625//像素归一化,1/255
      } 

     7)网络参数太多,网络太深,删掉几层看看,可能因为数据少,需要减少中间层的num_output;
      8)记得要shuffle数据,否则数据不够随机,几个batch之间的数据差异很小。

    loss出现NAN

      1)观察loss值的趋势,如果迭代几次以后一直在增大,最后变成nan,那就是发散了,需要考虑减小训练速率,或者是调整其他参数。
      2)数据不能太少,如果太少的话很容易发散"
      3)Gradient Clipp
      处理gradient之后往后传,一定程度上解决梯度爆炸问题。(但由于有了batch normalization,此方法用的不多)
      4)原因可能是训练的时间不够长。
      5)可以看一下训练时,网络参数的L2或L1

    联合观察loss曲线和acc

      1)单独的 loss 曲线能提供的信息很少的,一般会结合测试机上的 accuracy 曲线来判断是否过拟合;
      2)关键是要看你在测试集上的acc如何;
      3)可以把accuracy和loss的曲线画出来,方便设定stepsize,一般在accuracy和loss都趋于平缓的时候就可以减小lr了;
      4)看第一次test时(即iteration 0),loss和精度,如果太差,说明初始点的设置有问题
      5)使用caffe时,train时,看见的loss是训练集的;accuracy才是测试集的
      6)所谓的过拟合是:loss下降,accuracy也下降

    TensorFlow中loss与val_loss、accuracy和val_accuracy含义


    loss:训练集损失值

    accuracy:训练集准确率

    val_loss:测试集损失值

    val_accruacy:测试集准确率

    以下5种情况可供参考:

    train loss 不断下降,test loss不断下降,说明网络仍在学习;(最好的)

    train loss 不断下降,test loss趋于不变,说明网络过拟合;(max pool或者正则化)

    train loss 趋于不变,test loss不断下降,说明数据集100%有问题;(检查dataset)

    train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;(减少学习率)

    train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。(最不好的情况)

    震荡修复

    1. 验证集曲线震荡

      分析原因:训练的batch_size太小
      目前batch_size = 64,改成128:

      改成200:

      可见,增大batch_size 变大,震荡逐渐消失,同时在测试集的acc也提高了。batch_size为200时,训练集acc小于测试集,模型欠拟合,需要继续增大epoch。

    总结
    增大batchsize的好处有三点:
    1)内存的利用率提高了,大矩阵乘法的并行化效率提高。
    2)跑完一次epoch(全数据集)所需迭代次数减少,对于相同的数据量的处理速度进一步加快,但是达到相同精度所需要的epoch数量也越来越多。由于这两种因素的矛盾, batch_Size 增大到某个时候,达到时间上的最优。
    3)一定范围内,batchsize越大,其确定的下降方向就越准,引起训练震荡越小。
    盲目增大的坏处:
    1)当数据集太大时,内存撑不住。
    2)过大的batchsize的结果是网络很容易收敛到一些不好的局部最优点。
    3)batchsize增大到一定的程度,其确定的下降方向已经基本不再变化。
    4)太小的batch也存在一些问题,比如训练速度很慢,训练不容易收敛等。
    5)具体的batch size的选取和训练集的样本数目相关。

    2
    Socket通信-Linux系统中C语言实现TCP/UDP图片和文件传输
    « 上一篇 2024-02-29
    泛化能力,过拟合,欠拟合,不收敛,奥卡姆剃刀
    下一篇 » 2024-01-19

    评论 (0)

    取消