個人開発アプリTinyONNXViewer v1.0をリリース

# TL;DR
　今回、https://tinyonnxviewer.com にて機械学習モデルの情報をまとめたONNXファイル、中でも数層くらいからなるものすごい小さいONNXファイルを綺麗に可視化する個人開発アプリTinyONNXViewer v1.0をリリースしたので、こちらで告知させて頂き簡単に背景や所感も述べ、現状の課題なども共有させて頂きます。https://github.com/guard-mann/tinyonnxviewer.git がリポジトリになります。

<br>**例. NetronとTinyONNXViewerの比較図**

![スクリーンショット 2024-12-28 19.57.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/6d8b0fdc-f99e-4f5b-284f-66e6ef6cd018.png)


　 ↑ この画像の上パートは競合アプリと言ってもいい Netron[^1]のUIを示しており、下パートは今回リリースしたTinyONNXViewerのUIを示している。TinyONNXViewerは、レイヤー単位でアーキテクチャを描画してくれるNetronとは違って、もっと細かい粒度である<font color="Red">**ユニット単位**</font>でグラフを描画してくれる。あくまで現状このアプリは**すごく小さい2層か3層くらいの全結合からなるニューラルネットワークを想定**していることを念頭に置いて使って頂けると幸いである。

　 しかし、TinyONNXViewerは現状結構なクソアプリであることも伝えなければならない。世界中のユーザーをガッカリさせないためにも先にクソポイントを開示させて頂く。<br><br>

- **クソポイント1**：ノード数10（要は10層）以下の相当小さいアーキテクチャではユニークなUIを提供するが、10層以上のアーキテクチャではレイヤー単位での描画しか行わない上に、Netronよりも表示する情報が少なく、画像をそのままレンダリングさせているため質がNetronよりもはるかに低いUIを提供する(下に添付した例3.)<br><br>
- **クソポイント2**：10層以下のアーキテクチャに関して、ユニット単位でグラフ描画をしてくれるのは全結合層だけに限る。他のレイヤーはレイヤー単位でグラフ描画が行われる(下に添付した例2.)<br><br>
- **クソポイント3**：ONNXをアップロードしてから結果が返るまでが遅い。<br><br>

<br>**例2. (全結合層以外はレイヤー単位で描画)**

![スクリーンショット 2024-12-28 19.53.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/e8ab4270-c587-883a-8973-79c14bffa79f.png)

<br>**例3. (ONNX Model Zooに入っているような一般的なサイズのモデルだと質が低い)**

![スクリーンショット 2024-12-28 14.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/57768909-a477-cfd3-f607-2ff2059dbccb.png)

# 使い方
　このアプリは、ONNXを可視化する機能を有している。これはUI下部の`ファイルを選択`ボタンを押して、ONNXファイルを選択した後`ONNX Upload`というボタンを押すと、アップロードしたONNXファイルが描画される。ONNX以外は対応していない。2stepの操作が必要なあたり流石のクソアプリっぷりではあるのだが、ご容赦頂きたい。数層程度からなる極めて小さいTinyなONNXであれば綺麗に所望の描画ができる。

![スクリーンショット 2024-12-28 19.59.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/83e72953-3cbc-cc0b-9882-834bece1cdcc.png)


# ONNXって何？


　ONNXは機械学習モデルを格納する共通規格であり、主に推論で用いられるバイナリファイルである。例えば ONNX Model Zoo[^2] には汎用性の高い学習済みモデルをONNXファイルとして多数格納しており、タスク（Computer Vision/Natural Language Processing/Generative AI etc..）ごとにカテゴリ分けされてまとめられている。
 
![スクリーンショット 2024-12-28 13.56.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/58afc08b-e8b2-f1e5-d376-b32a57c1972c.png)

 この”規格”の優れたところは、互換性の高さである。機械学習のライブラリは多岐に渡っており、推論の際にライブラリを超えて使いまわせる規格としてONNXは最も優れたものであると言える。ONNXの公式サイト[^3]にはSUPPORTED FRAMEWORKSとして以下のような表示がなされている。

 ![スクリーンショット 2024-12-28 14.47.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/25cef0af-5f99-09de-4c1d-472c4e6a94e7.png)

このONNXという規格はバイナリファイル(*.onnx)で保管され、バイナリにまとめられる情報は、機械学習の推論に必要な情報が格納されている。アーキテクチャの情報、重みの情報、入力、出力次元の情報などが挙げられる。これさえあればPyTorch環境で学習させたモデルをTensorflow環境で推論させたりできてとても便利なのである。

# ブラックボックス化されがちな機械学習モデル
　機械学習モデルは（ONNXだろうが）どんなフォーマットで管理しようが、中で何が行われているのか、ブラックボックス化されがちである。それをクリアにするためのフレームワークはすでに多数存在している。例えば、PyTorchViZ[^4]やTorchView[^5]ではPyTorchで組まれている処理がどんなフローかを綺麗に描画してくれたり、TensorSensor[^6]ではNumpyやPyTorchの行列処理を可視化してくれる。
 
![スクリーンショット 2024-12-28 16.31.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/9b038ef9-46ef-2b56-2fb9-68e6bcf21744.png)

 
　こういう処理フローを可視化するツールは大量にあるが、ONNXの中身を見たい場合**Netron**というサービスを使うことが多い。これはブラウザからでもONNXファイルを見ることができる（アプリ版もある）。ONNXは１つの深層学習モデルの情報全てが入っており、Netronはその情報を(すべてではないが)確認できる。
 
 ![スクリーンショット 2024-12-28 15.29.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/0bfdd845-c6e1-1516-eed2-7b421200c307.png)

↑ 例えばこの図はNetronでONNX Model ZooのResNet18を可視化した例である。グラフ状にアーキテクチャの情報が描画され、大変わかりやすい。また、ノードをクリックすると、そのノードの属性情報も確認できる。ONNXの中身を確認したければ、大概の場合はNetronで事足りるのである。

　他にもこういう処理系統を可視化するツールはいくつかあるが、ONNXに関してはNetronがよく使われる。ちなみにNetronはONNX以外も描画することができる（.prototxtとか）。


# Netronでよくね？

正直そう。
 ただ、Netronは**あくまでレイヤーレベルでの処理のトラックしかできない**一方、ユニットレベルで情報を確認できると嬉しいこともある。例えば教科書でよくニューラルネットワークの説明をするときにユニットレベルの処理の様子を下図のような感じで記述する。これを実際に現場で使うことも多いONNXから推論させたりしながら確認することができると初学者にとっては少し嬉しい。
 
![スクリーンショット 2024-12-28 15.37.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/70777469-7442-0dcb-4e5a-eaad6d6a5498.png)

↑ Wikipediaで”ニューラルネットワーク”の記事で出てくるよく分からん図

　他にもDropoutの作用をさせた際に、ちゃんとワークしているかをトラックしたかったり、基礎的な解析をしたい場合であったり、ユニットレベルでニューラルネットワークを描画できると意外と嬉しいケースもあるのではないかと考えている。

　また今後の展開として、現状学習の際にエッジ重みがどう変化していくかを視覚的に把握したい場合に使えるようにしたいという構想もある。例えばこの優れた記事[^7]では学習過程でどうエッジ重みが変化していくかをかなり綺麗に描画してくれている。こういう描画がフレームワークを超えてもっと簡単にできるようになると大変嬉しい（未実装：今後の自分に期待）ので、エッジの太さと重みを対応づけるとかそういう拡張も進めていきたいと考えている。
 


# 一応、アプリ開発の流れと所感
使っている要素は以下の通り

・バックエンド（Java Spring）

・フロントエンド（React）

・構成（AWS EC2,ALB,S3）

所感：思ってたより金がかかる。


[^1]:URL : https://netron.app/
[^2]:URL : https://github.com/onnx/models.git
[^3]:URL : https://onnx.ai/
[^4]:URL : https://github.com/szagoruyko/pytorchviz.git
[^5]:URL : https://github.com/mert-kurttutan/torchview.git
[^6]:URL : https://github.com/parrt/tensor-sensor.git
[^7]:URL : https://qiita.com/gensal/items/4ee74531d22e3ba7a556