减少过拟合:减少数据;将模型换成一个浅层模型;正则化;dropout;early stopping
设置交叉验证
将数据集分为训练集、dev和测试集
dev用来提前防止训练过拟合,每隔一段时间观察testperformace,选取最好的性能模型
test是真实交给客户,用来测量模型的真实性能,test不能用来反馈给模型训练
K-fold交叉验证:每次迭代都随机将训练数据集划分为k份,将其中的k-1份用来做训练集,剩余的1份用来做验证
目的:及防治模型的“死记硬背”,也充分利用了所有数据集
实际效果:提升模型性能并不多
正则化
- 原理:当模型参数的范数越小,模型的复杂度越小
一阶正则:
J ( θ ) = − 1 m ∑ i = 1 m [ y i ln y ^ i + ( 1 − y i ) ln ( 1 − y ^ i ) ] + λ ∑ i = 1 n ∣ θ i ∣ J(\theta)=-\frac{1}{m} \sum_{i=1}^{m}\left[y_{i} \ln \hat{y}_{i}+\left(1-y_{i}\right) \ln \left(1-\hat{y}_{i}\right)\right]+\lambda \sum_{i=1}^{n}\left|\theta_{i}\right| J(θ)=−m1i=1∑m[yilny^i+(1−yi)ln(1−y^i)]+λi=1∑n∣θi∣
regularization_loss+=torch.sum(torch.abs(param))
loss=classify_loss+0.01*regularization_loss
loss.backward()
二阶正则:
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
optimzer=optim.SGD(net.parameters(),lr=learning_rate,weight_decay=0.01) #L2范数
动量与学习率衰减
- 考虑历史动量方向
optimzer=optim.SGD(net.parameters(),lr=learning_rate,momentu=args.momentum,weight_decay=0.01) #adam中内置了动量,不需要自己设置
一般学习率在:0.0001~0.001之间
early stopping ,dropout
- early stopping:提前终止训练,因为test.acc达到了最高值
- dropout:随机在两层之间的连接中选取部分weight设为0
注意:
torch.nn.Dropout(p=dropout_prob)
tf.nn.dropout(keep_prob)
model.train() :启用 BatchNormalization 和 Dropout
model.eval() :不启用 BatchNormalization 和 Dropout