{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "collapsed_sections": [],
      "authorship_tag": "ABX9TyN5C7ksmPxMRl+1Zjtfz39p",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/gist/ZackAkil/d1a7987b764c8f4cbcb2715db712bfb9/automl-edge-tflite-metadata.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!wget  https://storage.googleapis.com/automl-demo-misc/model-5586077621008990208/tflite/2022-11-05T12%3A56%3A46.449246Z/model.tflite"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "96Q74FQLz1gY",
        "outputId": "c60f2215-84ac-4cf0-dee3-da2ac4629a4f"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--2022-11-07 11:18:21--  https://storage.googleapis.com/automl-demo-misc/model-5586077621008990208/tflite/2022-11-05T12%3A56%3A46.449246Z/model.tflite\n",
            "Resolving storage.googleapis.com (storage.googleapis.com)... 172.253.122.128, 172.253.63.128, 142.251.111.128, ...\n",
            "Connecting to storage.googleapis.com (storage.googleapis.com)|172.253.122.128|:443... connected.\n",
            "HTTP request sent, awaiting response... 200 OK\n",
            "Length: 5853661 (5.6M) [application/octet-stream]\n",
            "Saving to: ‘model.tflite’\n",
            "\n",
            "model.tflite        100%[===================>]   5.58M  --.-KB/s    in 0.1s    \n",
            "\n",
            "2022-11-07 11:18:21 (39.8 MB/s) - ‘model.tflite’ saved [5853661/5853661]\n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!pip3 install --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "zjK_M37P0IAI",
        "outputId": "29d5e3af-f434-4920-dcb5-ba67a9878b8f"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/, https://google-coral.github.io/py-repo/\n",
            "Collecting tflite_runtime\n",
            "  Downloading tflite_runtime-2.10.0-cp37-cp37m-manylinux2014_x86_64.whl (2.5 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.5 MB 16.2 MB/s \n",
            "\u001b[?25hRequirement already satisfied: numpy>=1.19.2 in /usr/local/lib/python3.7/dist-packages (from tflite_runtime) (1.21.6)\n",
            "Installing collected packages: tflite-runtime\n",
            "Successfully installed tflite-runtime-2.10.0\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import tflite_runtime.interpreter as tflite"
      ],
      "metadata": {
        "id": "fQXcwoCxz-6N"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "TFAVJsevzxkq"
      },
      "outputs": [],
      "source": [
        "model_path = 'model.tflite'\n",
        "interpreter = tflite.Interpreter(model_path)"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "interpreter"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "97QWoCve0M8C",
        "outputId": "28663fe9-9bdf-4a88-ec73-7b39bc74e521"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<tflite_runtime.interpreter.Interpreter at 0x7f32152901d0>"
            ]
          },
          "metadata": {},
          "execution_count": 5
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "interpreter.get_input_details()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "H5zfwxf50P3x",
        "outputId": "ac1ec0d9-cf8f-418d-fc84-b2baea7eee76"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[{'name': 'image',\n",
              "  'index': 0,\n",
              "  'shape': array([  1, 224, 224,   3], dtype=int32),\n",
              "  'shape_signature': array([  1, 224, 224,   3], dtype=int32),\n",
              "  'dtype': numpy.uint8,\n",
              "  'quantization': (0.007874015718698502, 128),\n",
              "  'quantization_parameters': {'scales': array([0.00787402], dtype=float32),\n",
              "   'zero_points': array([128], dtype=int32),\n",
              "   'quantized_dimension': 0},\n",
              "  'sparsity_parameters': {}}]"
            ]
          },
          "metadata": {},
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "interpreter.get_output_details()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xjO8JHRP0SnG",
        "outputId": "0e8e096e-6aa3-4ae8-aaa7-f79e8da3057e"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[{'name': 'scores',\n",
              "  'index': 172,\n",
              "  'shape': array([1, 3], dtype=int32),\n",
              "  'shape_signature': array([1, 3], dtype=int32),\n",
              "  'dtype': numpy.uint8,\n",
              "  'quantization': (0.00390625, 0),\n",
              "  'quantization_parameters': {'scales': array([0.00390625], dtype=float32),\n",
              "   'zero_points': array([0], dtype=int32),\n",
              "   'quantized_dimension': 0},\n",
              "  'sparsity_parameters': {}}]"
            ]
          },
          "metadata": {},
          "execution_count": 7
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install tflite-support"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 680
        },
        "id": "aIJj-WTq1syN",
        "outputId": "50315b93-0d65-42b5-acf2-7fadc0055c17"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
            "Collecting tflite-support\n",
            "  Downloading tflite_support-0.4.3-cp37-cp37m-manylinux2014_x86_64.whl (60.9 MB)\n",
            "\u001b[K     |████████████████████████████████| 60.9 MB 1.2 MB/s \n",
            "\u001b[?25hCollecting protobuf<4,>=3.18.0\n",
            "  Downloading protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.0 MB)\n",
            "\u001b[K     |████████████████████████████████| 1.0 MB 50.8 MB/s \n",
            "\u001b[?25hRequirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from tflite-support) (1.3.0)\n",
            "Collecting pybind11>=2.6.0\n",
            "  Downloading pybind11-2.10.1-py3-none-any.whl (216 kB)\n",
            "\u001b[K     |████████████████████████████████| 216 kB 48.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: numpy>=1.20.0 in /usr/local/lib/python3.7/dist-packages (from tflite-support) (1.21.6)\n",
            "Collecting flatbuffers>=2.0\n",
            "  Downloading flatbuffers-22.10.26-py2.py3-none-any.whl (26 kB)\n",
            "Collecting sounddevice>=0.4.4\n",
            "  Downloading sounddevice-0.4.5-py3-none-any.whl (31 kB)\n",
            "Requirement already satisfied: CFFI>=1.0 in /usr/local/lib/python3.7/dist-packages (from sounddevice>=0.4.4->tflite-support) (1.15.1)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from CFFI>=1.0->sounddevice>=0.4.4->tflite-support) (2.21)\n",
            "Installing collected packages: sounddevice, pybind11, protobuf, flatbuffers, tflite-support\n",
            "  Attempting uninstall: protobuf\n",
            "    Found existing installation: protobuf 3.17.3\n",
            "    Uninstalling protobuf-3.17.3:\n",
            "      Successfully uninstalled protobuf-3.17.3\n",
            "  Attempting uninstall: flatbuffers\n",
            "    Found existing installation: flatbuffers 1.12\n",
            "    Uninstalling flatbuffers-1.12:\n",
            "      Successfully uninstalled flatbuffers-1.12\n",
            "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "tensorflow 2.9.2 requires flatbuffers<2,>=1.12, but you have flatbuffers 22.10.26 which is incompatible.\n",
            "tensorflow 2.9.2 requires protobuf<3.20,>=3.9.2, but you have protobuf 3.20.3 which is incompatible.\n",
            "tensorboard 2.9.1 requires protobuf<3.20,>=3.9.2, but you have protobuf 3.20.3 which is incompatible.\u001b[0m\n",
            "Successfully installed flatbuffers-22.10.26 protobuf-3.20.3 pybind11-2.10.1 sounddevice-0.4.5 tflite-support-0.4.3\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.colab-display-data+json": {
              "pip_warning": {
                "packages": [
                  "google"
                ]
              }
            }
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from tflite_support import metadata"
      ],
      "metadata": {
        "id": "ik8mwF320U5W"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "displayer = metadata.MetadataDisplayer.with_model_file(model_path)"
      ],
      "metadata": {
        "id": "iLFH50q31_QV"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "print(displayer.get_metadata_json())"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "HHILNeU02BvM",
        "outputId": "56237d30-fd02-48d4-a78f-059ab3cab8c5"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{\n",
            "  \"name\": \"Image Classification Model\",\n",
            "  \"description\": \"Model built using AutoML Vision\",\n",
            "  \"subgraph_metadata\": [\n",
            "    {\n",
            "      \"input_tensor_metadata\": [\n",
            "        {\n",
            "          \"name\": \"image\",\n",
            "          \"description\": \"Input image to be classified. The expected image is 224 x 224, with three channels (red, blue, and green) per pixel. Each value in the tensor is a single byte between 0 and 255.\",\n",
            "          \"content\": {\n",
            "            \"content_properties_type\": \"ImageProperties\",\n",
            "            \"content_properties\": {\n",
            "              \"color_space\": \"RGB\"\n",
            "            }\n",
            "          },\n",
            "          \"process_units\": [\n",
            "            {\n",
            "              \"options_type\": \"NormalizationOptions\",\n",
            "              \"options\": {\n",
            "                \"mean\": [\n",
            "                  127.5\n",
            "                ],\n",
            "                \"std\": [\n",
            "                  127.5\n",
            "                ]\n",
            "              }\n",
            "            }\n",
            "          ],\n",
            "          \"stats\": {\n",
            "            \"max\": [\n",
            "              255.0\n",
            "            ],\n",
            "            \"min\": [\n",
            "              0.0\n",
            "            ]\n",
            "          }\n",
            "        }\n",
            "      ],\n",
            "      \"output_tensor_metadata\": [\n",
            "        {\n",
            "          \"name\": \"scores\",\n",
            "          \"description\": \"Probabilities of the labels.\",\n",
            "          \"content\": {\n",
            "            \"content_properties_type\": \"FeatureProperties\"\n",
            "          },\n",
            "          \"stats\": {\n",
            "            \"max\": [\n",
            "              1.0\n",
            "            ],\n",
            "            \"min\": [\n",
            "              0.0\n",
            "            ]\n",
            "          },\n",
            "          \"associated_files\": [\n",
            "            {\n",
            "              \"name\": \"dict.txt\",\n",
            "              \"description\": \"Labels for objects that the model can recognize.\",\n",
            "              \"type\": \"TENSOR_AXIS_LABELS\"\n",
            "            }\n",
            "          ]\n",
            "        }\n",
            "      ]\n",
            "    }\n",
            "  ],\n",
            "  \"min_parser_version\": \"1.0.0\"\n",
            "}\n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from tflite_support import metadata\n",
        "import zipfile"
      ],
      "metadata": {
        "id": "LAc-95Lb2MVi"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model_file = 'model.tflite'\n",
        "\n",
        "def get_labels_from_tflite(model_file_name, format=0):\n",
        "  '''\n",
        "  Unpack the metadata from a tflite model and return the first associated file \n",
        "  which is assumed to be the label file within AutoML edge models\n",
        "  input : str (model file name), int (formate 0=list, 1=dict)\n",
        "  output : str (text from labels file)\n",
        "  '''\n",
        "\n",
        "  displayer = metadata.MetadataDisplayer.with_model_file(model_file_name)\n",
        "  associate_files= displayer.get_packed_associated_file_list()\n",
        "  resource_file = associate_files[0]\n",
        "  archive = zipfile.ZipFile(model_file_name, 'r')\n",
        "  labels = archive.read(resource_file).decode().split('\\n')\n",
        "\n",
        "  if format == 1:\n",
        "    labels = {i:label  for (i, label) in enumerate(labels)}\n",
        "\n",
        "  return labels\n",
        "\n",
        "print(get_labels_from_tflite(model_file))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4ctlXDcc0HN0",
        "outputId": "ccfc1443-43db-41c8-a778-817615eaed07"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "cirrus\n",
            "cumulus\n",
            "cumulonimbus\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Gus' metadata reader"
      ],
      "metadata": {
        "id": "XIbd_7Ec0Q1C"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!wget https://raw.githubusercontent.com/gustheman/metadata_viewer/master/metadata_viewer.py"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "T1MxE-8B0Trb",
        "outputId": "42609e31-15fe-44a3-a1e3-f7219f5115f7"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--2022-11-07 11:19:53--  https://raw.githubusercontent.com/gustheman/metadata_viewer/master/metadata_viewer.py\n",
            "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.108.133, ...\n",
            "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n",
            "HTTP request sent, awaiting response... 200 OK\n",
            "Length: 2131 (2.1K) [text/plain]\n",
            "Saving to: ‘metadata_viewer.py’\n",
            "\n",
            "\rmetadata_viewer.py    0%[                    ]       0  --.-KB/s               \rmetadata_viewer.py  100%[===================>]   2.08K  --.-KB/s    in 0s      \n",
            "\n",
            "2022-11-07 11:19:53 (28.8 MB/s) - ‘metadata_viewer.py’ saved [2131/2131]\n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!python metadata_viewer.py --model_file=model.tflite --appended_resource_id=0"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "IuWFUpwT0XZy",
        "outputId": "a0e390be-dd7c-415c-a29e-833467de74b5"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "2022-11-07 11:22:14.010709: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected\n",
            "cirrus\n",
            "cumulus\n",
            "cumulonimbus\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "hMLg-9kq0g-s"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}