confection
? ist eine leichte Bibliothek, die ein Konfigurationssystem bietet, in dem Sie bequem beliebige Bäume von Objekten beschreiben können.
Die Konfiguration ist eine große Herausforderung für den maschinellen Lerncode, da Sie möglicherweise fast alle Details jeder Funktion als Hyperparameter freilegen möchten. Die Einstellung, die Sie aufdecken möchten, ist möglicherweise willkürlich weit unten in Ihrem Anrufstapel. Daher muss sie möglicherweise bis durch die CLI oder die REST -API durch eine beliebige Anzahl von Zwischenfunktionen geleitet, die die Schnittstelle von allem auf dem Weg beeinflussen. Und dann, sobald diese Einstellungen hinzugefügt sind, sind sie später schwer zu entfernen. Standardwerte werden auch schwierig zu ändern, ohne die Kompatibilität rückwärts zu brechen.
Um dieses Problem zu lösen, bietet confection
ein Konfigurationssystem, mit dem Sie leicht beliebige Bäume von Objekten beschreiben können. Die Objekte können über Funktionsaufrufe erstellt werden, die Sie mit einer einfachen Dekorateur -Syntax registrieren. Sie können sogar die Funktionen, die Sie erstellen, übertreffen, sodass Sie Verbesserungen vornehmen können, ohne die Kompatibilität rückwärts zu brechen. Das ähnlichste Konfigurationssystem, das uns bewusst ist, ist Gin, das eine ähnliche Syntax verwendet, und ermöglicht es Ihnen auch, das Konfigurationssystem mit einem Dekorator mit Funktionen in Ihrem Code zu verknüpfen. Das Konfigurationssystem von confection
ist einfacher und betont einen anderen Workflow über eine Untergruppe der Gin -Funktionalität.
PIP installieren Konfekt
Conda install -c Conda -forge Confection
Das Konfigurationssystem analysiert eine .cfg
-Datei wie
[Training] midence = 10dropout = 0.2use_vectors = false [Training.logging] Level = "Info" [NLP]# Dies verwendet den Wert des Trainings.
und löst es auf ein Dict
:
{"Training": {"Geduld": 10, "Dropout": 0.2, "Gebrauchsnutzung": Falsch, "Protokollierung": {"Level": "Info"} }, "nlp": {"use_Vectors": false, "lang": "en" } }
Die Konfiguration ist in Abschnitte unterteilt, wobei der Abschnittsname in quadratischen Klammern beispielsweise [training]
ist. Innerhalb der Abschnitte können Konfigurationswerte Tasten mit =
zugewiesen werden. Werte können auch aus anderen Abschnitten unter Verwendung der DOT -Notation und den Platzhaltern, die durch das Dollarzeichen und die lockigen Klammern angegeben sind, verwiesen werden. Beispielsweise erhält ${training.use_vectors}
den Wert von Use_Vectors im Trainingsblock. Dies ist nützlich für Einstellungen, die über Komponenten hinweg geteilt werden.
Das Konfigurationsformat verfügt über drei Hauptunterschiede zu Pythons integriertem configparser
:
JSON-formatierte Werte. confection
führt alle Werte über json.loads
um sie zu interpretieren. Sie können Atomwerte wie Zeichenfolgen, Schwimmer, Ganzzahlen oder Booleschen verwenden oder komplexe Objekte wie Listen oder Karten verwenden.
Strukturierte Abschnitte. confection
verwendet eine Punktnotation, um verschachtelte Abschnitte zu bauen. Wenn Sie einen Abschnitt namens [section.subsection]
haben, wird das confection
in eine verschachtelte Struktur analysiert, wobei der Unterabschnitt innerhalb des Abschnitts eingelegt wird.
Verweise auf Registrierungsfunktionen. Wenn ein Schlüssel mit @
beginnt, interpretiert confection
seinen Wert als Name einer Funktionsregistrierung, laden Sie die für diesen Namen registrierte Funktion und geben Sie den Rest des Blocks als Argumente weiter. Wenn in der Funktion Typ Hinweise verfügbar sind, werden die Argumentwerte (und der Rückgabewert der Funktion) gegen sie validiert. Auf diese Weise können Sie komplexe Konfigurationen wie eine Trainingspipeline ausdrücken, in der batch_size
durch eine Funktion besiedelt wird, die Schwimmer ausgibt.
Es gibt kein vordefiniertes Schema, dem Sie folgen müssen. Wie Sie die obersten Abschnitte einrichten, liegt bei Ihnen. Am Ende erhalten Sie ein Wörterbuch mit den Werten, die Sie in Ihrem Skript verwenden können - sei es vollständige initialisierte Funktionen oder nur grundlegende Einstellungen.
Nehmen wir zum Beispiel an, Sie möchten einen neuen Optimierer definieren. Sie würden seine Argumente in config.cfg
wie so definieren:
[Optimierer] @optimizers = "my_cool_optimizer.v1" Learn_Rate = 0,001Gamma = 1E-8
So laden und analysieren Sie diese Konfiguration mithilfe einer catalogue
( catalogue
separat installieren):
Importieren Sie DataClassesFrom Typing Typing Import Union, iterableImport Katalogue von Confection Import Registry, config# Erstellen einer neuen Registrierung.registry.optimizers = catalogue.create ("Confection", "Optimierer", Entry_points = False)# Dummy -Optimierer -Klasse. MyCooloptimizer: Learn_Rate: FloatGamma: [email protected]("my_cool_optimizer.v1")def make_my_optimizer(learn_rate: Union[float, Iterable[float]], gamma: float):return MyCoolOptimizer(learn_rate, gamma)# Load the config file from disk, resolve es und holt das sofortige Optimizer -Objekt.Config = Config (). From_disk ("./ config.cfg") creamed = registry.resolve (config) optimizer = aufgelöst ["optimizer"] # myCooloptimizer (Learn_Rate = 0,001, Gamma = 1E-08)
Euen Achtung: Typ -Prüfer wiemypy
markieren das Hinzufügen neuer Attribute zurregistry
auf diese Weise - dhregistry.new_attr = ...
- als Fehler. Dies liegt daran, dass nach der Initialisierung der Klasse ein neues Attribut hinzugefügt wird. Wenn Sie typechecker verwenden, können Sie dies entweder ignorieren (z. B. mit# type: ignore
fürmypy
) oder verwenden Sie eine Art typesafe Alternative: anstelle vonregistry.new_attr = ...
, verwenden Siesetattr(registry, "new_attr", ...)
.
Unter der Motorhaube wird confection
in der Funktion "my_cool_optimizer.v1"
in der Registrierung "Optimierer" nachschlagen und sie dann mit den Argumenten learn_rate
und gamma
aufrufen. Wenn die Funktion Typanmerkungen hat, wird auch die Eingabe überprüft. Wenn beispielsweise learn_rate
als Float kommentiert wird und die Konfiguration eine Zeichenfolge definiert, erhöht confection
einen Fehler.
Die Thinc -Dokumentation bietet weitere Informationen zum Konfigurationssystem:
rekursive Blöcke
Definieren von variablen Positionsargumenten
Verwenden von Interpolation
Verwenden von benutzerdefinierten Registern
Erweiterte Typanmerkungen mit Pydantic
Verwenden von Basisschemata
Füllen einer Konfiguration mit Standardeinstellungen
Config
Diese Klasse enthält die Modell- und Trainingskonfiguration und kann das Konfigurationsformat im INI-Stil von/zu einer String, Datei oder Bytes laden und speichern. Die Config
ist eine Unterklasse von dict
und verwendet Pythons ConfigParser
unter der Haube.
Config.__init__
Initialisieren Sie ein neues Config
mit optionalen Daten.
von Confection Import configConfig = config ({"Training": {"Geduld": 10, "Dropout": 0.2}})
Argument | Typ | Beschreibung |
---|---|---|
data | Optional[Union[Dict[str, Any], Config]] | Optionale Daten zur Initialisierung der Konfiguration mit. |
section_order | Optional[List[str]] | In den Abschnittsnamen der obersten Ebene wird in der Reihenfolge die gespeicherte und geladene Konfiguration verwendet. Alle anderen Abschnitte werden alphabetisch sortiert. |
is_interpolated | Optional[bool] | Ob die Konfiguration interpoliert ist oder ob sie Variablen enthält. Lesen Sie aus den data , wenn es sich um eine Instanz der Config handelt und ansonsten standardmäßig True . |
Config.from_str
Laden Sie die Konfiguration aus einer Zeichenfolge.
Aus Confection Import configConfig_str = "" "[Training] pifert = 10dropout = 0.2" "" "config = config (). Von_str (config_str) print (config [" Training "]) # {'Geduld': 10, 'Dropout': 0,2}}
Argument | Typ | Beschreibung |
---|---|---|
text | str | Die String -Konfiguration zu laden. |
interpolate | bool | Ob Variablen wie ${section.key} interpolieren soll. Standardmäßig True . |
overrides | Dict[str, Any] | Überschreibt für Werte und Abschnitte. Tasten sind in Punktnotation, z. B. "training.dropout" bereitgestellt. |
Zurück | Config | Die geladene Konfiguration. |
Config.to_str
Laden Sie die Konfiguration aus einer Zeichenfolge.
von Confection Import configConfig = config ({"Training": {"Geduld": 10, "Dropout": 0.2}}) print (config.to_str ()) # '[Training] npATience = 10nnndropout = 0.2'
Argument | Typ | Beschreibung |
---|---|---|
interpolate | bool | Ob Variablen wie ${section.key} interpolieren soll. Standardmäßig True . |
Zurück | str | Die String -Konfiguration. |
Config.to_bytes
Serialisieren Sie die Konfiguration zu einer Byte -Zeichenfolge.
Aus Confection Import configConfig = config ({"Training": {"Patience": 10, "Dropout": 0.2}}) config_bytes = config.to_Bytes () print (config_bytes) # b '[Training] npATience = 10nnndropout = 0.2'
Argument | Typ | Beschreibung |
---|---|---|
interpolate | bool | Ob Variablen wie ${section.key} interpolieren soll. Standardmäßig True . |
overrides | Dict[str, Any] | Überschreibt für Werte und Abschnitte. Tasten sind in Punktnotation, z. B. "training.dropout" bereitgestellt. |
Zurück | str | Die serialisierte Konfiguration. |
Config.from_bytes
Laden Sie die Konfiguration aus einer Byte -Zeichenfolge.
Aus Confection Import configConfig = config ({"Training": {"Patience": 10, "Dropout": 0.2}}) config_bytes = config.to_Bytes () new_config = config (). from_Bytes (config_bytes)
Argument | Typ | Beschreibung |
---|---|---|
bytes_data | bool | Die Daten zum Laden. |
interpolate | bool | Ob Variablen wie ${section.key} interpolieren soll. Standardmäßig True . |
Zurück | Config | Die geladene Konfiguration. |
Config.to_disk
Serialisieren Sie die Konfiguration in eine Datei.
von Confection Import configConfig = config ({"Training": {"Patience": 10, "Dropout": 0.2}}) config.to_disk ("./ config.cfg"))
Argument | Typ | Beschreibung |
---|---|---|
path | Union[Path, str] | Der Dateipfad. |
interpolate | bool | Ob Variablen wie ${section.key} interpolieren soll. Standardmäßig True . |
Config.from_disk
Laden Sie die Konfiguration aus einer Datei.
von Confection Import configConfig = config ({"Training": {"Patience": 10, "Dropout": 0.2}}) config.to_disk ("./ config.cfg") new_config = config (). from_disk ("./ config.cfg ")
Argument | Typ | Beschreibung |
---|---|---|
path | Union[Path, str] | Der Dateipfad. |
interpolate | bool | Ob Variablen wie ${section.key} interpolieren soll. Standardmäßig True . |
overrides | Dict[str, Any] | Überschreibt für Werte und Abschnitte. Tasten sind in Punktnotation, z. B. "training.dropout" bereitgestellt. |
Zurück | Config | Die geladene Konfiguration. |
Config.copy
Tiefkopieren Sie die Konfiguration.
Argument | Typ | Beschreibung |
---|---|---|
Zurück | Config | Die kopierte Konfiguration. |
Config.interpolate
Interpolieren Sie Variablen wie ${section.value}
oder ${section.subsection}
und geben Sie eine Kopie der Konfiguration mit interpolierten Werten zurück. Kann verwendet werden, wenn eine Konfiguration mit interpolate=False
, z. B. über Config.from_str
geladen wird.
von Confection Import configconfig_str = "" "[hyper_params] Dropout = 0.2 [Training] Dropout = $ {hyper_params.dropout}" "" "" config = config (). From_str (config_str, interpolat = false) print ("config [" Training "] ) # {'Dropout': '$ {hyper_params.dropout}'}} config = config.Interpolat () print (config ["traction"]) # {'Dropout': 0.2}}
Argument | Typ | Beschreibung |
---|---|---|
Zurück | Config | Eine Kopie der Konfiguration mit interpolierten Werten. |
Config.merge
Deep-Merge Zwei Konfigurationsobjekte, die die aktuelle Konfiguration als Standardeinstellung verwenden. Nur Abschnitte und Wörterbücher verschmelzen und nicht andere Werte wie Listen. Werte, die in den Aktualisierungen bereitgestellt werden, werden in der Basiskonfiguration überschrieben, und alle neuen Werte oder Abschnitte werden hinzugefügt. Wenn ein Konfigurationswert eine Variable wie ${section.key}
ist (z. B. wenn die Konfiguration mit interpolate=False)
wird die Variable bevorzugt , auch wenn die Aktualisierungen einen anderen Wert liefern. Dies stellt sicher, dass variable Referenzen nicht durch eine Zusammenführung zerstört werden.
Euen Beachten Sie, dass Blöcke, die sich auf registrierte Funktionen unter Verwendung der@
syntax beziehen, nur fusioniert werden, wenn sie sich auf dieselben Funktionen beziehen. Andernfalls könnte das Zusammenführen leicht ungültige Konfigurationen erzeugen, da verschiedene Funktionen unterschiedliche Argumente erfolgen können. Wenn sich ein Block auf eine andere Funktion bezieht, ist er überschrieben.
Aus Confection Import configBase_config_str = "" "" [Training] Patience = 10dropout = 0.2 "" "" "" "" "" "" "" "" "" "" "" "" "" "" "[Training] Dropout = 0.1Max_epochs = 2000" "" "" Base_config = config (). From_str (Base_Config) update_config = config (config (config (config). from_str (base_config) update_config = config (config (config (config). from_str (base_config) update_config = config (config (config (config (config). from_str (base_config_str) updaconfig = config (config (config (config ) .from_str (update_config_str) merged = Config (base_config) .merge (update_config) print (merged ["Training"]) # {'Geduld': 10, 'Dropout': 0.1, 'max_epochs': 2000}
Argument | Typ | Beschreibung |
---|---|---|
overrides | Union[Dict[str, Any], Config] | Die Aktualisierungen, die sich in die Konfiguration verschmelzen. |
Zurück | Config | Eine neue Konfigurationsinstanz, die die zusammengeführte Konfiguration enthält. |
Argument | Typ | Beschreibung |
---|---|---|
is_interpolated | bool | Ob die Konfigurationswerte interpoliert wurden. Standardeinstellungen zu True und ist auf False eingestellt, wenn eine Konfiguration mit interpolate=False , z. B. mit Config.from_str geladen wird. |