PyTorch项目实战12——CIFAR10训练模型全局平均池化

140 阅读2分钟

1 全局平均池化

使用全局平均池化,提升模型效率,之前的模型训练耗时非常长,通过采用全局平均池化,可以大大缩小参数规模,泛化能力好。

但是随着参数的减少,也有其不足之处,比如参数规模变小后,模型架构变得比较单一。要想提升准确率,需要增加迭代。

在程序中增加训练中使用到的参数输出。

image.png

在未使用全局平均池化时,使用到的参数如下:

image.png

2 优化

修改 juejin.cn/post/724308… 中初始化神经网络全连接层代码:

def __init__(self):
    super(CNNNet, self).__init__()
    # 第一层卷积网络,输入通道,输出通道,卷积盒,步长
    self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1)
    # 第一个池化层,卷积盒,步长,不会改变通道数
    self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
    # 第二层卷积网络
    self.conv2 = nn.Conv2d(in_channels=16, out_channels=36, kernel_size=3, stride=1)
    self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
    # 全连接层,输入特征,输出特征
    # 对以下语句进行改写
    # self.fc1 = nn.Linear(1296, 128)
    # self.fc2 = nn.Linear(128, 10)

    # 改写后,将channel结果变为单一值
    self.app = nn.AdaptiveAvgPool2d(1)
    self.fc3 = nn.Linear(36, 10)

同时修改串联层级部分的代码

# 串联层级
def forward(self, x):
    # 处理卷积之后的非线性变化
    # 对原数据做第一层卷积后再进行池化操作
    x = self.pool1(fun.relu(self.conv1(x)))
    # 对做完第一层卷积的数据,再次进行第二层卷积及池化操作
    x = self.pool2(fun.relu(self.conv2(x)))
    # reshape
    # 对以下代码进行改写
    # x = x.view(-1, 36*6*6)
    # # 完成两层全连接,并进行非线性变化
    # x = fun.relu(self.fc2(fun.relu(self.fc1(x))))
    
    # 改写后的代码如下
    x = self.app(x)
    x = x.view(x.shape[0], -1)
    x = self.fc3(x)
    return x

重新执行后,打印出训练中使用到的参数个数

image.png

可以看出,在使用了全局平均池化技术后,参数由原来的 173742 减小到了 6806,YYDS啊,参数减少到了百分之四,优化效果突出。