Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
c5acd8c2
Unverified
Commit
c5acd8c2
authored
May 27, 2019
by
SparkSnail
Committed by
GitHub
May 27, 2019
Browse files
Merge pull request #173 from microsoft/master
merge master
parents
40bae6e2
d135d184
Changes
93
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
247 additions
and
24 deletions
+247
-24
src/sdk/pynni/nni/evolution_tuner/README_zh_CN.md
src/sdk/pynni/nni/evolution_tuner/README_zh_CN.md
+5
-0
src/sdk/pynni/nni/gridsearch_tuner/README_zh_CN.md
src/sdk/pynni/nni/gridsearch_tuner/README_zh_CN.md
+5
-0
src/sdk/pynni/nni/hyperband_advisor/README_zh_CN.md
src/sdk/pynni/nni/hyperband_advisor/README_zh_CN.md
+56
-0
src/sdk/pynni/nni/hyperopt_tuner/README_zh_CN.md
src/sdk/pynni/nni/hyperopt_tuner/README_zh_CN.md
+13
-0
src/sdk/pynni/nni/medianstop_assessor/README_zh_CN.md
src/sdk/pynni/nni/medianstop_assessor/README_zh_CN.md
+5
-0
src/sdk/pynni/nni/metis_tuner/README_zh_CN.md
src/sdk/pynni/nni/metis_tuner/README_zh_CN.md
+19
-0
src/webui/src/components/public-child/OpenRow.tsx
src/webui/src/components/public-child/OpenRow.tsx
+50
-15
src/webui/src/static/style/copyParameter.scss
src/webui/src/static/style/copyParameter.scss
+22
-0
src/webui/src/static/style/overview.scss
src/webui/src/static/style/overview.scss
+0
-1
test/pipelines-it-remote-windows.yml
test/pipelines-it-remote-windows.yml
+49
-0
test/remote_docker.py
test/remote_docker.py
+20
-4
tools/README_zh_CN.md
tools/README_zh_CN.md
+1
-1
uninstall.ps1
uninstall.ps1
+2
-3
No files found.
src/sdk/pynni/nni/evolution_tuner/README_zh_CN.md
0 → 100644
View file @
c5acd8c2
# Naive Evolution Tuner
## Naive Evolution(进化算法)
进化算法来自于
[
Large-Scale Evolution of Image Classifiers
](
https://arxiv.org/pdf/1703.01041.pdf
)
。 它会基于搜索空间随机生成一个种群。 在每一代中,会选择较好的结果,并对其下一代进行一些变异(例如,改动一个超参,增加或减少一层)。 进化算法需要很多次 Trial 才能有效,但它也非常简单,也很容易扩展新功能。
\ No newline at end of file
src/sdk/pynni/nni/gridsearch_tuner/README_zh_CN.md
0 → 100644
View file @
c5acd8c2
# Grid Search
## Grid Search(遍历搜索)
Grid Search 会穷举定义在搜索空间文件中的所有超参组合。 注意,搜索空间仅支持
`choice`
,
`quniform`
,
`qloguniform`
。
`quniform`
和
`qloguniform`
中的
**
数字
`q`
有不同的含义(与
[
搜索空间
](
../../../../../docs/zh_CN/SearchSpaceSpec.md
)
说明不同)。 这里的意义是在
`low`
和
`high`
之间均匀取值的数量。
</p>
\ No newline at end of file
src/sdk/pynni/nni/hyperband_advisor/README_zh_CN.md
0 → 100644
View file @
c5acd8c2
# NNI 中使用 Hyperband
## 1. 介绍
[
Hyperband
](
https://arxiv.org/pdf/1603.06560.pdf
)
是一种流行的自动机器学习算法。 Hyperband 的基本思想是对配置分组,每组有
`n`
个随机生成的超参配置,每个配置使用
`r`
次资源(如,epoch 数量,批处理数量等)。 当
`n`
个配置完成后,会选择最好的
`n/eta`
个配置,并增加
`r*eta`
次使用的资源。 最后,会选择出的最好配置。
## 2. 实现并行
首先,此样例是基于 MsgDispatcherBase 来实现的自动机器学习算法,而不是基于 Tuner 和Assessor。 这种实现方法下,Hyperband 集成了 Tuner 和 Assessor 两者的功能,因而将它叫做 Advisor。
其次,本实现完全利用了 Hyperband 内部的并行性。 具体来说,下一个分组不会严格的在当前分组结束后再运行,只要有资源,就可以开始运行新的分组。
## 3. 用法
要使用 Hyperband,需要在 Experiment 的 YAML 配置文件进行如下改动。
advisor:
#可选项: Hyperband
builtinAdvisorName: Hyperband
classArgs:
#R: 最大的步骤
R: 100
#eta: 丢弃的 Trial 的比例
eta: 3
#可选项: maximize, minimize
optimize_mode: maximize
注意,一旦使用了 Advisor,就不能在配置文件中添加 Tuner 和 Assessor。 使用 Hyperband 时,Trial 代码收到的超参(如键值对)中,除了用户定义的超参,会多一个
`STEPS`
。
**
使用
`STEPS`
,Trial 能够控制其运行的时间。
</p>
对于 Trial 代码中
`report_intermediate_result(metric)`
和
`report_final_result(metric)`
的
**`指标` 应该是数值,或者用一个 dict,并保证其中有键值为 default 的项目,其值也为数值型**
。 这是需要进行最大化或者最小化优化的数值,如精度或者损失度。
`R`
和
`eta`
是 Hyperband 中可以改动的参数。
`R`
表示可以分配给配置的最大步数(STEPS)。 这里,STEPS 可以代表 epoch 或 批处理数量。
`STEPS`
应该被 Trial 代码用来控制运行的次数。 参考样例
`examples/trials/mnist-hyperband/`
,了解详细信息。
`eta`
表示
`n`
个配置中的
`n/eta`
个配置会留存下来,并用更多的 STEPS 来运行。
下面是
`R=81`
且
`eta=3`
时的样例:
| | s=4 | s=3 | s=2 | s=1 | s=0 |
| - | ---- | ---- | ---- | ---- | ---- |
| i | n r | n r | n r | n r | n r |
| 0 | 81 1 | 27 3 | 9 9 | 6 27 | 5 81 |
| 1 | 27 3 | 9 9 | 3 27 | 2 81 | |
| 2 | 9 9 | 3 27 | 1 81 | | |
| 3 | 3 27 | 1 81 | | | |
| 4 | 1 81 | | | | |
`s`
表示分组,
`n`
表示生成的配置数量,相应的
`r`
表示配置会运行多少 STEPS。
`i`
表示轮数,如分组 4 有 5 轮,分组 3 有 4 轮。
关于如何实现 Trial 代码,参考
`examples/trials/mnist-hyperband/`
中的说明。
## 4. 待改进
当前实现的 Hyperband 算法可以通过改进支持的提前终止算法来提高,原因是最好的
`n/eta`
个配置并不一定都表现很好。 不好的配置可以更早的终止。
在当前实现中,遵循了
[
此论文
](
https://arxiv.org/pdf/1603.06560.pdf
)
的设计,配置都是随机生成的。 要进一步提升,配置生成过程可以利用更高级的算法。
\ No newline at end of file
src/sdk/pynni/nni/hyperopt_tuner/README_zh_CN.md
0 → 100644
View file @
c5acd8c2
# TPE, Random Search, Anneal Tuners
## TPE
Tree-structured Parzen Estimator (TPE) 是一种 sequential model-based optimization(SMBO,即基于序列模型优化)的方法。 SMBO 方法根据历史指标数据来按顺序构造模型,来估算超参的性能,随后基于此模型来选择新的超参。 TPE 方法对 P(x|y) 和 P(y) 建模,其中 x 表示超参,y 表示相关的评估指标。 P(x|y) 通过变换超参的生成过程来建模,用非参数密度(non-parametric densities)代替配置的先验分布。 细节可参考
[
Algorithms for Hyper-Parameter Optimization
](
https://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf
)
。
## Random Search(随机搜索)
[
Random Search for Hyper-Parameter Optimization
](
http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf
)
中介绍了随机搜索惊人的简单和效果。 建议当不清楚超参的先验分布时,采用随机搜索作为基准。
## Anneal(退火算法)
这种简单的退火算法从先前的采样开始,会越来越靠近发现的最佳点取样。 此算法是随机搜索的简单变体,利用了响应面的平滑性。 退火率不是自适应的。
\ No newline at end of file
src/sdk/pynni/nni/medianstop_assessor/README_zh_CN.md
0 → 100644
View file @
c5acd8c2
# Medianstop Assessor
## Median Stop
Medianstop 是一种简单的提前终止 Trial 的策略,可参考
[
论文
](
https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46180.pdf
)
。 如果 Trial X 的在步骤 S 的最好目标值比所有已完成 Trial 的步骤 S 的中位数值明显要低,这个 Trial 就会被提前停止。
\ No newline at end of file
src/sdk/pynni/nni/metis_tuner/README_zh_CN.md
0 → 100644
View file @
c5acd8c2
# Metis Tuner
## Metis Tuner
大多数调参工具仅仅预测最优配置,而
[
Metis
](
https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/
)
的优势在于有两个输出:(a) 最优配置的当前预测结果, 以及 (b) 下一次 Trial 的建议。 不再需要随机猜测!
大多数工具假设训练集没有噪声数据,但 Metis 会知道是否需要对某个超参重新采样。
大多数工具都有着重于在已有结果上继续发展的问题,而 Metis 的搜索策略可以在探索,发展和重新采样(可选)中进行平衡。
Metis 属于基于序列的贝叶斯优化 (SMBO) 的类别,它也基于贝叶斯优化框架。 为了对超参-性能空间建模,Metis 同时使用了高斯过程(Gaussian Process)和高斯混合模型(GMM)。 由于每次 Trial 都可能有很高的时间成本,Metis 大量使用了已有模型来进行推理计算。 在每次迭代中,Metis 执行两个任务:
在高斯过程空间中找到全局最优点。 这一点表示了最佳配置。
它会标识出下一个超参的候选项。 这是通过对隐含信息的探索、挖掘和重采样来实现的。
注意,搜索空间仅支持
`choice`
,
`quniform`
,
`uniform`
和
`randint`
。
更多详情,参考论文:https://www.microsoft.com/en-us/research/publication/metis-robustly-tuning-tail-latencies-cloud-systems/
\ No newline at end of file
src/webui/src/components/public-child/OpenRow.tsx
View file @
c5acd8c2
...
...
@@ -3,9 +3,10 @@ import * as copy from 'copy-to-clipboard';
import
PaiTrialLog
from
'
../public-child/PaiTrialLog
'
;
import
TrialLog
from
'
../public-child/TrialLog
'
;
import
{
TableObj
}
from
'
../../static/interface
'
;
import
{
Row
,
Tabs
,
Button
,
message
}
from
'
antd
'
;
import
{
Row
,
Tabs
,
Button
,
message
,
Modal
}
from
'
antd
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
'
../../static/style/overview.scss
'
;
import
'
../../static/style/copyParameter.scss
'
;
import
JSONTree
from
'
react-json-tree
'
;
const
TabPane
=
Tabs
.
TabPane
;
...
...
@@ -17,43 +18,62 @@ interface OpenRowProps {
}
interface
OpenRowState
{
idList
:
Array
<
string
>
;
isShowFormatModal
:
boolean
;
formatStr
:
string
;
}
class
OpenRow
extends
React
.
Component
<
OpenRowProps
,
OpenRowState
>
{
public
_isMounted
:
boolean
;
constructor
(
props
:
OpenRowProps
)
{
super
(
props
);
this
.
state
=
{
idList
:
[
''
]
isShowFormatModal
:
false
,
formatStr
:
''
};
}
showFormatModal
=
(
record
:
TableObj
)
=>
{
// get copy parameters
const
params
=
JSON
.
stringify
(
record
.
description
.
parameters
,
null
,
4
);
// open modal with format string
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isShowFormatModal
:
true
,
formatStr
:
params
}));
}
}
hideFormatModal
=
()
=>
{
// close modal, destroy state format string data
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isShowFormatModal
:
false
,
formatStr
:
''
}));
}
}
copyParams
=
(
record
:
TableObj
)
=>
{
copyParams
=
()
=>
{
// json format
const
params
=
JSON
.
stringify
(
record
.
description
.
parameters
,
null
,
4
)
;
if
(
copy
(
params
))
{
const
{
formatStr
}
=
this
.
state
;
if
(
copy
(
formatStr
))
{
message
.
destroy
();
message
.
success
(
'
Success copy parameters to clipboard in form of python dict !
'
,
3
);
const
{
idList
}
=
this
.
state
;
const
copyIdList
:
Array
<
string
>
=
idList
;
copyIdList
[
copyIdList
.
length
-
1
]
=
record
.
id
;
this
.
setState
(()
=>
({
idList
:
copyIdList
}));
}
else
{
message
.
destroy
();
message
.
error
(
'
Failed !
'
,
2
);
}
this
.
hideFormatModal
();
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
render
()
{
const
{
trainingPlatform
,
record
,
logCollection
,
multiphase
}
=
this
.
props
;
const
{
i
dList
}
=
this
.
state
;
const
{
i
sShowFormatModal
,
formatStr
}
=
this
.
state
;
let
isClick
=
false
;
let
isHasParameters
=
true
;
if
(
idList
.
indexOf
(
record
.
id
)
!==
-
1
)
{
isClick
=
true
;
}
if
(
record
.
description
.
parameters
.
error
)
{
isHasParameters
=
false
;
}
...
...
@@ -101,7 +121,7 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
</
Row
>
<
Row
className
=
"copy"
>
<
Button
onClick
=
{
this
.
copyParams
.
bind
(
this
,
record
)
}
onClick
=
{
this
.
showFormatModal
.
bind
(
this
,
record
)
}
>
Copy as python
</
Button
>
...
...
@@ -128,6 +148,21 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
}
</
TabPane
>
</
Tabs
>
<
Modal
title
=
"Format"
okText
=
"Copy"
centered
=
{
true
}
visible
=
{
isShowFormatModal
}
onCancel
=
{
this
.
hideFormatModal
}
maskClosable
=
{
false
}
// click mongolian layer don't close modal
onOk
=
{
this
.
copyParams
}
destroyOnClose
=
{
true
}
width
=
"60%"
className
=
"format"
>
{
/* write string in pre to show format string */
}
<
pre
className
=
"formatStr"
>
{
formatStr
}
</
pre
>
</
Modal
>
</
Row
>
);
}
...
...
src/webui/src/static/style/copyParameter.scss
0 → 100644
View file @
c5acd8c2
$color
:
#f2f2f2
;
.formatStr
{
border
:
1px
solid
#8f8f8f
;
color
:
#333
;
padding
:
5px
10px
;
background-color
:
#fff
;
}
.format
{
.ant-modal-header
{
background-color
:
$color
;
border-bottom
:
none
;
}
.ant-modal-footer
{
background-color
:
$color
;
border-top
:
none
;
}
.ant-modal-body
{
background-color
:
$color
;
padding
:
10px
24px
!
important
;
}
}
src/webui/src/static/style/overview.scss
View file @
c5acd8c2
...
...
@@ -52,4 +52,3 @@
.link
{
margin-bottom
:
10px
;
}
test/pipelines-it-remote-windows.yml
0 → 100644
View file @
c5acd8c2
jobs
:
-
job
:
'
integration_test_remote_windows'
steps
:
-
script
:
python -m pip install --upgrade pip setuptools
displayName
:
'
Install
python
tools'
-
task
:
CopyFilesOverSSH@0
inputs
:
sshEndpoint
:
$(end_point)
targetFolder
:
/tmp/nnitest/$(Build.BuildId)/nni-remote
overwrite
:
true
displayName
:
'
Copy
all
files
to
remote
machine'
-
script
:
|
powershell.exe -file install.ps1
displayName
:
'
Install
nni
toolkit
via
source
code'
-
script
:
|
python -m pip install scikit-learn==0.20.1 --user
displayName
:
'
Install
dependencies
for
integration
tests'
-
task
:
SSH@0
inputs
:
sshEndpoint
:
$(end_point)
runOptions
:
inline
inline
:
cd /tmp/nnitest/$(Build.BuildId)/nni-remote/deployment/pypi;make build
continueOnError
:
true
displayName
:
'
build
nni
bdsit_wheel'
-
task
:
SSH@0
inputs
:
sshEndpoint
:
$(end_point)
runOptions
:
commands
commands
:
python3 /tmp/nnitest/$(Build.BuildId)/nni-remote/test/remote_docker.py --mode start --name $(Build.BuildId) --image nni/nni --os windows
displayName
:
'
Start
docker'
-
powershell
:
|
Write-Host "Downloading Putty..."
(New-Object Net.WebClient).DownloadFile("https://the.earth.li/~sgtatham/putty/latest/w64/pscp.exe", "$(Agent.TempDirectory)\pscp.exe")
$(Agent.TempDirectory)\pscp.exe -hostkey $(hostkey) -pw $(pscp_pwd) $(remote_user)@$(remote_host):/tmp/nnitest/$(Build.BuildId)/port test\port
Get-Content test\port
displayName
:
'
Get
docker
port'
-
powershell
:
|
cd test
python generate_ts_config.py --ts remote --remote_user $(docker_user) --remote_host $(remote_host) --remote_port $(Get-Content port) --remote_pwd $(docker_pwd) --nni_manager_ip $(nni_manager_ip)
Get-Content training_service.yml
python config_test.py --ts remote --exclude cifar10,smac,bohb
displayName
:
'
integration
test'
-
task
:
SSH@0
inputs
:
sshEndpoint
:
$(end_point)
runOptions
:
commands
commands
:
python3 /tmp/nnitest/$(Build.BuildId)/nni-remote/test/remote_docker.py --mode stop --name $(Build.BuildId) --os windows
displayName
:
'
Stop
docker'
test/remote_docker.py
View file @
c5acd8c2
...
...
@@ -30,18 +30,33 @@ def find_wheel_package(dir):
return
file_name
return
None
def
start_container
(
image
,
name
):
def
start_container
(
image
,
name
,
nnimanager_os
):
'''Start docker container, generate a port in /tmp/nnitest/{name}/port file'''
port
=
find_port
()
source_dir
=
'/tmp/nnitest/'
+
name
run_cmds
=
[
'docker'
,
'run'
,
'-d'
,
'-p'
,
str
(
port
)
+
':22'
,
'--name'
,
name
,
'--mount'
,
'type=bind,source='
+
source_dir
+
',target=/tmp/nni'
,
image
]
output
=
check_output
(
run_cmds
)
commit_id
=
output
.
decode
(
'utf-8'
)
wheel_name
=
find_wheel_package
(
os
.
path
.
join
(
source_dir
,
'dist'
))
if
nnimanager_os
==
'windows'
:
wheel_name
=
find_wheel_package
(
os
.
path
.
join
(
source_dir
,
'nni-remote/deployment/pypi/dist'
))
else
:
wheel_name
=
find_wheel_package
(
os
.
path
.
join
(
source_dir
,
'dist'
))
if
not
wheel_name
:
print
(
'Error: could not find wheel package in {0}'
.
format
(
source_dir
))
exit
(
1
)
sdk_cmds
=
[
'docker'
,
'exec'
,
name
,
'python3'
,
'-m'
,
'pip'
,
'install'
,
'/tmp/nni/dist/{0}'
.
format
(
wheel_name
)]
def
get_dist
(
wheel_name
):
'''get the wheel package path'''
if
nnimanager_os
==
'windows'
:
return
'/tmp/nni/nni-remote/deployment/pypi/dist/{0}'
.
format
(
wheel_name
)
else
:
return
'/tmp/nni/dist/{0}'
.
format
(
wheel_name
)
pip_cmds
=
[
'docker'
,
'exec'
,
name
,
'python3'
,
'-m'
,
'pip'
,
'install'
,
'--upgrade'
,
'pip'
]
check_call
(
pip_cmds
)
sdk_cmds
=
[
'docker'
,
'exec'
,
name
,
'python3'
,
'-m'
,
'pip'
,
'install'
,
get_dist
(
wheel_name
)]
check_call
(
sdk_cmds
)
with
open
(
source_dir
+
'/port'
,
'w'
)
as
file
:
file
.
write
(
str
(
port
))
...
...
@@ -58,8 +73,9 @@ if __name__ == '__main__':
parser
.
add_argument
(
'--mode'
,
required
=
True
,
choices
=
[
'start'
,
'stop'
],
dest
=
'mode'
,
help
=
'start or stop a container'
)
parser
.
add_argument
(
'--name'
,
required
=
True
,
dest
=
'name'
,
help
=
'the name of container to be used'
)
parser
.
add_argument
(
'--image'
,
dest
=
'image'
,
help
=
'the image to be used'
)
parser
.
add_argument
(
'--os'
,
dest
=
'os'
,
default
=
'unix'
,
choices
=
[
'unix'
,
'windows'
],
help
=
'nniManager os version'
)
args
=
parser
.
parse_args
()
if
args
.
mode
==
'start'
:
start_container
(
args
.
image
,
args
.
name
)
start_container
(
args
.
image
,
args
.
name
,
args
.
os
)
else
:
stop_container
(
args
.
name
)
tools/README_zh_CN.md
View file @
c5acd8c2
...
...
@@ -54,4 +54,4 @@ NNI CTL 模块用来控制 Neural Network Intelligence,包括开始新 Experim
## 开始使用 NNI CTL
参考
[
NNI CTL 文档
](
../docs/zh_CN/NNICTLDOC.md
)
。
\ No newline at end of file
参考
[
NNI CTL 文档
](
../docs/zh_CN/Nnictl.md
)
。
\ No newline at end of file
uninstall.ps1
View file @
c5acd8c2
$NNI_DEPENDENCY_FOLDER
=
"C:\tmp\
$
env
:
USERNAME
"
$NNI_DEPENDENCY_FOLDER
=
[
System.IO.Path
]::
GetTempPath
()
+
$
env
:
USERNAME
$
env
:
PYTHONIOENCODING
=
"UTF-8"
if
(
$
env
:
VIRTUAL_ENV
){
...
...
@@ -27,4 +26,4 @@ Remove-Item "src/nni_manager/node_modules" -Recurse -Force
Remove-Item
"src/webui/build"
-Recurse
-Force
Remove-Item
"src/webui/node_modules"
-Recurse
-Force
Remove-Item
$NNI_YARN_FOLDER
-Recurse
-Force
Remove-Item
$NNI_NODE_FOLDER
-Recurse
-Force
\ No newline at end of file
Remove-Item
$NNI_NODE_FOLDER
-Recurse
-Force
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment