5分でできるHydraによるパラメーター管理


## 目次
1. [Hydraとは](#Hydraとは)
2. [インストール方法](#インストール方法)
3. [基本的な使い方](#基本的な使い方)
    - [ディレクトリ構成](#ディレクトリ構成)
    - [設定ファイル](#設定ファイル)
    - [main関数](#main関数)
4. [コマンドラインからの操作](#コマンドラインからの操作)
5. [複数のパラメータでの実行](#複数のパラメータでの実行)
6. [まとめ](#まとめ)
7. [参考にしたもの](#参考にしたもの)
8. [ソースコード](#ソースコード)
9. [補足説明](#補足説明)



---

## Hydraとは
HydraはMeta（旧Facebook）が開発したPython用の設定管理ライブラリです。このライブラリを使用すると、プログラムの設定を効率的に管理できます。特に機械学習のような、多数のパラメータを持つプロジェクトで役立ちます。

---

## インストール方法
Hydraはpipを使って簡単にインストールできます。
```bash
pip install hydra-core
```

---

## 基本的な使い方
### ディレクトリ構成
Hydraを使う際の基本的なディレクトリ構成は以下のようになります。
```
.
├── main.py                  # メインのPythonスクリプト（Hydraの設定と実行が含まれる）
├── conf                     # 設定ファイルが格納されるディレクトリ
│   └── config.yaml          # Hydraによって読み込まれる主要な設定ファイル
├── outputs                  # Hydraによって自動生成される出力ディレクトリ
│   └── [タイムスタンプ]     # 各実行（ジョブ）に基づいて生成されるサブディレクトリ
│       ├── config.yaml      # 実行時の設定ファイルのコピー
│       └── ...              # その他の出力（ログファイルなど）
└── multirun                 # multirunオプションで自動生成されるディレクトリ
    └── [タイムスタンプ]
        ├── 0                # ナンバリングされたジョブディレクトリ
        │   ├── config.yaml  # 実行時の設定ファイルのコピー
        │   └── ...          # その他の出力（ログファイルなど）
        ├── 1
        │   ├── config.yaml
        │   └── ...
        └── ...

```
- `main.py`: このPythonファイルはプログラムのエントリーポイントとなります。Hydraの設定とプログラムの実行がこのファイル内で行われます。
- `conf`: このディレクトリには、Hydraによって読み込まれる設定ファイル（`config.yaml`）が格納されます。
- `config.yaml`: このYAMLファイルには、プログラムで使用する各種パラメータが設定されています。  
- `outputs`: このディレクトリは、プログラムが実行されるたびにHydraによって自動的に生成されます。各実行（または「ジョブ」）には、タイムスタンプに基づいて独自のサブディレクトリが作成されます。
- `multirun`: このディレクトリは、`--multirun`オプションを使用した場合にHydraによって生成されます。各タイムスタンプの下には、ナンバリングされたジョブディレクトリが作成されます。

---

この構成に従って、設定ファイルとプログラムを配置します。

### 設定ファイル
Hydraでは設定をYAMLファイルで管理します。以下は基本的な`config.yaml`の例です。
```yaml
data:
  input: "../input"

learning_rate: 0.001
batch_size: 32
```
このYAMLファイルには、データセットのパス(`data.input`)、学習率（`learning_rate`）、バッチサイズ（`batch_size`）が設定されています。

### main関数
設定ファイルを読み込むためには、`main`関数に`@hydra.main`デコレータを追加します。以下はその例です。
```python
import hydra
from omegaconf import DictConfig


@hydra.main(config_name="config", version_base=None, config_path="conf")
def main(cfg: DictConfig) -> None:
    print(cfg.data.input)
    print(cfg.learning_rate)
    print(cfg.batch_size)


if __name__ == "__main__":
    main()
```
この`main`関数では、`config.yaml`から設定を読み込み、それを出力しています。実際に機械学習などで使用する際は、パラメーターをモデリング部分などに渡してあげます。
1. `from omegaconf import DictConfig`: OmegaConfライブラリからDictConfigクラスをインポートしています。このクラスは、設定ファイルから読み込んだデータをPythonの辞書のように扱うことができます。
2. `@hydra.main(...)`: このデコレータは、`main`関数をHydraで管理するためのものです。
    - `config_name="config"`: `config.yaml`という名前の設定ファイルを使用することを指定しています。
    - `version_base=None`: Hydraのバージョン互換性に関する警告を無視するために`None`を指定しています。
    - `config_path="conf"`: 設定ファイルが`conf`ディレクトリ内にあることを指定しています。
3. `def main(cfg: DictConfig) -> None:`: `main`関数の定義です。この関数は、設定情報を引数`cfg`として受け取ります。
    - `cfg: DictConfig`: `DictConfig`型の`cfg`引数は、設定ファイルの内容を保持します。
   
---

## コマンドラインからの操作
Hydraを使うと、コマンドラインから直接パラメータを実行時のみオーバーライドすることができます。元の設定ファイルが書き換わることはありません。
```bash
python main.py learning_rate=0.1 batch_size=64
```
このコマンドでは、`learning_rate`を0.1、`batch_size`を64に設定しています。指定していないパラメーターは、設定ファイルの値がそのまま使用されます。実行すると、`outputs`にタイムスタンプと共にログとして保存されます。

---

## 複数のパラメータでの実行
Hydraの`--multirun`オプションを使うと、複数のパラメータでプログラムを実行できます。
```bash
python main.py --multirun learning_rate=0.1 batch_size=16,32,64
```
このコマンドでは、`learning_rate`を0.1に固定し、`batch_size`を16,32,64の3つの値(**間にスペースを入れるとエラーになるので注意**)で実行します。機械学習でパラメーターチューニングをするときにとても便利です。実行すると、`multirun`に各実験がタイムスタンプと共にログとして保存されます。

---

## まとめ
この記事では、Hydraを使ってパラメーター管理を効率的に行う基本的な方法を紹介しました。特に、`config.yaml`での設定、`main`関数での設定の読み込み、コマンドラインでのパラメータオーバーライド、複数のパラメータでの実行などについて説明しました。
以上「5分でできるHydraによるパラメーター管理」でした。ご参考になれば幸いです。

## 参考にしたもの
- [1] [Hydra公式サイト](https://hydra.cc/)
- [2] [機械学習の煩雑なパラメーター管理の決定版 「Hydra」「MLflow」「Optuna」の組み合わせで手軽にはじめる一元管理](https://logmi.jp/tech/articles/325087)
- [3] [実験設定の管理[hydra]](https://zenn.dev/zenizeni/books/a64578f98450c2/viewer/041e66)
- [4] [hydraを使用した機械学習のパラメータ管理方法について理解する](https://yaakublog.com/hydra)


## ソースコード
ソースコードは[**こちらのGitHub**](https://github.com/Isaka-code/hydra-in-5-minutes)で共有しています


## 補足説明


<details><summary>補足説明：YAMLファイルとは</summary><div>


### YAMLファイルとは

YAMLは、データの構造化された形での表現を可能にするテキストベースのフォーマットです。YAMLはJSON（JavaScript Object Notation）と同様に、データを階層的に構造化することができますが、人間が読み書きしやすい形式が採用されています。

#### 基本的な特徴

1. **可読性が高い**: インデントとコロンを用いてデータの階層構造を表現します。
2. **拡張性が高い**: スカラー値だけでなく、リストやマップ（辞書）も表現できます。
3. **多言語対応**: YAMLライブラリは多くのプログラミング言語で利用可能です。

#### 基本的な構文

- **キーと値**: キーと値はコロン（`:`）で区切られます。
  ```yaml
  key: value
  ```
  
- **リスト**: ハイフン（`-`）を用いてリストを表現します。
  ```yaml
  fruits:
    - Apple
    - Banana
    - Cherry
  ```
  
- **マップ（辞書）**: キーと値のペアでマップを表現します。
  ```yaml
  person:
    name: John
    age: 30
  ```

#### 例：`config.yaml`

```yaml
# config.yaml
learning_rate: 0.001
batch_size: 32
```

この`config.yaml`ファイルは、`learning_rate`と`batch_size`という2つのキーを持ち、それぞれのキーには`0.001`と`32`という値が設定されています。

---

YAMLは設定ファイル、データ交換、データ保存など多くの用途で広く使用されています。特に機械学習やデータ分析の分野では、実験の設定やハイパーパラメータを管理するためによく用いられます。　
</div></details>


<details><summary>補足説明：デコレーターとは</summary><div>



### デコレーターとは

デコレータ（Decorator）は、Pythonにおいて関数やメソッド、クラスに新しい機能を動的に追加するための特殊な種類の構文です。デコレータは、元の関数を「装飾」する形で動作し、その動作を拡張または修正します。

#### 基本的な特徴

1. **再利用性**: 同じ機能を複数の関数に追加する場合に、コードの再利用性が高まります。
2. **コードの整理**: 機能ごとにデコレータを定義することで、コードが整理され、可読性が向上します。
3. **拡張性**: 既存のコードを変更することなく新しい機能を追加できます。

#### 基本的な構文

デコレータは`@`記号を用いて関数の前に定義されます。

```python
@decorator_function
def my_function():
    print("Hello, world!")
```

ここで`decorator_function`は、デコレータとして機能する関数です。

#### シンプルなデコレータの例

以下は、関数が呼び出された際にその名前を表示するシンプルなデコレータの例です。

```python
def simple_decorator(f):
    def wrapper():
        print(f"Function {f.__name__} is called.")
        f()
    return wrapper

@simple_decorator
def hello():
    print("Hello, world!")
```

この例では、`hello()`関数が呼び出されると、`simple_decorator`によってその前後にメッセージが表示されます。

#### Hydraでの使用例

Hydraライブラリでは、`@hydra.main()`というデコレータが提供されています。このデコレータは、設定管理、コマンドラインオプションの解析、ロギングなど、多くの便利な機能を`main`関数に追加します。

```python
@hydra.main(config_name="config")
def main(cfg):
    ...
```

---

デコレータはPythonにおいて非常に強力な機能であり、特に設定管理やロギング、権限管理など、多くの用途で使用されます。　
</div></details>