AdvancedNas.md 4.33 KB
Newer Older
Chi Song's avatar
Chi Song committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 高级神经网络架构搜索教程

目前,许多 NAS(Neural Architecture Search,神经网络架构搜索)算法都在 Trial 上使用了 **权重共享(weight sharing)** 的方法来加速训练过程。 例如,[ENAS](https://arxiv.org/abs/1802.03268) 与以前的 [NASNet](https://arxiv.org/abs/1707.07012) 算法相比,通过'*子模型间的参数共享(parameter sharing between child models)*'提高了 1000 倍的效率。 而例如 [DARTS](https://arxiv.org/abs/1806.09055), [Network Morphism](https://arxiv.org/abs/1806.10282), 和 [Evolution](https://arxiv.org/abs/1703.01041) 等算法也利用或者隐式的利用了权重共享。

本教程介绍了如何使用权重共享。

## 权重共享

推荐通过 NFS (Network File System)进行权重共享,它是轻量、相对高效的多机共享文件方案。 欢迎社区来共享更多高效的技术。

### 通过 NFS 文件使用权重共享

使用 NFS 配置(见下文),Trial 代码可以通过读写文件来共享模型权重。 建议使用 Tuner 的存储路径:

```yaml
tuner:
  codeDir: path/to/customer_tuner
Chi Song's avatar
Chi Song committed
18
  classFileName: customer_tuner.py
Chi Song's avatar
Chi Song committed
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
  className: CustomerTuner
  classArgs:
    ...
    save_dir_root: /nfs/storage/path/
```

并让 Tuner 来决定在什么路径读写权重文件,通过 `nni.get_next_parameters()` 来获取路径:

<img src="https://user-images.githubusercontent.com/23273522/51817667-93ebf080-2306-11e9-8395-b18b322062bc.png" alt="drawing" width="700" />

例如,在 Tensorflow 中:

```python
# 保存 models
saver = tf.train.Saver()
saver.save(sess, os.path.join(params['save_path'], 'model.ckpt'))
# 读取 models
tf.init_from_checkpoint(params['restore_path'])
```

超参中的 `'save_path'``'restore_path'` 可以通过 Tuner 来管理。

### NFS 配置

NFS 使用了客户端/服务器架构。通过一个 NFS 服务器来提供物理存储,远程计算机上的 Trial 使用 NFS 客户端来读写文件,操作上和本地文件相同。

#### NFS 服务器

如果有足够的存储空间,并能够让 NNI 的 Trial 通过**远程机器**来连接,NFS 服务可以安装在任何计算机上。 通常,可以选择一台远程服务器作为 NFS 服务。

在 Ubuntu 上,可通过 `apt-get` 安装 NFS 服务:

```bash
sudo apt-get install nfs-kernel-server
```

假设 `/tmp/nni/shared` 是物理存储位置,然后运行:

```bash
mkdir -p /tmp/nni/shared
sudo echo "/tmp/nni/shared *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
sudo service nfs-kernel-server restart
```

可以通过命令 `sudo showmount -e localhost` 来检查上述目录是否通过 NFS 成功导出了

#### NFS 客户端

为了通过 NFS 访问远程共享文件,需要安装 NFS 客户端。 例如,在 Ubuntu 上运行:

```bash
sudo apt-get install nfs-common
```

然后创建并装载上共享目录:

```bash
mkdir -p /mnt/nfs/nni/
sudo mount -t nfs 10.10.10.10:/tmp/nni/shared /mnt/nfs/nni
```

实际使用时,IP `10.10.10.10` 需要替换为 NFS 服务器的真实地址。

Chi Song's avatar
Chi Song committed
82
## Trial 依赖控制的异步 Dispatcher 模式
Chi Song's avatar
Chi Song committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

多机间启用权重的 Trial,一般是通过**先写后读**的方式来保持一致性。 子节点在父节点的 Trial 完成训练前,不应该读取父节点模型。 要解决这个问题,要通过 `multiThread: true` 来启用**异步调度模式**。在 `config.yml` 中,每次收到 `NEW_TRIAL` 请求,分派一个新的 Trial 时,Tuner 线程可以决定是否阻塞当前线程。 例如:

```python
    def generate_parameters(self, parameter_id):
        self.thread_lock.acquire()
        indiv = # 新 Trial 的配置
        self.events[parameter_id] = threading.Event()
        self.thread_lock.release()
        if indiv.parent_id is not None:
            self.events[indiv.parent_id].wait()

    def receive_trial_result(self, parameter_id, parameters, reward):
        self.thread_lock.acquire()
        # 处理 Trial 结果的配置
        self.thread_lock.release()
        self.events[parameter_id].set()
```

## 样例

Chi Song's avatar
Chi Song committed
104
详细内容参考:[简单的参数共享样例](https://github.com/Microsoft/nni/tree/master/test/async_sharing_test)。 基于已有的 [ga_squad](https://github.com/Microsoft/nni/tree/master/examples/trials/ga_squad) 样例,还提供了新的 [样例](https://github.com/Microsoft/nni/tree/master/examples/trials/weight_sharing/ga_squad)