はじめに
転職活動中の近藤です。
物体検出モデルを「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. モデル分析から始める!変換前のチェックリスト✔️
変換エラーを避けるためには、まずモデルの中身を知ることが重要です。
✔️ おすすめの変換ステップ
-
PyTorch → ONNX を opset=11, 12, 13 あたりで順番に試す
torch.onnx.export(model, dummy_input, "model.onnx", opset_version=13)
-
Netron でONNXモデルを確認
- 使用されている演算子(op_type)を確認
- 特に
GridSample
,Slice
,Loop
,If
などの使用に注意
-
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への変換を前提としたモデル設計が何より大切だと改めて感じました。
そのために何を想定して設計すべきかを知る手助けができたらいいなと思っていますので、これからも記事を書いていきます🌱
参考になった方は、いいね・ストック・フォローしてもらえると嬉しいです!