使用NNI的MNIST-Annotation例子分析

使用NNI的MNIST-Annotation例子分析

mnist-annotation结构分析

mnist-annotation例子中使用了nni自定义的annotation语法对需要搜索的参数/层直接在网络结构的代码里定义了所需的搜素空间,免去了config.yml的书写,为使用带来便捷。

以下为mnist-annotation例子中定义的搜索空间:

  • 卷积核大小 | 隐藏层输出长度 | 学习率
"""@nni.variable(nni.choice(2, 3, 5, 7),name=self.conv_size)""" 
self.conv_size = conv_size # 卷积核大小
"""@nni.variable(nni.choice(124, 512, 1024), name=self.hidden_size)"""
self.hidden_size = hidden_size # 全连接隐藏层输出的特征向量长度
self.pool_size = pool_size
"""@nni.variable(nni.loguniform(0.0001, 0.1), name=self.learning_rate)"""
self.learning_rate = learning_rate # 学习率
  • 非线性激活函数 | 池化方式
# First convolutional layer - maps one grayscale image to 32 feature maps.
    with tf.name_scope('conv1'):
        w_conv1 = weight_variable(
            [self.conv_size, self.conv_size, 1, self.channel_1_num])
        b_conv1 = bias_variable([self.channel_1_num])
        """@nni.function_choice(tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1), tf.nn.sigmoid(conv2d(x_image, w_conv1) + b_conv1), tf.nn.tanh(conv2d(x_image, w_conv1) + b_conv1), name=tf.nn.relu)"""
        h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1) # 非线性激活函数:relu/sigmoid/tanh

    # Pooling layer - downsamples by 2X.
    with tf.name_scope('pool1'):
        """@nni.function_choice(max_pool(h_conv1, self.pool_size), avg_pool(h_conv1, self.pool_size), name=max_pool)"""
        h_pool1 = max_pool(h_conv1, self.pool_size) # 最大池化/平均池化
  • batch size | dropout rate
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    """@nni.variable(nni.choice(16, 32), name=batch_size)"""
    batch_size = params['batch_size']
    for i in range(params['batch_num']):
        batch = mnist.train.next_batch(batch_size)
        """@nni.variable(nni.choice(0.5, 0.9), name=dropout_rate)"""
        dropout_rate = params['dropout_rate']

实验分析

mnist-annotation例子中提供了TPE、Random、Anneal、Evolution、SMAC共5种tuner。实验中尝试了了4种tuner默认配置下的tuning过程,SMAC tuner由于不支持function的选择(function_choice ),不便对比,因此没有做相应的实验。

以下为4种tuner训练过程的Web-UI截图。

TPE采用的是SMBO(即基于序列模型的全局优化)的思想,每次迭代,都会总结历次迭代的最优评估值(如准确率)及其对应参数所构成的域,求出某种模型分布,然后根据一定的准则,推出一个新的参数,并求评估值,如此往复。

Random则是对搜索空间的简单随机采样,没有用到历次迭代和评估值的信息。

Anneal即模拟退火搜索,模拟粒子内能降低的过程,以评估值作为温度,每次搜索基于当前温度产生一个概率指导下一次参数的变化,概率越大变化越大。在本例中,温度即为准确率,所不同的是准确率升高代表温度的降低。

Evolution则是遗传算法,算法先初始化一组亲代,然后每次搜索通过选择亲代中表现最好的一组参数,对该亲代修改少数的参数值(基因变异),产生一组子代,然后重复上述过程。

下面tuning的过程也一定程度上体现了如上算法的特点:

  • TPE:序贯的搜索过程,模型由简单到复杂变化,不追求全局最优但是渐进达到最优,从准确率上来看也符合这一规律。
TPE.png
  • Random:随机采样搜索,由于任务简单,因此也可以达到很好的效果
Random.png
  • Anneal:由于波动的存在并不满足当前最优,如在trial 2的结果之后还进行了多次尝试。
Anneal.png
  • Evolution:可见达到最优解的过程较为缓慢,因为每一代较上一代的参数变动很少。
Evolution.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容