『计算机视觉』神经网络复杂度的计算

转载自知乎:卷积神经网络的复杂度分析

时间复杂度

即模型的运算次数,可用FLOPs衡量,也就是浮点运算次数(FLoating-point OPerations)。

单个卷积层的时间复杂度

      Time~O(M2·K2·Cin·Cout)

M:输出特征图边长

K:卷积核尺寸

C:通道数目

输出边长M计算公式为:

      M = (X - K + 2*Padding)//Stride + 1

  • 注1:为了简化表达式中的变量个数,这里统一假设输入和卷积核的形状都是正方形
  • 注2:严格来讲每层应该还包含 1 个 Bias 参数,这里为了简洁就省略了
  • 注3:TensorFlow中SAME形式输出为(X/Stride)上取整,因为TF中默认总共填充K/2,注意不需要进行2*Padding

卷积神经网络整体复杂度

      Time~O(∑l=1 M2·K2·Cl-1·Cl)

l表示层编号,实质就是对各个层求和。

卷积层实现可以很好的看清实现机理:out层、out长宽、in层循环,循环体内k2级别运算:

def conv2d(img, kernel):
    height, width, in_channels = img.shape
    kernel_height, kernel_width, in_channels, out_channels = kernel.shape
    out_height = height - kernel_height + 1
    out_width = width - kernel_width + 1
    feature_maps = np.zeros(shape=(out_height, out_width, out_channels))
    for oc in range(out_channels):              # Iterate out_channels (# of kernels)
        for h in range(out_height):             # Iterate out_height
            for w in range(out_width):          # Iterate out_width
                for ic in range(in_channels):   # Iterate in_channels
                    patch = img[h: h + kernel_height, w: w + kernel_width, ic]
                    feature_maps[h, w, oc] += np.sum(patch * kernel[:, :, ic, oc])

    return feature_maps

空间复杂度

空间复杂度(访存量),严格来讲包括两部分:总参数量 + 各层输出特征图。

  • 参数量:模型所有带参数的层的权重参数总量(即模型体积,下式第一个求和表达式)
  • 特征:模型在实时运行过程中每层所计算出的输出特征图大小(下式第二个求和表达式)

      Space~O(∑K2·Cl-1·Cl + ∑M2·Cl)

M:输出特征图边长

K:卷积核尺寸

C:通道数目

复杂度对模型的影响

时间复杂度决定了模型的训练/预测时间。如果复杂度过高,则会导致模型训练和预测耗费大量时间,既无法快速的验证想法和改善模型,也无法做到快速的预测。

空间复杂度决定了模型的参数数量。由于维度诅咒的限制,模型的参数越多,训练模型所需的数据量就越大,而现实生活中的数据集通常不会太大,这会导致模型的训练更容易过拟合。

当我们需要裁剪模型时,由于卷积核的空间尺寸通常已经很小(3x3),而网络的深度又与模型的表征能力紧密相关,不宜过多削减,因此模型裁剪通常最先下手的地方就是通道数

猜你喜欢

转载自www.cnblogs.com/hellcat/p/10442073.html