在讲解过拟合和欠拟合之前,先说一下数据的真实的模态,也叫数据的真实分布或者 P r ( x ) P_r(x) Pr(x)。
线性模型:
非线性模型:
已经提前知道数据的分布但是不知道具体的参数,比如房价与面积的倍数。我们不但对 P r ( x ) P_r(x) Pr(x)的类型不知,观察时还有误差。
y = w ∗ x + b + ϵ y=w*x+b+\epsilon y=w∗x+b+ϵ , ϵ ∼ N ( 0.01 , 1 ) \epsilon \sim N(0.01,1) ϵ∼N(0.01,1)
l o s s = ( W X + b − y ) 2 loss=(WX+b-y)^2 loss=(WX+b−y)2
用一个模型去学习数据的分布时会优先选择不同类型的模型,比如使用不同次方的多项式,如下图所示:
怎么衡量不同类型的模型的学习能力(model capacity)。
y = β 0 + β 1 x + β 2 x 2 + β 3 x 3 + ⋯ + β n x n + ϵ y=\beta_0+\beta_{1}x+\beta_{2}x^{2}+\beta_{3}x^{3}+\cdots+\beta_{n}x^{n}+\epsilon y=β0+β1x+β2x2+β3x3+⋯+βnxn+ϵ
常数时学习能力最弱,幂次越大能表达的情况越复杂。深度学习层数越深,学习能力越强。
现实生活中更多出现的是overfitting。我们需要解决两个问题,怎么检测overfitting(how to detect),怎么减少overfitting(how to reduce)。
Train-Val-Test划分
print('train:',len(train_db),'test:',len(test_db))
train_db,val_db=torch.utils.data.random_split(train_db,[50000,10000])
print('db1:',len(train_db),'db2:',len(val_db))
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)
将一个60k的样本划分为一个50k和一个10k。用Val来反馈。
K-fold cross-validation
先将Train与Val合并,再重新分出validation,好处是,长时间下去,每一个数据集都有可能参与进去,每次都做切换。
regularization_loss=0
for param in model.parameters():
regularization_loss+=torch.sum(torch.abs(param)) #先求绝对值,再求和
classify_loss=criteon(logits,target)
loss=classify_loss+0.01*regularization_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
L2-regularization(最常用,pytorch方便)
J ( W ; X , y ) + 1 2 λ ⋅ ∣ ∣ W ∣ ∣ 2 J(W;X,y)+\frac{1}{2}\lambda\cdot||W||^{2} J(W;X,y)+21λ⋅∣∣W∣∣2
λ \lambda λ是个超参数,需要人为调整。
device=torch.device('cuda:0')
net=MLP().to(device)
optimizer=optim.SCD(net.parameters(), lr=learning_rate, weight_decay=0.01)
criteon=nn.CrossEntropyLoss().to(device)
没有overfitting就设置weight-decay的话会导致性能急剧下降。