因为连续做了两个使用 CNN 网络的模型训练,所以这里单独开一个记录 CNN 调参的心路历程。

模型

经过众多测试,得到的通用模型如下。基本思想是深的神经网络以及小的卷积核,并且卷积核的 channel 逐渐增加的机制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class SuperNaiveModel(nn.Module):
def __init__(self):
super(SuperNaiveModel, self).__init__()
self.conv0 = nn.Sequential(
torch.nn.Conv2d(1, 64, kernel_size=5, stride=2, padding=3),
torch.nn.BatchNorm2d(64, momentum=0.1),
torch.nn.ReLU(),
)
self.conv1 = torch.nn.Sequential(
torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(stride=2, kernel_size=2))
self.conv2 = torch.nn.Sequential(
torch.nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(stride=2, kernel_size=2))
self.conv20 = torch.nn.Sequential(
torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(stride=2, kernel_size=2))
self.conv3=torch.nn.Sequential(
torch.nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
torch.nn.BatchNorm2d(512, momentum=0.1),
torch.nn.ReLU(),
torch.nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
torch.nn.BatchNorm2d(512, momentum=0.1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(stride=2, kernel_size=2))
self.dense = torch.nn.Sequential(
torch.nn.Linear(512 * 4 * 4, 20),
nn.LogSoftmax(dim=1)
)

def forward(self, x):
x = x.reshape(x.shape[0], 1, 128, 128).float()
x = self.conv0(x)
x = self.conv1(x)
x = self.conv2(x)
x = self.conv20(x)
x = self.conv3(x)
x = x.view(x.shape[0], 512 * 4 * 4)
x = self.dense(x)
return x1

设定

由于训练资源不够,所以使用一个 5x5 的卷积核代替了应有的两个 3x3 卷积核链接的效果。根据 VGG,连续使用两个 3x3可能效果会好一些。

Batchnorm 是一个玄学的东西,它的功能并不如预期一样稳定,并且没有必要在没一个网络后都接一个 BN 层。事实上,根据实验,在模型的最开始和最后一层添加 BN 层的效果是明显的。ReLU 层作为非线性化的方法,几乎是必须的。

此外,过多的全连接层是不利的,每多增一个全连接层会对模型造成一定的影响。预测的原因是由于数据量不够支撑全连接层的泛化性,导致容易过拟合,泛化性差,反而不如一层全连接。所以全连接层越多越好不是绝对的。