0 前言
复杂度对模型的影响
时间复杂度决定了模型的训练/预测时间。如果复杂度过高,会导致模型训练和预测耗费大量时间,既无法快速的验证想法和改善模型,也无法做到快速的预测。
空间复杂度决定了模型的参数数量。由于维度灾难(curse of dimensionality)的限制,模型的参数越多,训练模型所需的数据量就越大,而现实生活中的数据集通常不会太大,这会导致模型的训练更容易过拟合。
1. 时间复杂度
时间复杂度即模型的运行次数。
单个卷积层的时间复杂度:Time~O(M^2 * K^2 * Cin * Cout)
- M:输出特征图(Feature Map)的尺寸。
- K:卷积核(Kernel)的尺寸。
- Cin:输入通道数。
- Cout:输出通道数。
注1:为了简化表达式变量个数,统一假设输入和卷积核的形状是正方形,实际中如果不是,则将M ^2替换成特征图的长宽相乘即可;
注2:每一层卷积都包含一个偏置参数(bias),这里也给忽略了。加上的话时间复杂度则为:O(M^2 * K^2 * Cin * Cout+Cout)。
2.空间复杂度
空间复杂度即模型的参数数量。
单个卷积的空间复杂度:Space~O(K^2 * Cin * Cout)
空间复杂度只与卷积核的尺寸K、通道数C相关。而与输入图片尺寸无关。当我们需要裁剪模型时,由于卷积核的尺寸通常已经很小,而网络的深度又与模型的能力紧密相关,不宜过多削减,因此模型裁剪通常最先下手的地方就是通道数。
3. 数据流的变化
设计好了网络结构之后,网络的卷积核大小,通道,步长,padding等都已经确定了,那么一个好的工程师应该非常清楚输入数据在每一层的流动情况。
计算公式:
:卷积前图像的宽度;
:卷积后Feature Map的宽度;
:卷积前图像的高度;
: 卷积后Feature Map的高度;
- P :padding数量;
- S:stride步长.
首先计算一下最简单的LeNet。网络结构如下:
下面是我自己论文中的一个架构图,之前一直是直接调用TensorFlow网络运行,没有关注过数据流的走向,通过今天的梳理发现全连接层确实是挺占内存的。另外计算时间复杂度的话,和输入输出feature map的大小有关,网上有人说为什么设计网络的通道数先小后大,是为了维护前面和后面的卷积计算量平衡,由此看也是有些道理的吧。[注:我的架构图在第3,7,9层卷积前面各有一个最大池化操作,在图中没有标出]
改进Resnet架构:
数据流变化:
网络层(操作) | 输入 | filter | stride | padding | 输出 | 计算公式 | 参数量 |
Input | 57![]() ![]() | - | - | - | - | - | 0 |
Conv1 | 57![]() ![]() | 1![]() | 1 | 1 | 57![]() ![]() | 1![]() ![]() ![]() | 96 |
Conv2 | 57![]() ![]() | 5![]() | 1 | 1 | 57![]() ![]() | 5![]() ![]() ![]() | 96 |
Max Pool1 | 57![]() ![]() | - | 2 | - | 29![]() ![]() | - | - |
Conv3 | 29![]() ![]() | 3![]() | 1 | 1 | 29![]() ![]() | 3![]() ![]() ![]() | 2320 |
Conv4 | 29![]() ![]() | 3![]() | 1 | 1 | 29![]() ![]() | 3![]() ![]() ![]() | 2320 |
Conv5 | 29![]() ![]() | 3![]() | 1 | 1 | 29![]() ![]() | 3![]() ![]() ![]() | 2320 |
Conv6 | 29![]() ![]() | 3![]() | 1 | 1 | 29![]() ![]() | 3![]() ![]() ![]() | 2320 |
Max Pool2 | 29![]() ![]() | - | 2 | - | 15![]() ![]() | - | - |
Conv7 | 15![]() ![]() | 3![]() | 1 | 1 | 15![]() ![]() | 3![]() ![]() ![]() | 4640 |
Conv8 | 15![]() ![]() | 3![]() | 1 | 1 | 15![]() ![]() | 3![]() ![]() ![]() | 4640 |
Max Pool3 | 15![]() ![]() | - | 2 | 1 | 8![]() ![]() | - | - |
Conv9 | 8![]() ![]() | 3![]() | 1 | 1 | 8![]() ![]() | 3![]() ![]() ![]() | 4640 |
Conv10 | 8![]() ![]() | 3![]() | 1 | 1 | 8![]() ![]() | 3![]() ![]() ![]() | 4640 |
Conv11 | 8![]() ![]() | 3![]() | 1 | 1 | 8![]() ![]() | 3![]() ![]() ![]() | 4640 |
Conv12 | 8![]() ![]() | 3![]() | 1 | 1 | 8![]() ![]() | 3![]() ![]() ![]() | 4640 |
Max Pool4 | 8![]() ![]() | - | 2 | 1 | 4![]() ![]() | - | - |
FC1 | 4![]() ![]() | - | - | - | 512 | 4![]() ![]() ![]() | 262656 |
FC2 | 512 | - | - | - | 4 | 512*4+4 | 2052 |
参考网址: