0
0

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→TensorFlow変換】ONNXモデルからTensorFlowモデルへ変換できない?よく詰まるポイントと対処法

Posted at

アイキャッチ

はじめに

転職活動中の近藤です。
物体検出モデルを「PyTorchで学習 → TensorFlowで推論」する流れに興味を持ち、
変換時にどこで詰まりやすいのか、どうすれば現実的に解決できるのかを調べています。

今回はPyTorchのモデルをTensorFlow形式に変換しようとして、ONNX変換でハマった経験からこの記事を書いています。

ONNXにできたからOK? → ではないんです ❌

PyTorch → ONNX は「柔軟」で変換できてしまうことが多く、
そのせいで「変換成功した!」と思ってしまいがちです。

でも、ONNX → TensorFlow(tf2onnxやonnx-tf)では
"変換できる演算子(Op)しか動かない" ため、ここでハマってしまうんですよね。

そんな時にはこんなエラーが出ます。

NotImplementedError: No conversion function for op: GridSample
ValueError: No converter found for op: NonMaxSuppression

「えっ、ONNXにはできたのに...」
という "変換落とし穴" に、ハマってしまった人も多いはずです。


この記事では、そうした ONNX → TensorFlow変換で詰まる原因 と、
特に物体検出モデルなどで問題になりやすい 演算子(Op)やopset_versionの選び方 について、
実際の変換失敗例やログ とあわせてわかりやすく整理します。


✅ この記事でわかること

  • モデル変換を成功させるための分析ステップ
  • TensorFlowで非対応なONNX演算子と対策
  • opset_versionは「一致させるべき」ではなく、目的別に選ぶべき理由
  • 実際の変換エラーログとその解決パターン

1. モデル分析から始める!変換前のチェックリスト✔️

変換エラーを避けるためには、まずモデルの中身を知ることが重要です。

✔️ おすすめの変換ステップ

  1. PyTorch → ONNX を opset=11, 12, 13 あたりで順番に試す

    torch.onnx.export(model, dummy_input, "model.onnx", opset_version=13)
    
  2. Netron でONNXモデルを確認

    • 使用されている演算子(op_type)を確認
    • 特に GridSample, Slice, Loop, If などの使用に注意
  3. tf2onnxの対応演算子 と照らし合わせる

    • サポート外のOpが含まれていないかを事前に確認する

2. よくある「変換NG」or「鬼門」なONNX演算子一覧💥

演算子(Op)名 よく使う場面 問題点 回避・対策
GridSample RoIAlign、DeformableConv TensorFlow未サポート 事前処理に切り出す or 削除・置換
NonMaxSuppression 検出後処理 TF Liteでも非対応/opset依存の挙動 モデル外処理として切り出す
Loop 条件付き処理、可変ステップ処理 動的制御構造がONNX→TFで通らない ループをunroll or 平坦化
If 学習・推論の分岐など TF変換で失敗しやすい 条件分岐を避け、常に同じ経路にする
Slice 特定領域の取り出し opsetで仕様が異なりバグりやすい opset 13以降推奨/Reshapeに変更
Reshape, Flatten 中間層整形 shapeが可変だと失敗 明示的に固定shapeを与える
ConstantOfShape 全体マスク生成など TensorFlowで非サポートなケースあり tf.fill などで置き換え

詳しくは公式のtf2onnxの対応演算子 の一覧をチェックしてください!


3. opset_versionは一致させなくてOK!でも選び方に注意⚠️

そもそも「opset_version」ってなに?

  • ONNXの中で使われる演算子仕様のバージョン
  • PyTorchとTensorFlowでは対応している範囲が違う!

💡 結論:opset_versionは“合わせる”より“目的に応じて選ぶ”

フェーズ 推奨されるopset戦略
PyTorch → ONNX モデルが変換できて必要な演算子が含まれる最小限のバージョン
ONNX → TensorFlow tf2onnxが対応しているバージョンで動作するかを確認

4. 実際の変換失敗ログと対応例

例:YOLO風モデル

  • PyTorch → ONNX(opset=17)では成功
  • でも GridSample, Slice-13 などが含まれていたため...

❌ 変換時に発生したエラーログ

NotImplementedError: No conversion function for op: GridSample
ValueError: No converter found for op: NonMaxSuppression

✔️ 対応策

  • モデルを変更して GridSample を削除 or 前処理に切り出し
  • NonMaxSuppression をモデル外に分離してTensorFlow側で実装

5. 安定した変換を実現するために

目的 実務での考え方
精度を維持した変換 PyTorch→ONNX の opset は必要最小限に。TFでの互換性を確認する
変換エラーの回避 ONNXモデルを見て、変換不能な演算子があるか先にチェック
安定運用 モデルごとに「安定する組み合わせ」を記録しておく

✍️ おわりに

物体検出モデルをPyTorch→TensorFlowへ変換するためには
TensorFlowへの変換を前提としたモデル設計が何より大切だと改めて感じました。

そのために何を想定して設計すべきかを知る手助けができたらいいなと思っていますので、これからも記事を書いていきます🌱
参考になった方は、いいね・ストック・フォローしてもらえると嬉しいです!


0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?