经过前面的赛题理解、数据读取与数据扩增、字符识别模型的建立和模型的训练与验证的学习;从跑通baseline,慢慢在这其中添加一些能让模型更优秀的元素,使得模型得分得到提高,在之前的基础上,学习最后一个任务:模型集成。
集成学习是一种机器学习范式。在集成学习中,我们会训练多个模型(通常称为“弱学习器”),解决相同的问题,并将它们结合起来以获得更好的结果。最重要的假设是:当弱模型被正确组合时,我们可以得到更精确和/或更鲁棒的模型。常见的集成学习方法有Stacking(堆叠法)、Bagging(自助聚合)和Boosting(提升法)。
- stacking:该方法通常考虑的是异质弱学习器,并行地学习它们,并通过训练一个【元模型】将它们组合起来,根据不同弱模型的预测结果输出一个最终的预测结果。
- bagging:该方法通常考虑的是同质弱学习器,相互独立地并行学习这些弱学习器,并按照某种确定性的平均过程将它们组合起来。
- boosting:该方法通常考虑的也是同质弱学习器。它以一种高度自适应的方法顺序地学习这些弱学习器(每个基础模型都依赖于前面的模型),并按照某种确定性的策略将它们组合起来。
总结: bagging 的重点在于获得一个方差比其组成部分更小的集成模型,而 boosting 和 stacking 则将主要生成偏置比其组成部分更低的强模型。
深度学习中的集成学习
值得借鉴的集成学习思路做法:
- Dropout
Dropout可以作为训练深度神经网络的一种技巧。在每个训练批次中,通过随机让一部分的节点停止工作。同时在预测的过程中让所有的节点都其作用。
Dropout经常出现在在先有的CNN网络中,可以有效的缓解模型过拟合的情况,也可以在预测时增加模型的精度。
加入Dropout后的网络结构如下:
# 定义模型
class SVHN_Model1(nn.Module):
def __init__(self):
super(SVHN_Model1, self).__init__()
# CNN提取特征模块
self.cnn = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=(3, 3), stride=(2, 2)),
nn.ReLU(),
nn.Dropout(0.25),
nn.MaxPool2d(2),
nn.Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2)),
nn.ReLU(),
nn.Dropout(0.25),
nn.MaxPool2d(2),
)
#
self.fc1 = nn.Linear(32*3*7, 11)
self.fc2 = nn.Linear(32*3*7, 11)
self.fc3 = nn.Linear(32*3*7, 11)
self.fc4 = nn.Linear(32*3*7, 11)
self.fc5 = nn.Linear(32*3*7, 11)
self.fc6 = nn.Linear(32*3*7, 11)
def forward(self, img):
feat = self.cnn(img)
feat = feat.view(feat.shape[0], -1)
c1 = self.fc1(feat)
c2 = self.fc2(feat)
c3 = self.fc3(feat)
c4 = self.fc4(feat)
c5 = self.fc5(feat)
c6 = self.fc6(feat)
return c1, c2, c3, c4, c5, c6
- TTA
测试集数据扩增(Test Time Augmentation,简称TTA)也是常用的集成学习技巧,数据扩增不仅可以在训练时候用,而且可以同样在预测时候进行数据扩增,对同一个样本预测三次,然后对三次结果进行平均。
def predict(test_loader, model, tta=10):
model.eval()
test_pred_tta = None
# TTA 次数
for _ in range(tta):
test_pred = []
with torch.no_grad():
for i, (input, target) in enumerate(test_loader):
c0, c1, c2, c3, c4, c5 = model(data[0])
output = np.concatenate([c0.data.numpy(), c1.data.numpy(),
c2.data.numpy(), c3.data.numpy(),
c4.data.numpy(), c5.data.numpy()], axis=1)
test_pred.append(output)
test_pred = np.vstack(test_pred)
if test_pred_tta is None:
test_pred_tta = test_pred
else:
test_pred_tta += test_pred
return test_pred_tta
总结:在经过五个阶段的学习后,虽然还存在一些问题,但是对模型的建立,模型的训练,验证集的产生有了大体的了解。通过这段时间学习,有以下几个注意点需要注意:
1、训练和测试的图片resize最好调成同样大小,对于模型精度会有帮助。
2、调整好学习率对于模型的学习有利。
3、在训练模型时,最好进行特征可视化,这样可以明确的知道模型的训练情况。
4、数据增强方法中推荐randomCrop,因为randomCrop不会破坏原有的数据分布。
5、在调参数的时候注意单一变量原则,防止出现不知道是哪个参数的修改引起的模型变化,浪费时间。
小组的学习会让我更加有动力,学习别人的高分经验。虽然目前了解的东西都很浅薄,但是对于整体的框架和学习思路有了了解,这对后续的学习提供了很大的帮助。