李宏毅《机器学习》总结 - 2022 HW3(图像识别、CNN) Strong Baseline

调参调吐了。。做的最艰难的一次(虽然一共也没做几次)
最好做到了 private 0.82 / public 0.808
这题前前后后做了五天。。主要是后来 train 一次就得花很长很长时间,我的 kaggle 余额也用的差不多了。。
image

这个题目大概就是给你 11 种食物的图片,让你学习,并分类

题目分析

4-fold ensemble \(epoch=25\) 能过 medium,\(epoch=100\) 过 strong

代码分析

处理图片就先转化成 \(128\times 128\) 个 pixel,然后做 CNN。pytorch 的卷积层长这样:

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)

前面两个可以理解成原来的图为 \(\mathit{in}\times N\times N\),卷积之后变成 \(\mathit{out}\times N\times N\)
kernel 就是 filter 的大小,stride 就是 filter 每次移动的步长,padding 就是移动出去之后填充的数字
做完卷积之后通常接一个batch normalization,防止 gradient exploding/vanishing
为了减少运算,一般再加一个池化层,设成 \(2\times 2\)

class Classifier(nn.Module):
   def __init__(self):
       super(Classifier, self).__init__()
       # torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
       # torch.nn.MaxPool2d(kernel_size, stride, padding)
       # input 維度 [3, 128, 128]
       self.cnn = nn.Sequential(
           nn.Conv2d(3, 64, 3, 1, 1),  # [64, 128, 128]
           nn.BatchNorm2d(64),
           nn.ReLU(),
           nn.MaxPool2d(2, 2, 0),      # [64, 64, 64] 
          

           nn.Conv2d(64, 128, 3, 1, 1), # [128, 64, 64]
           nn.BatchNorm2d(128),
           nn.ReLU(),
           nn.MaxPool2d(2, 2, 0),      # [128, 32, 32]
         
           nn.Conv2d(128, 256, 3, 1, 1), # [256, 32, 32]
           nn.BatchNorm2d(256),
           nn.ReLU(),
           nn.MaxPool2d(2, 2, 0),      # [256, 16, 16]

           nn.Conv2d(256, 512, 3, 1, 1), # [512, 16, 16]
           nn.BatchNorm2d(512),
           nn.ReLU(),
           nn.MaxPool2d(2, 2, 0),       # [512, 8, 8]
           
           nn.Conv2d(512, 512, 3, 1, 1), # [512, 8, 8]
           nn.BatchNorm2d(512),
           nn.ReLU(),  
           nn.MaxPool2d(2, 2, 0),       # [512, 4, 4]
       )
       self.fc = nn.Sequential(
           nn.Dropout(0.4),
           nn.Linear(512*4*4, 1024),
           nn.ReLU(),
           nn.Linear(1024, 512),
           nn.ReLU(),
           nn.Linear(512, 11)
       )

   def forward(self, x):
       out = self.cnn(x)
       out = out.view(out.size()[0], -1)
       return self.fc(out)

然后结合一下 ensemble,简单来说就是跑好几次这个模型,testing 预测的时候取 argmax,也叫做 k-fold,这里我让 \(k=4\)
还有就是 cross validation,由于是 4-fold,我每次重新划分训练集和验证集,具体的可以先把所有的训练资料存起来,然后每一轮训练的时候重新划分。
这样跑几轮,大概 2、3 个小时(当时我让 \(epoch=25\)),就跑出来 private 0.77 / public 0.79(所以后来四天我就让 public 提升了 0.02?
image

感觉到 strong baseline 就只需要把训练时间延长就行了,也试了不同的模型 & loss 函数,感觉差距也不是很大。单个模型延长到 \(epoch=100\),1-fold 跑出来就 0.78 了
image
又跑了将近 20 个小时,跑出来 4-fold 就是 private 0.82 了

posted @ 2024-01-31 19:37  SkyRainWind  阅读(78)  评论(0编辑  收藏  举报