タイトルだけだと意味不明かもしれませんので正しく書くと、ONNX Runtimeで動作する「他の人が開発した」Inferencerから出力されるWarningを出なくする方法、です。
いきさつ
ONNXって便利ですよね。特にPyTorchユーザーにとっては結構重宝する場面があるのではないでしょうか。それはなぜって ? PyTorchでは基本的にモデルはプログラム上に記述されている前提があるからです。
torch.save()で直接保存できることにはなっていますが、環境の制限が厳しく事実上モデルクラスを定義しておかないと正しく動作しないと言ってよいでしょう。保存サイズ的にも有利なtorch.save(model.state_dict(), model_path)でパラメータのみ保存している人がほとんどではないでしょうか。
TorchScript を利用した方法がありますが、私の手元ではうまくいかなかったんですよね。モデルによるんだと思いますが、エラーに次ぐエラーでかなりはまってしまい、結局あきらめました。
torch.save にバイナリーストリームで保存する方法があるみたいですね。もしかしたらこれを利用すると依存関係なしにモデル全体を保存できるかも知れません。
一方TensorflowやONNXではモデル全体を簡単にファイルに保存できるため、ソースコード上にモデルそのものを書かなくてよい(もちろんモデルをロードしたあとにネットワークを解析することはできますから、「隠蔽」できているわけではありませんが)ので、自作のシステムを他人に使ってもらうときに、なんとなく心穏やかになります。なので、最近はPyTorchで開発してONNXにConvertして人に渡すことが多くなってきました。それはそうと…
話しが反れてしまいましたが、
逆に人が作ったONNXのモデルを使うことも多くなってきました。そんなとき、Warningがコンソールに出力されて困ったことがありました。tqdmでプログレスバーを表示して進行状況を表示していたりすると、予期しない改行が入って嫌ですよね。というわけで、他の人が開発したONNXベースのInferencerで期せずして出力されたWarningを抑制する方法についてご紹介したいと思います。
ことのいきさつは、
3DDFA_V2 でした。OpenFaceももちろん素晴らしいですが、こちらも高速に精度よく顔認識し、3D face surfaceや2D face landmarkを出力してくれます。顔が画像からはみ出したときの処理や、時間軸方向のFace landmarkの安定性はOpenFaceのほうが優れていると感じますが、3DDFAはライセンス的に比較的緩いのが使用する側からするととてもうれしいですね。
さて、そんな3DDFA_V2を動かしていたときのこと、動画での顔認識をしていると、最初だけなにやらWarningが出ています。こんな感じ。
2022-06-10 13:13:41.243344149 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {output_dynamic_axes_1,16680,4} does not match actual shape of {1,2046,4} for output output
まあ開始直後だけだしということで、最初は気にしていなかったのですが、顔の向きや動きによっては顔が検出できなくなったりするわけですが、使い込んでいくにつれ、そんなときにもできる限り速やかに正しい状態に復帰したい欲求にかられ、いろいろと中身に手を入れる必要が出てきました。
簡単に言ってしまうと、動画での顔認識の場合、検出モードとトラッキングモードを切り替えて動作させることが通常ですが、最初は検出モードでしっかり顔をとらえ、そのあとはトラッキングモードで緩く顔らしきものを追いかけ続けるような構成になります。
このとき、たまに外れる顔認識のリカバリーとしては、定期的に検出モードを入れて顔の検出が外れていないか確認するというのが常套手段です。というわけで1秒おきに検出モードを入れてみると…
なんと、
1秒おきに前期のWarningが出るようになってしまいました。こんな感じ。
Processing 54.2[1530/18001]: 54%|███████████████████████████████████████████▏ | 54/100 [01:26<07:46, 10.13s/it] 2022-06-10 13:13:42.375825424 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {1,16680,2} does not match actual shape of {1,2046,2} for output 353 2022-06-10 13:13:42.381382627 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {output_dynamic_axes_1,16680,4} does not match actual shape of {1,2046,4} for output output Processing 54.3[1560/18001]: 54%|███████████████████████████████████████████▏ | 54/100 [01:27<07:46, 10.13s/it]2022-06-10 13:13:43.490572588 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {1,16680,2} does not match actual shape of {1,2046,2} for output 353 2022-06-10 13:13:43.490719339 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {output_dynamic_axes_1,16680,4} does not match actual shape of {1,2046,4} for output output Processing 54.4[1590/18001]: 54%|███████████████████████████████████████████▏ | 54/100 [01:28<07:46, 10.13s/it]2022-06-10 13:13:44.667101540 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {1,16680,2} does not match actual shape of {1,2046,2} for output 353 2022-06-10 13:13:44.667295887 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {output_dynamic_axes_1,16680,4} does not match actual shape of {1,2046,4} for output output Processing 54.5[1620/18001]: 54%|███████████████████████████████████████████▏ | 54/100 [01:29<07:46, 10.13s/it] 2022-06-10 13:13:45.796876353 [W:onnxruntime:, execution_frame.cc:770 VerifyOutputSizes] Expected shape from model of {1,16680,2} does not match actual shape of {1,2046,2} for output 353
そしてこれはさすがに何とかしたいな、となったわけです。
最初はstderr出力をコンソールに出さないようにするには… みたいな方向でいろいろ試してみたのですがうまく行かず。結構途方に暮れていたのですが、別件でONNX Runtimeのドキュメントを読んでいたところ、
SessionOptions
class onnxruntime.SessionOptions(self: onnxruntime.capi.onnxruntime_pybind11_state.SessionOptions) → None
Configuration information for a session.
:
property log_severity_level
Log severity level. Applies to session load, initialization, etc. 0:Verbose, 1:Info, 2:Warning. 3:Error, 4:Fatal. Default is 2.
:
SessionOptionsにlog_severity_levelというのがあるではありませんか !
というわけで、
以下のようにInferenceSessionでlog_severity_levelを引き上げてoptionsも呼ぶようにしたところ…
options = onnxruntime.SessionOptions() options.log_severity_level = 4 session = onnxruntime.InferenceSession(onnx_path, options)
Warningが出なくなりました ! めでたしめでたし。