コンテンツにスキップ

Mujou

連続的継続学習のための非同期分散型深層学習フレームワーク

mujou のイメージ
画像は、落合陽一の作品「リキッドユニバース」をもとに新たに制作したもの

mujou は推論と学習を同時に行い続ける深層学習フレームワークである。ノードをつなぎ、ネットワークを構築する。

開発の初期段階

mujou はまだ開発の初期段階にある。API は予告なく変わることがある。

🌱 学び続けるネットワーク

従来の機械学習は学習を終えたら重みを固定し推論する。mujou のネットワークは、実行中常に入力を受け取って出力を出し、同時に学び続ける。

学習と推論を切り替えるモードも、エポックも無い。

名前は「諸行無常」の「無常」(常が無いこと)から取った。ストリームから学び続け、常に変わり続ける機械を作るためのフレームワーク。リアルタイム処理やロボティクスのように、動きながら学ぶ用途を狙う。

次のプログラムがそのネットワーク。PC-ALM のノードの鎖が、流れてくるバッチから回帰を学ぶ(学ぶノードは 3 つ)。ノードは動き続けたまま、各バッチから学ぶ前にそのバッチを予測する。

SHOWN = 0.032  # seconds of the run's timer each batch is shown
# tau.h sets how fast the credit settles (and the period of the nodes, h / 2),
# and the weights learn once per batch, by SGD at the rate
# SHOWN / optimizer.tau = 0.3.
tau = pc.TimeConstants(h=4e-3, lam=2e-3, r=4e-3)
optimizer = pc.optim.SGD(tau=SHOWN / 0.3)
torch.manual_seed(0)  # the initial weights, before the run
net = pc.Chain(
    nn.Sequential(nn.Linear(2, 64), nn.Tanh()),
    nn.Sequential(nn.Linear(64, 64), nn.Tanh()),
    nn.Linear(64, 1),
    x=TensorSpec((B, 2)),
    y=TensorSpec((B, 1)),
    batch=B,
    loss=pc.loss.MSELoss(B),  # the loss of each sample, (B,)
    tau=tau,
    optimizer=optimizer,
    learn_interval=0.75 * SHOWN,  # learn once, 3/4 of the way through each batch
)

torch.set_num_threads(1)
g = torch.Generator().manual_seed(1)
every = torch.ones(B, dtype=torch.bool)  # every sample has a target, and is new
losses: list[float] = []
with mujou.run(net) as run:
    for i in range(300):
        x = 2 * torch.rand(B, 2, generator=g) - 1
        y = torch.sin(2 * x[:, :1]) * torch.cos(x[:, 1:])
        sample = pc.msg.Sample(x=x, y=y, mask=every, reset=every)
        p = pc.show(run, net, sample, seconds=SHOWN)
        losses.append(nn.functional.mse_loss(p["y_hat"], y).item())  # before learning
        if i == 0 or (i + 1) % 50 == 0:
            recent = losses[-50:]
            mean = sum(recent) / len(recent)
            print(
                f"batch {i + 1:3d}: loss {mean:.4f} (the mean of the last {len(recent)})"
            )
    # The state of a node, by its path: input, layer0, layer1, output.
    lam = run.state_dict()["nodes"]["layer0"]["state"]["lam"]
print(f"the mean |lam| of layer0 (its credit) at the end: {lam.abs().mean():.2e}")

✨ 特徴

  • 🔄 推論と学習を同時に: 学習のモードも推論のモードも、エポックも無い
  • 🧩 PyTorch で書くノード: 各ノードは PyTorch で書き実行する
  • ⚡ 非同期のノード: 各ノードは自分の周期で更新し、ほかのノードを待たない
  • ⏱️ 連続時間: 実際に経った時間 dt に比例して更新する
  • 🧠 更新則は自由: ノードの中の BP、ノードをまたぐ PC-ALM、自作の則
  • 💾 状態を保存: ネットワークの状態を取得、後でその状態から再開
  • 🧪 決定的なテスト: 仮想のタイマーと手動の更新でノードをテスト可能

⚙️ 動き方

flowchart LR
    H["ホスト(あなたのプログラム)"] -->|"入力を書く"| A["ノード A"]
    A -->|"最新の値"| B["ノード B"]
    B -->|"出力を読む"| H

各ノードは自分の周期で更新を繰り返し、ほかのノードを待たない。読むのは、隣のノードが最後に送った値である。

ホスト(ネットワークを走らせるプログラム)は、走っているネットワークに入力を書き、出力を読む。

🧭 読み進め方

  • 初めてなら

    インストール → Mujou の仕組み → チュートリアルを最初のページから

  • さらに詳しく

    → トピック、サンプル、API リファレンスへ

  • 📦 インストール


    ソースから mujou をビルド、動作確認。

    インストール

  • 🧠 Mujou の仕組み


    ノード、Port、ネットワーク、実行、時間、状態、テスト、学習と、ノードが守る規則について。

    Mujou の仕組み

  • 🚀 チュートリアル


    ネットワークを走らせ、ノードを書いてテストし、ノードの中と PC-ALM で学習、保存と再開まで。

    チュートリアル

  • 🗺️ トピック


    Port、Group、ホストの入出力、時間、スレッドとデバイス、例外、更新則、PC-ALM。

    トピック

  • 💡 サンプル


    サンプルプログラムの一覧。実際に扱う際の参考に。

    サンプル

  • 📚 API リファレンス


    公開されているクラスと関数すべて (docstring から生成)

    API リファレンス