Dynamic Shaped Network

Table of Contents

1. Dynamic Shaped Network

支持动态输入的模型主要有两类:

  1. fully convolutional networks
  2. 使用 adaptive pooling 的网络

1.1. Fully Convolutional Networks

由于 cnn 层计算时并不需要针对特定的尺寸, 所以全卷积网络本来就是和 input shape 无关的.

import numpy as np
import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers


def get_model():
    inputs = keras.Input(shape=(None, None, 3))

    outputs = inputs
    for i in range(3):
        outputs = layers.Conv2D(
            filters=16,
            kernel_size=[3, 3],
            activation="relu",
            padding="SAME",
        )(outputs)

    return keras.Model(inputs, outputs)


if __name__ == "__main__":
    model = get_model()
    print(model.predict(np.random.randn(1, 10, 10, 3)).shape)
    print(model.predict(np.random.randn(1, 20, 20, 3)).shape)

(1, 10, 10, 16) (1, 20, 20, 16)

fully convolutional network 的一个例子就是 semantic segmentation 里的 FCN 模型

1.2. Adaptive Pooling

传统的 cnn 通常最后需要一个 fully connected 来输出有用的信息, 而 fully connected 要求它的输入必须是确定大小的. 通过在 fully connected前插入特殊的 pooling, 可以达到把 cnn 输出的 feature 变成固定大小.

例如 torchvision 里的模型例如 alexnet, vgg 等都是 `features -> avgpool -> classifier` 的形式, 其中 `avgpool` 是AdaptiveAvgPool2d, 用了支持变长的输入.

正常的 pooling 使用 定长 的 stride, 针对变长的输入会产生 变长 的输出, 特殊的 pooling 使用和输入大小成正比的 变长 stride, 针对变长的输入会产生 定长 的输出.

例如:

  1. 输入是 100, 使用 stride 为 2, 输出为 50
  2. 输入是 200, stride 会变为 4, 输出还是 50

1.2.1. Global Average Pooling

GlobalAveragePooling2D 相当于 pool size 和 stride 都是变长的 [H,W], 输入为 [H,W,C], 输出为 [C]

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 2021-09-24 10:32
import numpy as np
import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers


def get_model():
    inputs = keras.Input(shape=(None, None, 3))

    outputs = inputs
    for i in range(3):
        outputs = layers.Conv2D(
            filters=16,
            kernel_size=[3, 3],
            activation="relu",
            padding="SAME",
        )(outputs)

    outputs = layers.GlobalAveragePooling2D()(outputs)
    outputs = layers.Dense(1)(outputs)
    return keras.Model(inputs, outputs)


if __name__ == "__main__":
    model = get_model()
    print(model.layers[1].output.shape)
    print(model.predict(np.random.randn(1, 10, 10, 3)).shape)
    print(model.predict(np.random.randn(1, 20, 20, 3)).shape)

(None, None, None, 16) (1, 1) (1, 1)

Backlinks

DeepLab (DeepLab > DeepLabV3 Network): 除了 ASPP, 还有一个 Image Pooling 层, 它实际是对 block4 做了一个 GlobalAveragePooling2D 后再通过 1x1 conv2d 和 bilinear interpolation, 最终也是输 出 (h, w, 256)

Faster RCNN (Faster RCNN > ROIPooling): 2. 通过 roi pooling 得到特定尺寸的 feature map, 所谓的 roi pooling 实际上 GlobalAveragePoolingSpatial Pyramid Pooling 类似.

GNN (GNN > GCN Example > GCN for Classification): 另一种方法是用 global pooling, 类似于图片上的 global average pooling, 即把所有的 node 的值平均

1.2.2. Adaptive Average Pooling

import torch
from torch import nn

m = nn.AdaptiveAvgPool2d((5, 7))
input = torch.randn(1, 64, 8, 9)
output = m(input)
print(output.shape)

torch.Size([1, 64, 5, 7])

pool size 和 stride 可以看做是变长的 [H/a,W/b], 其中 (a,b) 是它的 output size

GlobalAveragePooling2D 是 AdaptiveAveragePooling2D 的特殊情况: output size 为 (1,1)

Backlinks

AlexNet (AlexNet > Network): torchvison 的 alexnet 加入了一个 Adaptive Average Pooling, 使得它能支持变长的输 入.

PSPNet (PSPNet > Network > pyramid pooling module): 1. 使用 4 个 Adaptive Average Pooling, output size 分别为 1, 2, 3, 6

Vgg (Vgg > Network): features 后面的 7x7x512 是一个 adaptive average pooling

1.2.3. Spatial Pyramid Pooling

另外还是一种称为 Spatial Pyramid Pooling, 它使用多个不同尺寸的变长 pooling, 所以称为 pyramid:

假设输入 feature map 是 [H,W,C], 且它使用这三种尺寸的 pooling:

  1. [H,W], 输出 C*1
  2. [H/2,W/2], 输出 C*4
  3. [H/4,W/4], 输出 C*16

concat 在一起后输出 C*21 个值, 不论 H,W 是多少, 输出都是固定的 C*21

Backlinks

DeepLab (DeepLab): DeepLab 是 google 提出的 semantic segmentation 模型, 最新的模型是 v3 和 v3+, 主 要思想是利用多个不同 dilation rate 的 Dilated Conv2D 来融合不同尺度上的特征, 有 点类似于 Spatial Pyramid Pooling

Faster RCNN (Faster RCNN > ROIPooling): 2. 通过 roi pooling 得到特定尺寸的 feature map, 所谓的 roi pooling 实际上 GlobalAveragePoolingSpatial Pyramid Pooling 类似.

PSPNet (PSPNet): pspnet 是一个 semantic segmentation 模型, 它利用 Spatial Pyramid Pooling 获得全 局上下文信息. 它的结构与 DeepLab 非常像: 前者使用不同尺度的 pooling 叠加, 后者使 用不同尺度的 dilation conv 叠加.

Backlinks

CNN (CNN > Dynamic Shaped Network): Dynamic Shaped Network

Author: [email protected]
Date: 2021-09-29 Wed 00:00
Last updated: 2022-01-30 Sun 16:30

知识共享许可协议