| 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(); |
| } |
| } |
|
|