7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PyTorchとPySAMACTを比較してみた~Iris分類から見る設計思想の違い~

7
Last updated at Posted at 2026-07-15

はじめに

こんにちは。
メイビスデザインのokaki(@0kak1)です。

本記事では、機械学習フレームワークとして広く利用されている
PyTorchと、当社が開発・提供するPySAMACTを比較してみます。

ただし、本記事は「どちらが優れているか」を議論するものではありません。

両者はそもそも目的が異なります。

PyTorchはGPUを活用した高速な学習・推論を得意とする一方、
PySAMACTはエンドポイントAI向けハードウェア実装を意識した設計思想を重視しています。

今回は機械学習の定番であるIrisデータセットを用いて、
実際に両者で分類タスクを実施しながら違いを見ていきます。

PySAMACTの詳細は以下の記事を参照ください。
https://qiita.com/nhnhnh/items/243d9adbd4e79c44ca29

PyTorchとPySAMACTの違い

最初に結論を書いてしまうと、

PyTorchは
「AIモデルを作るためのライブラリ」

PySAMACTは
「エンドポイントAIを設計するためのライブラリ」

という違いがあります。

項目 PyTorch PySAMACT
主用途 AIモデル開発 エンドポイントAI PoC
学習方式 GPU学習前提 オンチップ学習想定
重視すること 学習速度・開発効率 HW実装を見据えた評価

今回の実験

タスク

アヤメ分類 (Classification)

データセット

scikit-learnのIrisデータセット

  • がく片長
  • がく片幅
  • 花びら長
  • 花びら幅

の4特徴量から3種類のアヤメを分類するデータセットです。

比較対象

  • PyTorch
    • 4-16-3 MLP
    • ReLU
    • Adam
    • CrossEntropyLoss
    • 20epoch / 100epoch
  • PySAMACT
    • RateEncodeLayer
    • SAMLayer(16)
    • SAMLayer(3)
    • MajorityDecodeLayer
    • Compile(32)
    • 20epoch

評価指標

今回は以下の3項目を比較します。

  • Accuracy(分類精度)
  • Training Time(学習時間)
  • Inference Time(推論時間)

PyTorchでIris分類

コード(一部抜粋)

細かいところは省略しますが、モデル作って、学習・推論する根幹の部分のみコードを提示します。

# ------------------------
# モデル定義
# ------------------------
class IrisNet(nn.Module):
    def __init__(self):
        super().__init__()

        self.fc1 = nn.Linear(4, 16)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(16, 3)

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

model = IrisNet()

# ------------------------
# 損失関数・最適化手法
# ------------------------
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# ------------------------
# 学習
# ------------------------
epochs = 100

train_start = time.perf_counter()

for epoch in range(epochs):

    optimizer.zero_grad()

    outputs = model(X_train)

    loss = criterion(outputs, y_train)

    loss.backward()

    optimizer.step()

    if (epoch + 1) % 10 == 0:
        print(
            f"Epoch [{epoch+1}/{epochs}], "
            f"Loss: {loss.item():.4f}"
        )

train_end = time.perf_counter()
print(f"Training Time = {train_end-train_start:.6f} sec")

# ------------------------
# 評価
# ------------------------
model.eval()

with torch.no_grad():

    outputs = model(X_test)

    _, predicted = torch.max(outputs, 1)

    accuracy = (
        (predicted == y_test).sum().item()
        / len(y_test)
    )

print(f"Accuracy: {accuracy:.4f}")

# 平均推論時間の測定
N = 10000

sample = X_test[0].unsqueeze(0)

# warmup
for _ in range(100):
    model(sample)

start_inf = time.perf_counter()

with torch.no_grad():

    for _ in range(N):
        model(sample)

end_inf = time.perf_counter()

avg_time = (end_inf - start_inf) / N

print(f"Inference Time = {avg_time*1e6:.3f} us/sample")

PySAMACTでIris分類

コード(一部抜粋)

PyTorchと同様に、モデル作って、学習・推論する根幹の部分のみコードを提示します。

def main():
    # ------------------------
    # データの準備
    # ------------------------
    iris = load_iris()
    data:np.ndarray = np.array(iris.data)
    scaler = MinMaxScaler()
    normData = scaler.fit_transform(data)
    label:np.ndarray = np.array(iris.target)

    # 学習8:テスト2に分割。再現性のためにシードは固定。
    trainData, testData, trainLabel, testLabel = train_test_split(normData, label, test_size=0.2, random_state=0)

    # ------------------------
    # ニューラルネットワークの構築
    # ------------------------
    nN1 = 4
    nN2 = 16
    nN3 = 3

    # エンコーダの設定 (入力層)
    inputLayer = RateEncodeLayer(nN1)

    # SAMレイヤーの設定 (中間層・出力層)
    # ハイパーパラメータa=3, p=0.75を指定。
    # 重みの逆伝搬時の活性化関数にStep関数を指定。
    # 教師信号生成時の活性化関数にStep関数を指定。(前段はエンコーダなので利用されない)
    hiddenLayer = SAMLayer(nN2, LayerProperty(a=3, p=0.75), Step(), Step())

    # ハイパーパラメータa=3, p=0.75を指定。
    # 重みの逆伝搬時の活性化関数にStep関数を指定。
    # 教師信号生成時の活性化関数にStep関数を指定。
    outputLayer = SAMLayer(nN3, LayerProperty(a=3, p=0.75), Step(), Step())

    # デコーダの設定
    # 分類問題なので、出力パルスを多数決するデコーダを指定。
    decoder = MajorityDecodeLayer()

    # ニューラルネットワークの生成
    # 上記layerを渡してモデルを構築
    model = Sequential(inputLayer, decoder, [hiddenLayer, outputLayer])
    # 1データを32サイクルで処理するように設定。(ハイパーパラメータ)
    model.Compile(32)

    # ------------------------
    # 学習
    # ------------------------
    # 学習プロパティの設定
    # 学習率eta, iotaの初期値を5, 2に設定。2エポックごとに1減衰する。
    learnProperty = LearningProperty(eta=5, iota=2, decayPeriod=2)
    # 学習の実施
    fit_start = time.perf_counter()
    # 学習エポック数は20に設定。
    fitResult = model.Fit(trainData, trainLabel, 20, learnProperty)
    
    fit_end = time.perf_counter()
    print(f"Training Time = {fit_end-fit_start:.3f} sec")

    # 学習結果の保存
    # パラメータの学習結果を保存
    dumpName = f"iris_{nN1}_{nN2}_{nN3}_ntd{len(trainData)}_step.h5"
    model.Save(dumpName)

    # 1epoch目から20epochまでのの学習精度(正解率)のリスト
    print(fitResult.metrics)

    # ------------------------
    # 推論
    # ------------------------
    # テストデータに対する正解率
    evalResult = model.Evaluate(testData, testLabel)
    print(evalResult.metrics)
    
    # 平均推論時間の測定(N=10000)
    N = 10000
    for _ in range(100):
        model.Predict(testData[0])
    
    start_inf = time.perf_counter()
    for _ in range(N):
        model.Predict(testData[0])
        
    end_inf = time.perf_counter()
    avg_time = (end_inf - start_inf) / N
    
    print(f"Inference Time = {avg_time*1e6:.3f} us/sample")

評価結果

項目 PyTorch (20epoch) PyTorch (100epoch) PySAMACT (20epoch)
Accuracy 80.00% 93.33% 96.67%
Training Time [s] 0.015 0.068 15.785
Inference Time [μs/sample] 15.377 18.194 2255.992

分類精度比較

手法 Accuracy
PySAMACT (20epoch) 96.67%
PyTorch (100epoch) 93.33%
PyTorch (20epoch) 80.00%
  • PyTorchは20epochでは十分に収束していなかった。
    • 100epochまで学習させることで Accuracy が 80.0% → 93.3% に改善。
  • PySAMACTでもIris分類は十分可能であり、今回の条件では96.7%のAccuracyを達成した。
    • ただし、両者は学習アルゴリズムやハイパーパラメータが異なるため、本結果のみで優劣を判断できるものではない。

学習時間比較

手法 Training Time [s]
PyTorch (20epoch) 0.015
PyTorch (100epoch) 0.068
PySAMACT (20epoch) 15.785

PySAMACTに対する速度比

比較対象 学習速度倍率
PyTorch (20epoch) 約1052倍高速
PyTorch (100epoch) 約232倍高速

推論時間比較

手法 Inference Time [μs/sample]
PyTorch (20epoch) 15.377
PyTorch (100epoch) 18.194
PySAMACT (20epoch) 2255.992

PySAMACTに対する速度比

比較対象 推論速度倍率
PyTorch (20epoch) 約147倍高速
PyTorch (100epoch) 約124倍高速

総括

今回の実験では、PySAMACTは96.67%の分類精度を達成し、PyTorch(100epoch時)の93.33%を上回る結果となりました。

一方で、学習時間および推論時間についてはPyTorchが圧倒的に高速であり、学習・推論ともに2桁〜3桁程度の差が確認できました。

ただし、両者は学習アルゴリズムや設計思想が異なるため、今回の結果だけで単純な優劣を判断できるものではありません。

PyTorchは高速な学習・推論を実現するためにGPU活用や自動微分を前提として設計されています。

一方、PySAMACTは高速化を主目的としておらず、
ハードウェア実装時の挙動をPython上で再現しながら評価することを重視しています。

同じ分類問題を解いていても見ているゴールが異なります。

なお、今回の評価は両者ともCPU環境上で実施しています。

そのため、本記事はGPU性能とオンチップ性能を直接比較したものではなく、
GPU学習を前提として設計されたPyTorchと、
オンチップ学習を前提として設計されたPySAMACTの設計思想や利用目的の違いを比較したものになります。

最後に

今回、Irisデータセットを用いてPyTorchとPySAMACTの両方で分類タスクを試してみました。

結果として、両者とも "分類可能" でした。

しかし、実際に触ってみると、

  • PyTorchは「より良いモデルを効率良く作る」
  • PySAMACTは「将来どのようにデバイスへ実装するかを考える」

という違いが体感できました。

AIモデルを作ることが目的であればPyTorchは非常に強力な選択肢です。

一方で、

  • FPGA実装
  • ASIC実装
  • オンチップ学習
  • エンドポイントAI

といった領域に興味がある方にとっては、PySAMACTによるPoCも触ってみると面白いかもしれません。

本記事が、
GPU中心のAI開発とオンチップ学習を前提としたエンドポイントAI開発の違いを考えるきっかけになれば幸いです。

リンク集

リソース URL
GitHub(サンプル・ドキュメント・フォーラム) https://github.com/maviss-design/SAMACT
PyPI (パッケージ) https://pypi.org/project/samact/
弊社Webサイト https://maviss-design.com/
お問合せ https://maviss-design.com/contact/

ライセンス

AGPLv3を採用しています。研究・検証目的での利用を歓迎しますが、商用利用や量産用途をご検討の場合は別途お問合せください。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?