Anyfig, config system built for ML

Oli: <p>Hi peepz! <img src="https://discuss.pytorch.org/images/emoji/apple/wave.png?v=12" title=":wave:" class="emoji" alt=":wave:" loading="lazy" width="20" height="20"></p>
<p>I’ve been active here at the forums for a while and would love some input on my project.</p>
<p>In my own ML projects, I’ve been using Python classes to define my settings such as batch size and learning rate. In many ways, it has been more powerful than Argparse, so I thought I’d make it into a package. Without any more fuzz, introducing Anyfig!! (<a href="https://github.com/OlofHarrysson/anyfig" rel="noopener nofollow ugc">Gihub repo</a>)</p>
<blockquote>
<p>Anyfig is a Python library for creating configurations (settings) at runtime. Anyfig utilizes Python classes which empowers the developer to put anything, from strings to custom objects in the config. Hence the name Any(con)fig.</p>
</blockquote>
<h3><a name="the-basics-1" class="anchor" href="#the-basics-1"></a>The basics</h3>
<ol>
<li>Decorate a class with ‘<span class="mention">@anyfig.config_class</span>’.</li>
<li>Add config-parameters as attributes in the class</li>
<li>Call the ‘setup_config’ function to instantiate the config object</li>
</ol>
<pre data-code-wrap="python"><code class="lang-python">import anyfig
import random

@anyfig.config_class
class FooConfig():
  def __init__(self):
    # Config-parameters goes as attributes
    self.experiment_note = 'Changed some stuff'
    self.seed = random.randint(0, 80085)

config = anyfig.setup_config(default_config='FooConfig')
print(config)
print(config.seed)
</code></pre>
<p>At the moment, Anyfig supports inheritance, command line inputs, saving &amp; loading and more ideas in the pipeline <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> Check the github for some more info or reach out to me.</p>
<p>The benefits might not be obvious at first glance so let me try to sell this.</p>
<ol>
<li>Defining config-parameters at runtime offers dynamic settings. Leverage the power of Python. Also cleans up the code</li>
</ol>
<pre><code class="lang-auto">{"loss_fn": "l1loss"} # Lives inside a .json file
config = ~parse_jsonfile~

if config.loss_fn = 'l1loss':
  loss_fn = torch.nn.L1Loss()
elif config.loss_fn = 'mse'
  loss_fn = torch.nn.MSELoss()
</code></pre>
<p>Skip the if else statements. You can do those kinds of operations directly in the config</p>
<pre><code class="lang-auto">@anyfig.config_class
class Train():
  def __init__(self):
    self.loss_fn = torch.nn.L1Loss()
</code></pre>
<ol start="2">
<li>Class inheritance avoids duplicated code. Good for biiig projects. How often have you started training with the wrong settings? Anyfig can help mitigate that problem.</li>
</ol>
<p>A typical use case for Anyfig would be to have one config-class for training, one for laptop-debugging and one for prediction. Since many of the config-parameters are the same, you can choose one class as the parent class and have the other two inherit from the parent and overwrite selected config-parameters.</p>
<pre data-code-wrap="python"><code class="lang-python">import anyfig

@anyfig.config_class
class Train():
  def __init__(self):
    self.batch_size = 32
    self.seed = random.randint(0, 80085)

@anyfig.config_class
class DebugTrain(Train):
  def __init__(self):
    super().__init__()
    self.seed = 0

@anyfig.config_class
class Predict(Train):
  def __init__(self):
    super().__init__()
    self.batch_size = 1
</code></pre>
<p>I’m currently looking for people who can try this thing out <img src="https://discuss.pytorch.org/images/emoji/apple/partying_face.png?v=12" title=":partying_face:" class="emoji" alt=":partying_face:" loading="lazy" width="20" height="20"></p>