GithubHelp home page GithubHelp logo

tjni / hyperpyyaml Goto Github PK

View Code? Open in Web Editor NEW

This project forked from speechbrain/hyperpyyaml

0.0 1.0 0.0 50 KB

Extensions to YAML syntax for better python interaction

License: Apache License 2.0

Python 100.00%

hyperpyyaml's Introduction

Introduction

A crucial element of systems for data-analysis is laying out all the hyperparameters of that system so they can be easily examined and modified. We add a few useful extensions to a popular human-readable data-serialization language known as YAML (YAML Ain't Markup Language). This provides support for a rather expansive idea of what constitutes a hyperparameter, and cleans up python files for data analysis to just the bare algorithm.

Table of Contents

Security note

Loading HyperPyYAML allows arbitrary code execution. This is a feature: HyperPyYAML allows you to construct anything and everything you need in your experiment. However, take care to verify any untrusted recipes' YAML files just as you would verify the Python code.

YAML basics

YAML is a data-serialization language, similar to JSON, and it supports three basic types of nodes: scalar, sequential, and mapping. PyYAML naturally converts sequential nodes to python lists and mapping nodes to python dicts.

Scalar nodes can take one of the following forms:

string: abcd  # No quotes needed
integer: 1
float: 1.3
bool: True
none: null

Note that we've used a simple mapping to demonstrate the scalar nodes. A mapping is a set of key: value pairs, defined so that the key can be used to easily retrieve the corresponding value. In addition to the format above, mappings can also be specified in a similar manner to JSON:

{foo: 1, bar: 2.5, baz: "abc"}

Sequences, or lists of items, can also be specified in two ways:

- foo
- bar
- baz

or

[foo, bar, baz]

Note that when not using the inline version, YAML uses whitespace to denote nested items:

foo:
    a: 1
    b: 2
bar:
    - c
    - d

YAML has a few more advanced features (such as aliases and merge keys) that you may want to explore on your own. We will briefly discuss one here since it is relevant for our extensions: YAML tags.

Tags are added with a ! prefix, and they specify the type of the node. This allows types beyond the simple types listed above to be used. PyYAML supports a few additional types, such as:

!!set                           # set
!!timestamp                     # datetime.datetime
!!python/tuple                  # tuple
!!python/complex                # complex
!!python/name:module.name       # A class or function
!!python/module:package.module  # A module
!!python/object/new:module.cls  # An instance of a class

These can all be quite useful, however we found that this system was a bit cumbersome, especially with the frequency with which we were using them. So we decided to implement some shortcuts for these features, which we are calling "HyperPyYAML".

HyperPyYAML

We make several extensions to yaml including easier object creation, nicer aliases, and tuples.

Objects

Our first extension is to simplify the structure for specifying an instance, module, class, or function. As an example:

model: !new:collections.Counter

This tag, prefixed with !new:, constructs an instance of the specified class. If the node is a mapping node, all the items are passed as keyword arguments to the class when the instance is created. A list can similarly be used to pass positional arguments. See the following examples:

foo: !new:collections.Counter
  - abracadabra
bar: !new: collections.Counter
  a: 2
  b: 1
  c: 5

We also simplify the interface for specifying a function or class or other static Python entity:

add: !name:operator.add

This code stores the add function. It can later be used in the usual way:

>>> loaded_yaml = load_hyperpyyaml("add: !name:operator.add")
>>> loaded_yaml["add"](2, 4)
6

Aliases

Another extension is a nicer alias system that supports things like string interpolation. We've added a tag written !ref that takes keys in angle brackets, and searches for them inside the yaml file itself. As an example:

folder1: abc/def
folder2: ghi/jkl
folder3: !ref <folder1>/<folder2>

foo: 1024
bar: 512
baz: !ref <foo> // <bar> + 1

This allows us to change some values and automatically change the dependent values accordingly. You can also refer to other references, and to sub-nodes using brackets.

block_index: 1
cnn1:
    out_channels: !ref <block_index> * 64
    kernel_size: (3, 3)
cnn2: 
    out_channels: !ref <cnn1[out_channels]>
    kernel_size: (3, 3)

Finally, you can make references to nodes that are objects, not just scalars.

yaml_string = """
foo: !new:collections.Counter
  a: 4
bar: !ref <foo>
baz: !copy <foo>
"""
loaded_yaml = load_hyperpyyaml(yaml_string)
loaded_yaml["foo"].update({"b": 10})
print(loaded_yaml["bar"])
print(loaded_yaml["baz"])

This provides the output:

Counter({'b': 10, 'a': 4})
Counter({'a': 4})

Note that !ref makes only a shallow copy, so updating foo also updates bar. If you want a deep copy, use the !copy tag.

There are some issues (#7 #11) mentioning that !ref cannot refer to the return value of !apply function. Thus we provide another !applyref tag to work with !ref, which can be used in four ways:

# 1. Pass the positional and keyword arguments at the same time. Like `!!python/object/apply:module.function` in pyyaml
c: !applyref:sorted
    _args: 
        - [3, 4, 1, 2]
    _kwargs:
        reverse: False
d: !ref <c>-<c>

# 2. Only pass the keyword arguments
e: !applyref:random.randint
    a: 1
    b: 3
f: !ref <e><e>

# 3. Only pass the positional arguments
g: !applyref:random.randint
    - 1
    - 3
h: !ref <g><g>

# 4. No arguments
i: !applyref:random.random
j: !ref <i><i>

Note that !applyref cannot return an object, otherwise the RepresenterError will be raised.

Tuples

One last minor extension to the yaml syntax we've made is to implicitly resolve any string starting with ( and ending with ) to a tuple. This makes the use of YAML more intuitive for Python users.

How to use HyperPyYAML

All of the listed extensions are available by loading yaml using the load_hyperpyyaml function. This function returns an object in a similar manner to pyyaml and other yaml libraries. Also, load_hyperpyyaml takes an optional argument, overrides which allows changes to any of the parameters listed in the YAML. The following example demonstrates changing the out_channels of the CNN layer:

>>> yaml_string = """
... block_index: 1
... cnn1:
...   out_channels: !ref <block_index> * 64
...   kernel_size: (3, 3)
... cnn2: 
...   out_channels: !ref <cnn1[out_channels]>
...   kernel_size: (3, 3)
... """
>>> overrides = {"block_index": 2}
>>> with open("hyperparameters.yaml") as f:
...    hyperparameters = load_hyperpyyaml(f, overrides)
>>> hyperparameters["block_index"]
2
>>> hyperparameters["cnn2"]["out_channels"]
128

Conclusion

We've defined a number of extensions to the YAML syntax, designed to make it easier to use for hyperparameter specification. Feedback is welcome!

hyperpyyaml's People

Contributors

pplantinga avatar matln avatar adel-moumen avatar weiwei-ww avatar xin-w8023 avatar gastron avatar gaetanlepage avatar aqzlpm11 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.