Dropout
Dropout可以作为训练深度神经网络的一种技巧。在每个训练批次中,通过随机让一部分的节点停止工作。同时在预测的过程中让所有的节点都其作用。
修改模型如下,主要就加了一个Dropout层,并采用0.5的丢弃率。
class SVHN_Model1(nn.Module):
def __init__(self):
super(SVHN_Model1, self).__init__()
model_conv = models.resnet18(pretrained=True)
model_conv.avgpool = nn.AdaptiveAvgPool2d(1)
model_conv = nn.Sequential(*list(model_conv.children())[:-1])
self.cnn = model_conv
self.dp = nn.Dropout(0.5)
self.relu = nn.ReLU()
self.fc1 = nn.Linear(512, 11)
self.fc2 = nn.Linear(512, 11)
self.fc3 = nn.Linear(512, 11)
self.fc4 = nn.Linear(512, 11)
self.fc5 = nn.Linear(512, 11)
def forward(self, img):
feat = self.cnn(img)
feat = self.dp(feat)
feat = self.relu(feat)
# print(feat.shape)
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)
return c1, c2, c3, c4, c5
实验采用单一变量控制,从实验结果来看,Dropout层加入后,Loss下降的要慢一些,ACC提高的也更慢,但是有效的防止了过拟合,需要很多epoch进行训练。实验结果还没提交,待续~
交叉验证
由于深度学习模型一般需要较长的训练周期,如果硬件设备不允许建议选取留出法,如果需要追求精度可以使用交叉验证的方法。
下面假设构建了10折交叉验证,训练得到10个CNN模型。
那么在10个CNN模型可以使用如下方式进行集成:
- 对预测的结果的概率值进行平均,然后解码为具体字符;
- 对预测的字符进行投票,得到最终字符。
TTA
# 修改tta为10
test_predict_label = predict(test_loader, model, 10)
测试集数据扩增(Test Time Augmentation,简称TTA)也是常用的集成学习技巧,数据扩增不仅可以在训练时候用,而且可以同样在预测时候进行数据扩增,对同一个样本预测三次,然后对三次结果进行平均。
实验总结
当前我提交的最高精度为0.76,
主要还是对Baseline进行修改,有以下几个关键点:
1、dataloader中需要把图片Resize为同样大小,我设置为(64,128),test和train的dataloader需要进行同样大小的resize操作,这也是大佬在直播中讲到的,很重要。
2、优化器:直接用Adam,学习率需要阶段下降
3、数据增强不要太花哨,一个randomcrop就足够可以了,基于位置的变换要更重要,randomcrop增强方法不会破掉数据原有分布,别的方法可能会增加黑边之类的。
4、单一变量原则很重要,这样实验结论很明确,不会浪费时间。Baseline尽量简单,不要乱七八糟花里胡哨。
总得来说还是用的图片分类思想,目标检测还在学习,希望能一起进步。