SearchSpaceZoo.md 9.29 KB
Newer Older
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# 搜索空间集合

## DartsCell

DartsCell 是从[这里](https://github.com/microsoft/nni/tree/master/examples/nas/darts)[CNN 模型](./DARTS.md)中提取出来的。 一个 DartsCell 是一个包含 N 个节点的序列的有向无环图 ,其中每个节点代表一个潜在特征的表示(例如卷积网络中的特征图)。 从节点1到节点2的有向边表示一些将节点1转换为节点2的操作。这些操作获取节点1的值并将转换的结果储存在节点2上。 节点之间的[操作](#darts-predefined-operations)是预定义的且不可更改。 一条边表示从预定义的操作中选择的一项,并将该操作将应用于边的起始节点。 一个 cell 包括两个输入节点,一个输出节点和其他 `n_node` 个节点。 输入节点定义为前两个 cell 的输出。 Cell 的输出是通过对所有中间节点进行归约运算(例如连接)而获得的。 为了使搜索空间连续,在所有可能的操作上通过softmax对特定操作选择进行松弛。 通过调整每个节点上softmax的权重,选择概率最高的操作作为最终结构的一部分。 可以通过堆叠多个cell组成一个CNN模型,从而构建一个搜索空间。 值得注意的是,在DARTS论文中,模型中的所有cell都具有相同的结构。

Darts的搜索空间如下图所示。 请注意,在NNI的实现中将最后一个中间节点与输出节点进行了合并。

![](../../img/NAS_Darts_cell.svg)

预定义的操作在[参考](#predefined-operations-darts)中列出。

```eval_rst
..  autoclass:: nni.nas.pytorch.search_space_zoo.DartsCell
    :members:
```

### 示例代码

[示例代码](https://github.com/microsoft/nni/tree/master/examples/nas/search_space_zoo/darts_example.py)

```bash
git clone https://github.com/Microsoft/nni.git
cd nni/examples/nas/search_space_zoo
# search the best structure
python3 darts_example.py
```

<a name="predefined-operations-darts"></a>

### 参考

所有Darts支持的操作如下。

* 最大池化 / 平均池化
  * 最大池化:调用`torch.nn.MaxPool2d`。 这个操作对所有输入的通道进行最大池化。 操作的参数固定,`kernel_size=3``padding=1`。 在池化操作后通过BatchNorm2d得到最终结果。
  * 平均池化:调用`torch.nn.AvgPool2d`。 这个操作对所有输入的通道进行平均池化。 操作的参数固定,`kernel_size=3``padding=1`。 在池化操作后通过BatchNorm2d得到最终结果。

    参数为`kernel_size=3`和`padding=1` 的最大池化操作和平均池化操作后均有BatchNorm2d操作。
    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.darts_ops.PoolBN
    ```
* 跳过连接

    两个节点之间没有任何操作。 调用` torch.nn.Identity `将其获取的内容转发到输出。
* 零操作

    两个节点之间没有连接。
* DilConv3x3 / DilConv5x5

    <a name="DilConv"></a>深度可分离卷积。 3x3深度可分离卷积是由 `C_in` 组的3x3深度卷积和1x1的卷积串联组成。 这个操作减少了参数的数量。 输入首先通过RelLU,然后通过DilConv,最后是batchNorm2d。 **请注意这个操作不是扩散卷积,但是我们按照NAS论文中的约定命名为DilConv。**3x3深度可分离卷积的参数是 `kernel_size=3`, `padding=1` 。5x5深度可分离卷积的参数是 `kernel_size=5`, `padding=4`。
    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.darts_ops.DilConv
    ```
* SepConv3x3 / SepConv5x5

    由两个参数为`kernel_size=3`, `padding=1`或`kernel_size=5`, `padding=2` 的深度可分离卷积串联组成。
    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.darts_ops.SepConv
    ```

## ENASMicroLayer

这个层是由[这里](https://github.com/microsoft/nni/tree/master/examples/nas/enas)的模型提取出来的。 一个模型包含共享结构的多个块。 一个块由一些常规层和约简层组成,`ENASMicroLayer`是这两型层的统一实现。 这两类层之间的唯一区别是约简层的所有操作`stride=2`

ENAS Micro的一个cell是含有N个节点的有向无环图。其中节点表示张量,边表示N个节点间的信息流。 一个cell包含两个输入节点和一个输出节点。 接下来节点选择前两个之前的节点作为输入,并从[预定义的的操作集](#predefined-operations-enas)中选择两个操作,分别应用到输入上,然后将它们相加为该节点的输出。 例如,节点4选择节点1和节点3作为输入,然后分别对输入应用` MaxPool `` AvgPool `,然后将它们相加作为节点4的输出。 未用作任何其他节点输入的节点将被视为该层的输出。 如果有多个输出节点,则模型将计算这些节点的平均值作为当前层的输出。

ENAS Micro的搜索空间如下图所示。

![](../../img/NAS_ENAS_micro.svg)

预定义的操作在[参考](#predefined-operations-enas)中列出。

```eval_rst
..  autoclass:: nni.nas.pytorch.search_space_zoo.ENASMicroLayer
    :members:
```

归约层由两个卷积操作和之后的BatchNorm组成,每个卷积操作都将输出` C_out//2`个通道并将它们在通道方向上串联作为输出。 卷积的参数是`kernel_size=1``stride=2`,并且它们对输入进行交替采样以降低分辨率而不会丢失信息。 该层封装在`ENASMicroLayer`中。

### 示例代码

[示例代码](https://github.com/microsoft/nni/tree/master/examples/nas/search_space_zoo/enas_micro_example.py)

```bash
git clone https://github.com/Microsoft/nni.git
cd nni/examples/nas/search_space_zoo
# search the best cell structure
python3 enas_micro_example.py
```

<a name="predefined-operations-enas"></a>

### 参考

所有ENAS Micro支持的操作如下。

* 最大池化 / 平均池化
    * 最大池化:调用`torch.nn.MaxPool2d`。 这个操作对所有输入的通道进行最大池化,之后进行BatchNorm2d。 池化操作的参数为`kernel_size=3`,,`stride=1``padding=1`
    * 平均池化:调用`torch.nn.AvgPool2d`。 这个操作对所有输入的通道进行最大池化,之后进行BatchNorm2d。 池化操作的参数为`kernel_size=3`,,`stride=1``padding=1`
    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.Pool
    ```

* SepConv
    * SepConvBN3x3:首先进行ReLU,之后进行[DilConv](#DilConv),最后是BatchNorm2d。 卷积操作的参数为`kernel_size=3`,,`stride=1``padding=1`
    * SepConvBN5x5:进行与之前相同的操作,但是它具有不同的内核大小和填充,分别设置为5和2。

    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.SepConvBN
    ```

* 跳过连接

    调用`torch.nn.Identity`直接连接到一个cell。

## ENASMacroLayer

在宏搜索中,控制器为每个层做出两个决定:i)对上一层的结果执行的[操作](#macro-operations),ii)通过跳过连接,连接到之前的那个层。 ENAS使用控制器来设计整个模型结构而不是模型的某一部分。 操作的输出将与跳过连接的所选层的张量连接在一起。 NNI提供了宏搜索中使用的[预定义的操作](#macro-operations),在[参考](#macro-operations)中列出。

ENAS Macro的搜索空间如下图所示。

![](../../img/NAS_ENAS_macro.svg)

```eval_rst
..  autoclass:: nni.nas.pytorch.search_space_zoo.ENASMacroLayer
    :members:
```

为了描述整个搜索空间,NNI提供了一个模型,该模型是通过堆叠ENASMacroLayer构成的。

```eval_rst
..  autoclass:: nni.nas.pytorch.search_space_zoo.ENASMacroGeneralModel
    :members:
```

### 示例代码

[示例代码](https://github.com/microsoft/nni/tree/master/examples/nas/search_space_zoo/enas_macro_example.py)

```bash
git clone https://github.com/Microsoft/nni.git
cd nni/examples/nas/search_space_zoo
# search the best cell structure
python3 enas_macro_example.py
```

<a name="macro-operations"></a>

### 参考

所有ENAS Macro支持的操作如下。

* ConvBranch

    首先将所有输入传递到StdConv,该操作由1x1Conv,BatchNorm2d和ReLU组成。 然后进行下列的操作之一。 最终结果通过后处理,包括BatchNorm2d和ReLU。
    * Separable Conv3x3:如果`separable=True`,则cell将使用[ SepConv](#DilConv)而不是常规的卷积操作。 卷积操作的参数为`kernel_size=3`,`stride=1` ,`padding=1`。
    * Separable Conv5x5:卷积操作的参数为`kernel_size=5`,,`stride=1` ,`padding=2`。
    * Normal Conv3x3:如果`separable=False`,cell将使用参数为` kernel_size=3`,`stride=1`,` padding=1`的一般卷积。
    * Separable Conv5x5:卷积操作的参数为`kernel_size=5`,,`stride=1` ,`padding=2`。

    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.ConvBranch
    ```
* PoolBranch

    首先将所有输入传递到StdConv,该操作由1x1Conv,BatchNorm2d和ReLU组成。 然后对中间结果进行池化操作和BatchNorm。
    * 平均池化:调用`torch.nn.AvgPool2d`。 这个操作对所有输入的通道进行平均池化。 池化操作的参数为`kernel_size=3`,,`stride=1` ,`padding=1`。
    * 最大池化:调用`torch.nn.MaxPool2d`。 这个操作对所有输入的通道进行最大池化。 池化操作的参数为`kernel_size=3`,,`stride=1` ,`padding=1`。

    ```eval_rst
    ..  autoclass:: nni.nas.pytorch.search_space_zoo.enas_ops.PoolBranch
    ```

<!-- push -->