⊂二二二( ^ω^)二⊃ブーン
この記事ではBarracudaについてざっくり理解してから、上のように遊んでみます
Unityはある程度触れるけどBarracudaは知らない人向けの内容です
Barracudaとは
- Unityの機械学習パッケージの1つ
- Unity上で動作するONNXランタイム
- ONNX : 機械学習モデルの共通ファイルフォーマット
.onnx
- 生成した学習モデルをONNX形式で出力することで、様々なランタイムで使いまわせる
- Homeページ : https://onnx.ai/
- ONNX : 機械学習モデルの共通ファイルフォーマット
- 機械学習のプロセスでいう「推論」の部分を担う (下図参照)
- NETORONに対応しており、UnityにインポートしたONNXファイルをダブルクリックするとNETORONで開ける
- NETORON : ニューラルネットの視覚化ツール
- Gitリポジトリ : https://github.com/lutzroeder/netron
- NETORON : ニューラルネットの視覚化ツール
Hello World
こちらを利用して、MNISTによる手書き数字の推論をやってみる
https://github.com/keijiro/MnistBarracuda
MNISTとは
- 手書き数字画像の大規模なデータベース
- 手書き数字がどの数字か推論するための学習モデルとして使える
- Wikipedia : https://ja.wikipedia.org/wiki/MNIST
手順
- クローンする
$git clone git@github.com:keijiro/MnistBarracuda.git
- Unityで開く
- MnistTestシーンを開く
Assets/MnistTest.unity
- シーンを実行すると、推論結果が表示される
コードを読む
// Convert the input image into a 1x28x28x1 tensor.
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;
}
}
- 入力画像
_image
をテンソルTensor
に変換する処理- テンソル = 多次元配列
- 機械学習の分野ではy軸方向が上から下、UnityのUV座標のV軸方向は下から上なので、yを反転させている
- モデルに入力するテンソルの形式はONNXファイルのインスペクタで確認可能 (下の画像参照)
- n:バッチサイズ, h:高さ, w:幅, c:チャネル数
- チャネル数1 = グレースケール、チャネル数3 = RGB画像
// Run the MNIST model.
using var worker =
ModelLoader.Load(_model).CreateWorker(WorkerFactory.Device.CPU);
worker.Execute(input);
- MNISTの学習モデルを元に推論を行う
-
worker
はIDisposable
-
CreateWorker
メソッドの第一引数でCPU/GPU実行を指定可能 ここではCPUを指定
// Inspect the output tensor.
var output = worker.PeekOutput();
var scores = Enumerable.Range(0, 10).
Select(i => output[0, 0, 0, i]).SoftMax().ToArray();
-
worker
から推論結果output
を取得し、0~9のそれぞれのスコアを配列scores
に格納 -
SoftMax()
メソッドは受け取ったIEnumerableの全要素を0~1に正規化した値に変換
SoftMax.cs
public static IEnumerable<float> SoftMax(this IEnumerable<float> source)
{
var exp = source.Select(x => Mathf.Exp(x)).ToArray();
var sum = exp.Sum();
return exp.Select(x => x / sum);
}
補足など
- Mnistのテンソルは(1,28,28,1)と小さいためCPU側で作成しても問題ないが、基本的にはComputeShaderを利用してGPU側で処理した方がいい
- BarracudaとONNXファイルを利用すれば、ユーザーがするのはモデルの入出力データの整形くらい
- ONNXファイルはいろいろなものが公開されてるので探してみるといい
- "model zoo" で検索するとたくさんでてくる
- 実際にはそのままでは動作させられないONNXの方が多いらしい
- Barracuda未対応の機能を利用している場合、ONNXの修正で動作させられる場合もある
- ONNXファイルはいろいろなものが公開されてるので探してみるといい
遊んでみた
Barracudaについてざっくり理解したので、次は遊んでみます
こちらを利用 (またしてもkeijiroさん)
https://github.com/keijiro/UltraFaceBarracuda
手順
- クローンする
$git clone git@github.com:keijiro/UltraFaceBarracuda.git
- Unityで開く
- こちらの画像をDLしてプロジェクトにimport
-
Assets/Marker/SunglassesMarker.prefab
を複製し、パラメータを変更
RectTransform > Scale : (2,2,2)
RawImage > Texture : 先ほどimportした画像 - Visualizerシーンを開く
Assets/Visualizer.unity
- シーン上の
Webcam Test
オブジェクトを有効にし、パラメータを変更
Visualizer > Marker Prefab : 先ほど作成したPrefab
WebcamInput > DeviceName : 右のSelect
を押し、プルダウンから入力デバイスを選択 - シーンを実行
補足など
- 先ほどの後Mnistと異なり、UltraFaceBarracudaではGPU(ComputeShader)でモデルの入出力データを整形している
- ONNXファイル :
Packages/UltraFace/ONNX
- ComputeShader :
Packages/UltraFace/Shader
- ONNXファイル :
- 各クラスについてざっくり
- Visualizer : FaceDetectorの作成/更新
- FaceDetector : ComputeBufferの作成/破棄、モデル実行と前後処理のコンピュートシェーダ実行
- ResourceSet : FaceDetectorで実行するONNXファイルと、その入出力データに対して実行するGPU処理(コンピュートシェーダ)の参照を持つ
- Detection : UltraFaceによる推論結果情報をもつ構造体
- SunglassesUpdater : Detectionに応じた位置にサングラスを表示する更新処理
最後に
簡単に Barracuda x 機械学習 で遊ぶことができました
機械学習を知らなくてもゲームは作れるし、なんとなく難しそうだったので敬遠してきましたが、今回触れてみて一気に身近に感じるようになりました
ゲーム x 機械学習 でどんなことができるか、考えてみようと思います
参考
keijiroさんによるBarracuda紹介動画
ぶっちゃけこの動画見た方がはy (ry
- Unity Barracudaを使用したONNXニューラルネットワークモデルのマルチプラットフォーム運用 - CEDEC2021
- [ニューラルネットで何でもできちゃう!?Unity Barracudaで遊ぼう!] (https://learning.unity3d.jp/6932/)