过拟合:模型在训练集上的表现很好,但在测试集和新数据上表现的较差的情况,过分地考虑了训练数据中的噪声等不必要的数据间的关联导致。
欠拟合:模型在训练和预测时表现都不好的情况,成因大多是模型不够复杂、拟合函数的能力不够。
降低过拟合方法:
1)使用更多的训练数据。可以通过一定的规则来扩充训练数据。例如,可以使用生成式对抗网络来合成大量的新训练数据。
2)降低模型复杂度。降低模型复杂度可以避免模型过拟合的采样噪声。例如,在神经网络模型中使用 Dropout 减少网络层数、神经元个数,还有Data argumentation,Early stopping等方法。
3)正则化。给模型的参数加上一定的正则约束,比如将权值的大小加入到损失函数中。
4)集成学习方法。集成学习是把多个模型集成在一起,来降低单一模型的过拟合风险,如Bagging方法。
5)多模型投票方法: 类似集成学习方法的思想,不同模型可能会从不同角度去拟合,互相之间取长补短,即使单独使用某个模型已出现过拟合,但综合起来却有可能减低过拟合程度,起到正则作用,提高了泛化效果。特别是使用多个非常简单的模型,更不容易产生过拟合。
1.交叉验证 K-fold
数据集分为训练、验证(挑选参数)、测试数据集。
train_db, val_db = torch.utils.data.random_split(train_db, [50, 10])#把数据集分为50份的训练,10份的验证
train_loader = torch.utils.data.DataLoader(train_db,batch_size=batch_size, shuffle=True)
val_loader = torch.utils.data.DataLoader(val_db,batch_size=batch_size, shuffle=True)
思路:假设有70k的数据集,60k用来作train set,10k用来作test set测试训练的模型是否优秀。首先把60k的train set,分为50k的train set来训练模型和10k的val set来验证训练的模型挑选一个好的模型参数,划分方式可以为前50k为train set,后10k为val set;前40k后10k为train set,中间10k为val set...该方法利于模型训练,但是效果提升不大。【假设做了5000个epoch,记录每个时间戳的模型效果,在第3620个epoch的验证集效果好,在测试之前加载最好那个的模型参数,然后再用于测试。】
2.正则化Regularization
使参数范数降低接近于0,从而降低模型复杂度,即使模型高次方前面的参数变小。
对于常用一范式&二范式:
#L2正则化
#weight_dacay为Π,使||W||->0
optimizer=optim.SGD(net.parameters(),lr=0.001,weight_dacay=0.01)
#L1正则化
3.动量Momentum
梯度更新:
加上动量: = ,其中
所以与和有关,即α和β用于调整当前和上一次梯度方向的大小,来决定w梯度方向的位置。
对比一下加和不加动量的区别,不加动量时更新梯度方向震动较大,也没有到达全局最优解。加过动量后,更新梯度震动减缓,且越过了局部最优解,能够达到全局最优解,实现了良好的效果。
optimizer=torch.optim.SGD(model.parameters(),args.lr,momentum=0.9,weight_decay=0.01)#Adam优化器自带mpmentum,SGD要写。
4.学习率衰减Learningrate decay
有时梯度更新过慢(a),梯度更新过快(c),这样更新忽大忽小不稳定时可以利用学习率衰减(b),这样以来梯度更新前快后慢C,例如lr可以从0.1->0.0001。若loss先下降然后一直不动,就该把learning rate变小。
方法一:使用ReduceLROnPlateau函数。
optimizer=torch.optim.SGD(model.parameters(),args.lr,momentum=0.9)
scheduler=ReduceLROnPlateau(optimizet,mode='min',factor=0.1,patience=10)
scheduler.step(loss_val) #监听loss_val,若10次都平坦的话,Lr衰减为0.1倍。
方法二:可以设置每经过多少个epoch,就衰减一次earning rate。
#第二种方法
optimizer=torch.optim.SGD(model.parameters(),args.lr,momentum=0.9)
scheduler=StepLR(optimizet,step_size=30,gamma=0.1)#epoch为30倍数时,lr=lr*0.1
5.Early stop
在进入过拟合之前,提早退出训练。
6.Dropout
按照一定的概率减少一部分神经网络单元。
方法:调用torch.nn.Dropout(0.5)
net_dropped=torch.nn.Sequential(
torch.nn.Linear(784,200),#in&out first layer
torch.nn.Dropout(0.5),#以0.5的概率减少神经单元连接数
torch.nn.Relu(),
torch.nn.Linear(200,200),#in&out second layer
torch.nn.Dropout(0.5),
torch.nn.Relu(),
torch.nn.Linear(200,10),#in&out third layer
)
#test时要加入net_dropped.eval()。