Skip to content

Commit 8dde624

Browse files
committed
parent 7d5ba61
author Reiase <[email protected]> 1641453952 +0800 committer Reiase <[email protected]> 1642438724 +0800 init commit
1 parent 7d5ba61 commit 8dde624

File tree

11 files changed

+879
-2
lines changed

11 files changed

+879
-2
lines changed

README.md

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,89 @@
1-
# hyperparameter
2-
a library for hyper parameter
1+
**H**_yper_**P**_arameter_
2+
===========================
3+
4+
A hyper-parameter library for researchers, data scientists and machine learning engineers.
5+
6+
- [**H**_yper_**P**_arameter_](#hyperparameter)
7+
- [Quick Start](#quick-start)
8+
- [Object-Style API:](#object-style-api)
9+
- [Scoped Parameter](#scoped-parameter)
10+
- [Examples](#examples)
11+
- [parameter tunning for researchers](#parameter-tunning-for-researchers)
12+
- [experiment tracing for data scientists](#experiment-tracing-for-data-scientists)
13+
- [design-pattern for system engineers](#design-pattern-for-system-engineers)
14+
15+
Quick Start
16+
============
17+
18+
## Object-Style API:
19+
20+
```python
21+
from hyperparameter import HyperParameter
22+
23+
params = HyperParameter(a=1, b={'c': 2})
24+
params.a == 1 # True
25+
params.b.c == 2 # True (nested parameter)
26+
```
27+
28+
or becomes powerful with `params()`:
29+
30+
```python
31+
params().a.b.c.getOrElse(3) # 3 (default value)
32+
params().a.b.c(3) # 3 (shortcut for default value)
33+
34+
params().a.b.c = 4 # set value to param `a.b.c`
35+
params().a.b.c(3) # 4 (default value is ignored)
36+
```
37+
38+
## Scoped Parameter
39+
40+
```python
41+
from hyperparameter import param_scope
42+
43+
# scoped parameter
44+
with param_scope(a=1) as hp:
45+
hp.a == 1 # True
46+
```
47+
or becomes powerful with `nested scope`:
48+
``` python
49+
with param_scope(a=1) as hp:
50+
with param_scope(a=2) as hp:
51+
hp.a == 2 # True, a=2 for inner scope
52+
hp.a == 1 # True, a=1 for outer scope
53+
```
54+
55+
even more powerful when using `param_scope` in function:
56+
57+
```python
58+
#change function behavior with scoped parameter:
59+
def foo(arg):
60+
# receive parameter using param_scope
61+
with param_scope() as hp:
62+
if (hp().param1.getOrElse(1) == 1):
63+
return 1
64+
else:
65+
return 2
66+
...
67+
68+
# call function with default parameter
69+
foo() # 1
70+
71+
# passing parameter using param_scope
72+
with param_scope(param1=2):
73+
foo() # 2
74+
```
75+
76+
Examples
77+
========
78+
79+
## [parameter tunning for researchers](examples/sparse_lr/README.md)
80+
81+
This example shows how to use hyperparameter in your research projects, and make your experiments reproducible.
82+
83+
## experiment tracing for data scientists
84+
85+
Todo.
86+
87+
## design-pattern for system engineers
88+
89+
Todo.

README_CN.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Overview
2+
========
3+
4+
hyperparameter 是一个参数管理工具库,用于解决如下问题:
5+
1. 应用级别/库级别参数配置与管理;
6+
2. 机器学习模型超参配置和调优;
7+
3. AutoML参数寻优;
8+
9+
Quick Start
10+
===========
11+
12+
``` python
13+
def foo():
14+
with param_scope() as hp:
15+
return hp.a
16+
17+
with param_scope(a=1, b=2) as hp:
18+
hp() # 1
19+
```

docs/_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
theme: jekyll-theme-slate

docs/index.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
**H**_yper_**P**_arameter_
2+
===========================
3+
A hyper-parameter library for researchers, data scientists and machine learning engineers.
4+
5+
## Object-Style API:
6+
7+
```python
8+
from hyperparameter import HyperParameter
9+
10+
params = HyperParameter(a=1, b={'c': 2})
11+
params.a == 1 # True
12+
params.b.c == 2 # True (nested parameter)
13+
```
14+
15+
or becomes powerful with `params()`:
16+
17+
```python
18+
params().a.b.c.getOrElse(3) # 3 (default value)
19+
params().a.b.c(3) # 3 (shortcut for default value)
20+
21+
params().a.b.c = 4 # set value to param `a.b.c`
22+
params().a.b.c(3) # 4 (default value is ignored)
23+
```
24+
25+
## Scoped Parameter
26+
27+
```python
28+
from hyperparameter import param_scope
29+
30+
# scoped parameter
31+
with param_scope(a=1) as hp:
32+
hp.a == 1 # True
33+
```
34+
or becomes powerful with `nested scope`:
35+
``` python
36+
with param_scope(a=1) as hp:
37+
with param_scope(a=2) as hp:
38+
hp.a == 2 # True
39+
hp.a == 1 # True
40+
```
41+
42+
even more powerful when using `param_scope` in function:
43+
44+
```python
45+
#change function behavior with scoped parameter:
46+
def foo(arg):
47+
# receive parameter using param_scope
48+
with param_scope() as hp:
49+
if (hp().param1.getOrElse(1) == 1):
50+
return 1
51+
else:
52+
return 2
53+
...
54+
55+
# call function with default parameter
56+
foo() # 1
57+
58+
# passing parameter using param_scope
59+
with param_scope(param1=2):
60+
foo() # 2
61+
```

examples/sparse_lr/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Sparse LR Examples
2+
==================
3+
4+
This example shows l1 penalty and sparsity in logistic regression, based on `scikit-learn` example from https://scikit-learn.org/stable/auto_examples/linear_model/plot_logistic_l1_l2_sparsity.html#sphx-glr-auto-examples-linear-model-plot-logistic-l1-l2-sparsity-py.
5+
6+
`sparse_lr_train` (from `model.py`) classifies 8x8 images of digits into two classes: 0-4 against 5-9,
7+
and visualize the coefficients of the model for different penalty methods(l1 or l2) and C.
8+
9+
We use the `let` decorator to declare hyper-parameters for our algorithm:
10+
``` python
11+
@let(learning_rate=0.01, penalty='l1', C=0.01, tol=0.01)
12+
def sparse_lr_train(X, y):
13+
C = local_param('C')
14+
penalty = local_param('penalty')
15+
tol = local_param('tol')
16+
print({'C': C, 'penalty': penalty, 'tol': tol})
17+
...
18+
```
19+
20+
Four hyper-parameter are defined for function `sparse_lr_train`: `learning_rate`, `penalty`, `C` and `tol`.
21+
There are two ways to control the hyper-parameters:
22+
1. parameter scope (see detail in `example_1.py`):
23+
24+
``` python
25+
with param_scope('model.sparse_lr_train.C=0.1'):
26+
sparse_lr_train(X, y)
27+
```
28+
29+
2. command line arguments (see detail in `example_2.py`):
30+
31+
``` python
32+
def run(args):
33+
# run the lr model with parameter from cmdline
34+
with param_scope(*args.define): # set parameters according to cmd line
35+
sparse_lr_train(X, y)
36+
...
37+
38+
39+
if __name__ == '__main__':
40+
# create cmd line arguments parser
41+
import argparse
42+
parser = argparse.ArgumentParser('example')
43+
parser.add_argument('-D', '--define', nargs='*', default=[])
44+
args = parser.parse_args()
45+
46+
run(args)
47+
48+
```

examples/sparse_lr/example_1.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from hyperparameter.hp import param_scope, Tracker
2+
from model import sparse_lr_train
3+
import numpy as np
4+
5+
from sklearn import datasets
6+
from sklearn.preprocessing import StandardScaler
7+
import matplotlib.pyplot as plt
8+
9+
X, y = datasets.load_digits(return_X_y=True)
10+
11+
X = StandardScaler().fit_transform(X)
12+
13+
# classify small against large digits
14+
y = (y > 4).astype(int)
15+
16+
print('parameter list: \n {}'.format('\n '.join(Tracker.all())))
17+
18+
# run the lr model with default parameters
19+
coef = sparse_lr_train(X, y)
20+
21+
plt.imshow(
22+
np.abs(coef.reshape(8, 8)),
23+
interpolation="nearest",
24+
cmap="binary",
25+
vmax=1,
26+
vmin=0,
27+
)
28+
plt.show()
29+
30+
# run the lr model with another parameter
31+
with param_scope('model.sparse_lr_train.C=0.1'):
32+
coef = sparse_lr_train(X, y)
33+
plt.imshow(
34+
np.abs(coef.reshape(8, 8)),
35+
interpolation="nearest",
36+
cmap="binary",
37+
vmax=1,
38+
vmin=0,
39+
)
40+
plt.show()

examples/sparse_lr/example_2.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from hyperparameter.hp import param_scope, Tracker
2+
from model import sparse_lr_train
3+
import numpy as np
4+
5+
from sklearn import datasets
6+
from sklearn.preprocessing import StandardScaler
7+
import matplotlib.pyplot as plt
8+
9+
X, y = datasets.load_digits(return_X_y=True)
10+
11+
X = StandardScaler().fit_transform(X)
12+
13+
# classify small against large digits
14+
y = (y > 4).astype(int)
15+
16+
17+
def run(args):
18+
# run the lr model with parameter from cmdline
19+
with param_scope(*args.define): # set parameters according to cmd line
20+
coef = sparse_lr_train(X, y)
21+
plt.imshow(
22+
np.abs(coef.reshape(8, 8)),
23+
interpolation="nearest",
24+
cmap="binary",
25+
vmax=1,
26+
vmin=0,
27+
)
28+
plt.show()
29+
30+
31+
if __name__ == '__main__':
32+
# create cmd line arguments parser
33+
import argparse
34+
parser = argparse.ArgumentParser('example')
35+
parser.add_argument(
36+
'-D',
37+
'--define',
38+
nargs='*',
39+
default=[],
40+
help=
41+
'define a parameter `param_name=param_value`, supported parameter list: \n\n {}'
42+
.format('\n '.join(Tracker.all())))
43+
args = parser.parse_args()
44+
run(args)
45+
46+
print(Tracker.report())

examples/sparse_lr/model.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import numpy as np
2+
from sklearn.linear_model import LogisticRegression
3+
4+
from hyperparameter import let, local_param, param_scope
5+
6+
7+
@let(learning_rate=0.01, penalty='l1', C=0.01, tol=0.01)
8+
def sparse_lr_train(X, y):
9+
C = local_param('C')
10+
penalty = local_param('penalty')
11+
tol = local_param('tol')
12+
LR = LogisticRegression(C=C, penalty=penalty, tol=tol, solver='saga')
13+
14+
LR.fit(X, y)
15+
coef = LR.coef_.ravel()
16+
sparsity_LR = np.mean(coef == 0) * 100
17+
print({'C': C, 'penalty': penalty, 'tol': tol, 'sparsity': '%.2f%%'%(sparsity_LR)})
18+
return coef

hyperparameter/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .hp import *

0 commit comments

Comments
 (0)