Metadata-Version: 2.1
Name: torch-lighter
Version: 0.1.1
Summary: Lightweight extension for torch to speed-up prototyping.
Home-page: https://github.com/Xpitfire/lighter
Author: Marius-Constantin Dinu
Author-email: dinu.marius-constantin@hotmail.com
License: UNKNOWN
Description: # Lighter
        
        Lightweight extension for torch to speed up project prototyping and enable dependency injection of object instances.
        This framework includes a setup script to get started with a pre-defined project structure and the documentation offers examples and an overview of the initial usage.
        
        ## Install
        
        ```shell script
        $> pip install torch-lighter
        ```
        
        ## Quickstart
        
        Create a JSON file `config.json`:
        
        ```json
        {
          "num_of_epochs": 50
        }
        ```
        
        Create a python file and use the decorators to inject the config instance:
        
        ```python
        # creates the application context
        Context.create()
        
        class Demo:
            @config(path='config.json', property='config')
            def __init__(self):
                pass
            
            def run(self):
                print(self.config.num_of_epochs)
        
        # creates the object instance and injects the configs
        Demo().run()
        ```
        
        This will print the following output:
        
        ```shell script
        []: 50
        ```
        
        Lighter can be simply added to any existing project or one can create a new lighter template project as shown in the next section.
        
        
        ## Create a project
        
        ### Initialize project
        
        Type the following in your command line / bash:
        ```shell script
        $> lighter-init <project-name>
        ``` 
        
        ### Structure overview
        The above command will create the following project structure:
        ```text
        my_project:
          * configs
            - modules.config.json
          * criterions
            - __init__.py
            - defaults.config.json
            - defaults.py
          * data_buildres
            - __init__.py
            - defaults.config.json
            - defaults.py
          * datasets
            - __init__.py
            - defaults.config.json
            - defaults.py
          * experiments
            - __init__.py
            - defaults.config.json
            - defaults.py
          * models
            - __init__.py
            - defaults.config.json
            - defaults.py
          * optimizers
            - __init__.py
            - defaults.config.json
            - defaults.py
          * tests
            - __init__.py
            - test_experiment.py
          * transforms
            - __init__.py
            - defaults.py
          * __init__.py
          * README.md
          * LICENSE
          * setup.py
        ```
        
        Of course this is only a preset example and the projects can be structured at will.
        
        ### Modules description
        - collectible: are used to gather metrics over multiple steps / epochs
        - criterion: torch criterion classes
        - data_builder: data builder classes creating the data loaders
        - dataset: dataset used by the data builder
        - experiment: experiment logic files containing the main `run()`, `train()` and `eval()` methods
        - metric: metrics used to measure performance
        - module: references all available modules
        - optimizer: optimizers used for performing the step
        - test: contains the main testing sources for the project and mark the main entrance point
        - transform: data transforms are used by the datasets to reshape the data structures
        - writer: tensorboard writers
        
        ### TODOs
        
        Each directory containing a python file may also contain a config file outsourcing properties for testing.
        Modules that require further code insertion are marked with `TODO` flags.
        
        ### Run an experiment
        
        After creating a demo project and inserting code into the `TODO` placeholders simply run an experiment by calling:
        ```python
        $> python tests/test_experiment.py
        ```
        
        It might be necessary to set your `PYTHONPATH` before running the experiment file:
        
        ```python
        $> PYTHONPATH=. python tests/test_experiment.py
        ```
        
        One can also simply change the global device setting or initialize an experiment from command line by specifying theses arguments:
        ```python
        $> PYTHONPATH=. python tests/test_experiment.py --device cuda:1 --config <path-to-config>
        ```
        
        ## Advanced
        
        ### Inheritance from base class
        
        One can simply extend from any base class within the lighter framework:
        ```python
        class SimpleExperiment(DefaultExperiment):
            @config(path='experiments/defaults.config.json', property='experiments')
            def __init__(self):
                super(SimpleExperiment, self).__init__(epochs=self.config.experiments.num_epochs)
        
            def eval(self):
                ...
        
            def train(self):
                ...
                preds = self.model(inputs)
                loss = self.metric(preds, targets)
                ...
        
            def run(self):
                for epoch in self.epochs:
                    self.train()
                    self.eval()
        ```
        In this example we use the `DefaultExperiment` class and create a new experiment. 
        The `@config` decorator injects the `defaults.config.json` into the `self.config` instance in a sub-property `experiments` of the default config.
        One can then access the properties by de-referencing `self.config.experiments.<property>`.
        `self.model` and `self.metric` are injected by the base class and are usually referenced in the `modules/defaults.config.json`.
        
        ### Decorators
        
        It is also possible to simply use the required decorators without base class sub-classing. 
        There are currently five decorators:
        * `@config` - injects the default config instance and allows to load new configs
        * `@context` - injects the application context which holds config and registry instances
        * `@transform` - injects the default data transform instance
        * `@dataset` - injects the default dataset instance
        * `@model` - injects the default model instance
        * `metric` - injects the default metric instance
        * `@reference` - injects a singe defined instance
        * `@references` - injects a set of pre-set or defined instance(s)
        * `@strategy` - loads and defines a training set strategy from a config and injects the main object instances
        * `@register` - allows to quickly register a new type to the context registry and inject the instance into the current instance
        * `@hook` - allows to hook and overwrite an existing method to change the execution logic
        * `@inject` - allows to inject single instances into different context options (registry, types, instances, configs)
        * `@search` - allows to register hyper-parameters to parse a config schedule for parallelled executions
        
        By default the templates for a new project are creating a config file at the `configs/modules.config.json` path, which uses the following names for the dependency injection `['dataset', 'data_builder', 'criterion', 'model', 'writer', 'optimizer', 'transfom', 'metric', 'collectible']`.
        An experiment gets these instances automatically injected.
        ```json
        {
          "transform": "type::transforms.defaults.Transform",
          "dataset": "type::datasets.defaults.Dataset",
          "data_builder": "type::data_builders.defaults.DataBuilder",
          "criterion": "type::criterions.defaults.Criterion",
          "model": "type::models.defaults.Model",
          "optimizer": "type::optimizers.defaults.Optimizer",
          "metric": "type::lighter.metric.BaseMetric",
          "collectible": "type::lighter.collectible.BaseCollectible",
          "writer": "type::lighter.writer.BaseWriter"
        }
        ```
        
        But it is simple to inject custom objects or exchangeable names by referring to a new name or type:
        ```json
        {
          ...
          "other_model_name": "type::models.other.Network",
          ...
        }
        ```
        
        This now allows to load a model using the `@model` decorator withe the new property reference.
        
        ```python
        class Demo:
            @references(properties=['other_model_name'])
            def __init__(self):
                ...
                self.other_model_name.<property>
                ...
        ```
        
        ### Config templates
        
        All configs are based on `json` files. Yet, when importing the configs `lighter` parses some escape sequences allowing for more modularization of your project structure:
        * `config::<config-file-path>` - imports another config into the current json config instance
        * `import::<config-file-path>` - imports all properties of the referenced config file into the current config instance (attention may override existing properties)
        * `type::<type-file-path>` - imports a python type which is registered to the application context `registry.types` and can be used to instantiate new objects
        
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Description-Content-Type: text/markdown
