Newer
Older
TIASJudgeModel / src / tias_judge_model / models / factory.py
"""timm によるモデル生成(SPEC_02「モデル」).

`model.name` に timm のモデル名を渡すだけでアーキテクチャを差し替えられるようにする.
"""

from __future__ import annotations

import timm
from torch import nn

from tias_judge_model.data.classes import NUM_CLASSES


def create_model(name: str, *, pretrained: bool, num_classes: int = NUM_CLASSES) -> nn.Module:
    """timm のモデルを出力 `num_classes` クラスで作る.

    Args:
        name: timm のモデル名(例: `convnext_tiny`・`efficientnet_b0`・`vit_small_patch16_224`).
        pretrained: ImageNet 事前学習の重みを使うか(初回はダウンロードする).
        num_classes: 出力クラス数.

    Returns:
        入力 `(B, 3, H, W)` の float テンソルから `(B, num_classes)` のロジットを返すモデル.

    Raises:
        ValueError: timm に無いモデル名の場合.
    """
    if not timm.is_model(name):
        raise ValueError(f"timm に無いモデル名である: {name!r}")
    return timm.create_model(name, pretrained=pretrained, num_classes=num_classes)


def count_parameters(model: nn.Module) -> int:
    """モデルのパラメータ数(学習対象外も含む)を返す.

    Args:
        model: モデル.

    Returns:
        パラメータの要素数の合計.
    """
    return sum(p.numel() for p in model.parameters())