|
using System.Collections.Generic; |
|
using Unity.Sentis; |
|
using UnityEngine; |
|
using System.IO; |
|
using FF = Unity.Sentis.Functional; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class RunMobileNet : MonoBehaviour |
|
{ |
|
|
|
public ModelAsset modelAsset; |
|
|
|
const string modelName = "mobilenet_v2.sentis"; |
|
|
|
|
|
public Texture2D inputImage; |
|
|
|
|
|
public TextAsset labelsAsset; |
|
|
|
|
|
const int imageHeight = 224; |
|
const int imageWidth = 224; |
|
|
|
const BackendType backend = BackendType.GPUCompute; |
|
|
|
private IWorker engine; |
|
private string[] labels; |
|
|
|
|
|
TensorFloat mulRGB = new TensorFloat(new TensorShape(1, 3, 1, 1), new float[] { 1 / 0.229f, 1 / 0.224f, 1 / 0.225f }); |
|
TensorFloat shiftRGB = new TensorFloat(new TensorShape(1, 3, 1, 1), new float[] { 0.485f, 0.456f, 0.406f }); |
|
|
|
void Start() |
|
{ |
|
|
|
|
|
labels = labelsAsset.text.Split('\n'); |
|
|
|
|
|
|
|
var model = ModelLoader.Load(modelAsset); |
|
|
|
|
|
|
|
var model2 = FF.Compile( |
|
input => |
|
{ |
|
var probability = model.Forward(NormaliseRGB(input))[0]; |
|
return (FF.ReduceMax(probability, 1), FF.ArgMax(probability, 1)); |
|
}, |
|
model.inputs[0] |
|
); |
|
|
|
|
|
engine = WorkerFactory.CreateWorker(backend, model2); |
|
|
|
|
|
ExecuteML(); |
|
} |
|
|
|
public void ExecuteML() |
|
{ |
|
|
|
using var input = TextureConverter.ToTensor(inputImage, imageWidth, imageHeight, 3); |
|
|
|
|
|
engine.Execute(input); |
|
|
|
|
|
var probability = engine.PeekOutput("output_0") as TensorFloat; |
|
var item = engine.PeekOutput("output_1") as TensorInt; |
|
item.CompleteOperationsAndDownload(); |
|
probability.CompleteOperationsAndDownload(); |
|
|
|
|
|
var ID = item[0]; |
|
var accuracy = probability[0]; |
|
|
|
|
|
int percent = Mathf.FloorToInt(accuracy * 100f + 0.5f); |
|
Debug.Log($"Prediction: {labels[ID]} {percent}﹪"); |
|
|
|
|
|
Resources.UnloadUnusedAssets(); |
|
} |
|
|
|
|
|
FunctionalTensor NormaliseRGB(FunctionalTensor image) |
|
{ |
|
return (image - FunctionalTensor.FromTensor(shiftRGB)) * FunctionalTensor.FromTensor(mulRGB); |
|
} |
|
|
|
private void OnDestroy() |
|
{ |
|
mulRGB?.Dispose(); |
|
shiftRGB?.Dispose(); |
|
engine?.Dispose(); |
|
} |
|
} |
|
|