hyperparameter 0.5.7

Hyperparameter, Make configurable AI applications.Build for Python hackers.
Documentation
Hyperparameter
===========================

<h3 align="center">
  <p style="text-align: center;">
  <a href="README.md" target="_blank">ENGLISH</a> | <a href="README.zh.md">中文文档</a>
  </p>
</h3>

<p align="center">

**Hyperparameter, Make configurable AI applications. Build for Python/Rust hackers.**

</p>

Hyperparameter is a Python/Rust library for managing hyperparameters that control the learning process of an ML model or the behaviors of an underlying machine learning system.

Quick Start
-----------

`Hyperparameter` uses the `auto_param` decorator to convert keywords arguments into configurable parameters:

```python
from hyperparameter import auto_param, param_scope

# Define the function 'foo' with configurable parameters
@auto_param("foo")
def foo(x=1):
    return f"x={x}"

# Control the parameters using 'param_scope'
foo()  # x=1, if no params is defined
with param_scope(**{"foo.x": 2}):
    foo()  # x=2', when `foo.x` is set to `2`
```

Rust version of the above example:
```rust
fn foo() -> i32{
    with_params! {
        get x = foo.x or 1i32;

        x
    }
}

fn main() {
    println!("foo() = {}", foo()); // foo() = 1
    with_params! {
        set foo.x = 2i32;

        println!("foo() = {}", foo()); // foo() = 2
    }
}
```

Advanced Usage
--------------

### Read/Write Parameters

```python
from hyperparameter import param_scope

# create param_scope
with param_scope():
    pass

with param_scope("foo.y=1", "foo.z=b"):
    pass

with param_scope(**{"foo.y":1, "foo.z":2}):
    pass

# read param with default value
with param_scope(**{"foo.y":2}) as ps:
    y = ps.foo.y(1)  
    y = ps.foo.y | 1
    y = param_scope.foo.y(1)
    y = param_scope.foo.y | 1
    foo(1) # x=1, y=2, z='a'

# wite values to param_scope
with param_scope(**{"foo.y":2}) as ps:
    ps.foo.y = 2
    param_scope.foo.y = 2
```

### Nested Scope

`Hyperparameter` support nested `param_scope`:

``` python
from hyperparameter import param_scope

# no param_scope, use the default value defined in foo
foo(1) # x=1, y=1, z='a'

# start a new param_scope
# and set the default value of `foo.y` to `2`
with param_scope(**{"foo.y":2}) as ps:
    # found one param_scope `ps`, 
    # and receive default value of `foo.y` from `ps`
    foo(1) # x=1, y=2, z='a'

    # start another param_scope
    # and set the default value of `foo.y` to `3`
    with param_scope(**{"foo.z": "b"}) as ps2:
        # found nested param_scope `ps2`, 
        # and receive default values of `foo.z` from `ps2`
        foo(1) # x=1, y=2, z='b'
    # `ps2` ends here, and `foo.y` is restored to `2`
    foo(1) # x=1, y=2, z='a'
# `ps` ends here, and `foo.y` is restored to `1`
foo(1) # x=1, y=1, z='a'
```

### CMD Line Arguments

An example CLI app: 

```python
from hyperparameter import param_scope, auto_param

@auto_param
def main(a=0, b=1): # `inline default values`
    print(a, b)

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()

    parser.add_argument("-D", "--define", nargs="*", default=[], action="extend")
    args = parser.parse_args()

    with param_scope(*args.define):
        main()
```

Examples
--------

### [parameter tunning for researchers]examples/sparse_lr/README.md

This example demonstrates how to use hyperparameter in research projects, and make experiments reproducible.

### [experiment tracing for data scientists]examples/mnist/README.md

This example showcases experiment management with hyperparameter and result tracing with mlflow.tracing.