Closed8
Unity Barracudaについてぼちぼち調査をしてみる

調査理由
これから開発でニューラルネットワークをUnityに組み込みたいから調査
参考記事、サイト

動画を見た学び
Tensorflowなどのニューラルネットワーク→ONNX→Unity Barracudaの順の開発って考えるとタスク整理のイメージがつく
マシンパワーがあればComputePrecomplied
全プラットフォームに対応させたいのであればCSharp C#実装(IL2CPP)
ONNXがうまく動くモデルは多くない
- 互換性
- ONNX opsetの整合性
- 未対応オペレーター
- カスタムオペレーター
- 未実装機能・バグ

公開されている処理を読み解いてみる
こんな感じのシーンがあって、
インスペクター上で代入した画像に対して予測される数字の確率が表示されている。
典型的なsoftmaxを用いた全確率出す系のタイプっぽい挙動をしていた

ソースコードを読んでみる
流れはざっくり入力を作る→NNに入れて出力を持ってくる→UI表示
入力
using var input = new Tensor(1, 28, 28, 1);
for (var y = 0; y < 28; y++)
{
for (var x = 0; x < 28; x++)
{
var tx = x * _image.width / 28;
var ty = y * _image.height / 28;
input[0, 27 - y, x, 0] = _image.GetPixel(tx, ty).grayscale;
}
}
これなんで1,28,28(枚数、縦、横)じゃないんだろう?
入力がそう制限されているから?
画像から一ピクセルずつ持ってきてグレースケールにしてfloat型で代入しているっぽい。
NNに入れて出力を持ってくる
using var worker =
ModelLoader.Load(_model).CreateWorker(WorkerFactory.Device.CPU);
worker.Execute(input);
// Inspect the output tensor.
var output = worker.PeekOutput();
入力して特にawaitとかしなくても取ってこれるのだろうか
これはさすがに同期処理だからUpdate化するときは非同期処理なのだろうか
出力
var scores = Enumerable.Range(0, 10).
Select(i => output[0, 0, 0, i]).SoftMax().ToArray();
// Show the results on the UI.
_imageView.texture = _image;
_textView.text = Enumerable.Range(0, 10).
Select(i => $"{i}: {scores[i]:0.00}").
Aggregate((t, s) => t + "\n" + s);
ちなみにソフトマックス関数は独自で実装されていた。
対応がうまくいかない場合Unity上で自作するみたいな逃げ方もある

明日はこれについてみてみる

識別された!
動画を入れてみてもリアルタイムでマーカー表示された

クラスは3つ
Visualizer.cs
Marker.cs
IndirectDraw.cs

Visualizer.cs
ここでUpdate内でマーカーの管理をしているっぽい
void Update()
{
_detector.ProcessImage(_source.Texture, _threshold);
var i = 0;
foreach (var d in _detector.Detections)
{
if (i == _markers.Length) break;
_markers[i++].SetAttributes(d);
}
for (; i < _markers.Length; i++) _markers[i].Hide();
_preview.texture = _source.Texture;
}
このスクラップは2023/12/01にクローズされました