神经架构搜索算法
本页面描述了Katib中神经架构搜索(NAS)算法的工作原理。
高效神经架构搜索 (ENAS)
该算法遵循Hieu Pham、Melody Y. Guan、Barret Zoph、Quoc V. Le和Jeff Dean提出的通过参数共享的高效神经架构搜索的思想(https://arxiv.org/abs/1802.03268)以及Barret Zoph和Quoc V. Le的使用强化学习的神经架构搜索(https://arxiv.org/abs/1611.01578)。
该实现基于 《通过参数共享的高效神经架构搜索》 的GitHub和 Google对ENAS的实现。 它使用带有LSTM单元的递归神经网络作为控制器来生成神经架构候选。 并且这个控制器网络是通过策略梯度更新的。然而,目前不支持参数共享。
Katib 实现
Katib 以特定格式表示神经网络。如果层数 (n) = 12 并且可能的操作数量 (m) = 6,则架构的定义将如下所示:
[2]
[0 0]
[1 1 0]
[5 1 0 1]
[1 1 1 0 1]
[5 0 0 1 0 1]
[1 1 1 0 0 1 0]
[2 0 0 0 1 1 0 1]
[0 0 0 1 1 1 1 1 0]
[2 0 1 0 1 1 1 0 0 0]
[3 1 1 1 1 1 1 0 0 1 1]
[0 1 1 1 1 0 0 1 1 1 1 0]
有 n 行,第 ith 行有 i 个元素,并描述第 ith 层。请注意,层 0 是输入,不包含在此定义中。
在每一行,第一整数范围从 0 到 m-1,表示此层的操作。 从第二个位置开始,第 kth 整数是一个布尔值,表示 (k-2)th 层是否与此层有跳过连接。 (从 (k-1)th 层到 kth 层将始终存在连接)
GetSuggestion() 的输出
算法服务中GetSuggestion()的输出由两个部分组成:
architecture 和 nn_config。
architecture 是神经架构定义的 JSON 字符串。格式如上所述。一个例子是:
[[27], [29, 0], [22, 1, 0], [13, 0, 0, 0], [26, 1, 1, 0, 0], [30, 1, 0, 1, 0, 0], [11, 0, 1, 1, 0, 1, 1], [9, 1, 0, 0, 1, 0, 0, 0]]
nn_config 是一个 json 字符串,用于详细描述层数、输入大小、输出大小以及每个操作索引所代表的内容。与上述架构对应的 nn_config 可以是:
{
"num_layers": 8,
"input_sizes": [32, 32, 3],
"output_sizes": [10],
"embedding": {
"27": {
"opt_id": 27,
"opt_type": "convolution",
"opt_params": {
"filter_size": "7",
"num_filter": "96",
"stride": "2"
}
},
"29": {
"opt_id": 29,
"opt_type": "convolution",
"opt_params": {
"filter_size": "7",
"num_filter": "128",
"stride": "2"
}
},
"22": {
"opt_id": 22,
"opt_type": "convolution",
"opt_params": {
"filter_size": "7",
"num_filter": "48",
"stride": "1"
}
},
"13": {
"opt_id": 13,
"opt_type": "convolution",
"opt_params": {
"filter_size": "5",
"num_filter": "48",
"stride": "2"
}
},
"26": {
"opt_id": 26,
"opt_type": "convolution",
"opt_params": {
"filter_size": "7",
"num_filter": "96",
"stride": "1"
}
},
"30": {
"opt_id": 30,
"opt_type": "reduction",
"opt_params": {
"reduction_type": "max_pooling",
"pool_size": 2
}
},
"11": {
"opt_id": 11,
"opt_type": "convolution",
"opt_params": {
"filter_size": "5",
"num_filter": "32",
"stride": "2"
}
},
"9": {
"opt_id": 9,
"opt_type": "convolution",
"opt_params": {
"filter_size": "3",
"num_filter": "128",
"stride": "2"
}
}
}
}
这个神经架构可以被可视化为:

以下项目可以在Katib中实现,以更好地支持ENAS:
- 添加“微型”模式,这意味着搜索一个神经元而不是整个神经网络。
- 添加对循环神经网络的支持,并为宾夕法尼亚树库任务构建一个训练容器。
- 添加参数共享,如果可能的话。
- 将LSTM.py中自定义的LSTM单元更改为
tf.nn.rnn_cell.LSTMCell - 将建议检查点存储到PVC,以防止意外的enas服务pod重启
- 将
RequestCount添加到 API 中,以便建议可以清理已完成研究的信息。
可微分架构搜索 (DARTS)
该算法遵循了 Hanxiao Liu、Karen Simonyan 和 Yiming Yang 提出的 DARTS: 可微分架构搜索 的思路: https://arxiv.org/abs/1806.09055。实现基于 官方 GitHub 实现 和 流行的代码库。
该算法通过以可微分的方式对任务进行公式化,从而解决了架构搜索的可扩展性挑战。它基于搜索空间中的连续放松和梯度下降。它能够高效地设计用于图像分类(在CIFAR-10和ImageNet上)的高性能卷积架构和用于语言建模(在Penn Treebank和WikiText-2上)的递归架构。
Katib 实现
为了在当前的Katib功能中支持DARTS,实施按以下方式进行:
DARTS Suggestion service 创建实验搜索空间中的一组原始操作。 例如:
['separable_convolution_3x3', 'dilated_convolution_3x3', 'dilated_convolution_5x5', 'avg_pooling_3x3', 'max_pooling_3x3', 'skip_connection']建议将算法设置、层数和原语集合返回给Katib控制器
Katib 控制器启动 DARTS 训练容器 并设置适当的参数和所有可能的操作。
训练容器运行DARTS算法。
指标收集器从训练容器日志中保存最佳基因型。
最佳基因型表示
最佳基因型是每个神经网络层的最佳单元。单元通过DARTS算法生成。 这是最佳基因型的一个例子:
Genotype(
normal=[
[('max_pooling_3x3',0),('max_pooling_3x3',1)],
[('max_pooling_3x3',0),('max_pooling_3x3',1)],
[('max_pooling_3x3',0),('dilated_convolution_3x3',3)],
[('max_pooling_3x3',0),('max_pooling_3x3',1)]
],
normal_concat=range(2,6),
reduce=[
[('dilated_convolution_5x5',1),('separable_convolution_3x3',0)],
[('max_pooling_3x3',2),('dilated_convolution_5x5',1)],
[('dilated_convolution_5x5',3),('dilated_convolution_5x5',2)],
[('dilated_convolution_5x5',3),('dilated_convolution_5x5',4)]
],
reduce_concat=range(2,6)
)
在这个例子中,你可以看到4个DARTS节点,索引为:2,3,4,5。
reduce 参数是位于总神经网络层的 1/3 和 2/3 的单元。它们代表减少单元,在这些单元中,所有与输入节点相邻的操作的步幅为二。
normal 参数是位于其他神经网络层的细胞。 它们代表正常细胞。
在CNN中,所有的reduce和普通中间节点被连接在一起,每个节点有2条边。
每个 normal 数组中的元素是具有 2 条边的节点。第一个元素是边上的操作,第二个元素是节点索引连接。请注意,索引 0 是 C_{k-2} 节点,索引 1 是 C_{k-1} 节点。
例如 [('max_pooling_3x3',0),('max_pooling_3x3',1)] 意味着 C_{k-2} 节点连接到第一个节点,使用 max_pooling_3x3 操作(滤波器大小为3的最大池化),而 C_{k-1} 节点连接到第一个节点,使用 max_pooling_3x3 操作。
reduce 数组按照 normal 数组的相同方式。
normal_concat 和 reduce_concat 表示中间节点之间的连接。
目前,它仅支持在单个 GPU 上运行和二阶近似,这比一阶产生了更好的结果。
以下项目可以在 DARTS 中实现:
支持多 GPU 训练。添加选择用于训练的 GPU 的功能。
在Katib UI中支持DARTS。
考虑更好的最优基因型的表示。
为CNN添加更多数据集。目前,它仅支持CIFAR-10。
除了CNN外,还支持RNN。
支持微模式,这意味着搜索特定的神经网络单元。