|
using Unity.InferenceEngine; |
|
using UnityEngine; |
|
|
|
public class RunMobileNet : MonoBehaviour |
|
{ |
|
public ModelAsset modelAsset; |
|
|
|
|
|
public Texture2D inputImage; |
|
|
|
|
|
public TextAsset labelsAsset; |
|
|
|
|
|
Tensor<float> input = new Tensor<float>(new TensorShape(1, 3, 224, 224)); |
|
|
|
const BackendType backend = BackendType.GPUCompute; |
|
|
|
Worker worker; |
|
string[] labels; |
|
|
|
|
|
Tensor<float> mulRGB = new Tensor<float>(new TensorShape(1, 3, 1, 1), new[] { 1 / 0.229f, 1 / 0.224f, 1 / 0.225f }); |
|
Tensor<float> shiftRGB = new Tensor<float>(new TensorShape(1, 3, 1, 1), new[] { 0.485f, 0.456f, 0.406f }); |
|
|
|
void Start() |
|
{ |
|
|
|
labels = labelsAsset.text.Split('\n'); |
|
|
|
|
|
var model = ModelLoader.Load(modelAsset); |
|
|
|
|
|
|
|
var graph = new FunctionalGraph(); |
|
var image = graph.AddInput(model, 0); |
|
var normalizedInput = (image - Functional.Constant(shiftRGB)) * Functional.Constant(mulRGB); |
|
var probability = Functional.Forward(model, normalizedInput)[0]; |
|
var value = Functional.ReduceMax(probability, 1); |
|
var index = Functional.ArgMax(probability, 1); |
|
graph.AddOutput(value, "value"); |
|
graph.AddOutput(index, "index"); |
|
var model2 = graph.Compile(); |
|
|
|
|
|
worker = new Worker(model2, backend); |
|
|
|
|
|
ExecuteML(); |
|
} |
|
|
|
public void ExecuteML() |
|
{ |
|
|
|
TextureConverter.ToTensor(inputImage, input); |
|
|
|
|
|
worker.Schedule(input); |
|
|
|
|
|
using var value = (worker.PeekOutput("value") as Tensor<float>).ReadbackAndClone(); |
|
using var index = (worker.PeekOutput("index") as Tensor<int>).ReadbackAndClone(); |
|
|
|
|
|
var accuracy = value[0]; |
|
var ID = index[0]; |
|
|
|
|
|
int percent = Mathf.FloorToInt(accuracy * 100f + 0.5f); |
|
Debug.Log($"Prediction: {labels[ID]} {percent}﹪"); |
|
|
|
|
|
Resources.UnloadUnusedAssets(); |
|
} |
|
|
|
void OnDestroy() |
|
{ |
|
input?.Dispose(); |
|
mulRGB?.Dispose(); |
|
shiftRGB?.Dispose(); |
|
worker?.Dispose(); |
|
} |
|
} |
|
|