{"id":261546,"date":"2024-10-03T01:07:29","date_gmt":"2024-10-03T01:07:29","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2024\/10\/03\/pytorch-machine-learning-models-on-android\/"},"modified":"2025-06-25T17:11:00","modified_gmt":"2025-06-25T17:11:00","slug":"pytorch-machine-learning-models-on-android","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2024\/10\/03\/pytorch-machine-learning-models-on-android\/","title":{"rendered":"PyTorch machine learning models on Android"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZjxrgmFgqtFucZ9AOr-KC-kNPi_JJoZVAOHolxpuJkhA3wzmxmxV8wi-bkxEzlggzJ8Wjk_oPl40ljl5BD3-EqIT2iQUlXRnIWGI-rlX65bPE6p9HHm1LAp4ovJ05F_OzBhPyiqpOL0BN1QLEQg-SnY5Aie3phGU76QXEjEs5_KuaaKTA6vcEUbUQdnM\/s1600\/AI-on-Android-Google-AI-Edge-Social.png\" name=\"twitter:image\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZjxrgmFgqtFucZ9AOr-KC-kNPi_JJoZVAOHolxpuJkhA3wzmxmxV8wi-bkxEzlggzJ8Wjk_oPl40ljl5BD3-EqIT2iQUlXRnIWGI-rlX65bPE6p9HHm1LAp4ovJ05F_OzBhPyiqpOL0BN1QLEQg-SnY5Aie3phGU76QXEjEs5_KuaaKTA6vcEUbUQdnM\/s1600\/AI-on-Android-Google-AI-Edge-Social.png\" style=\"display: none;\"\/><\/p>\n<p><em>Posted by Paul Ruiz \u2013 Senior Developer Relations Engineer<\/em><\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjBlnDoRECljZdnZDWoxF5TfurA_Y8_5zfLBqAniIsAhSNHKMhmmZDuOqfJ3-FWSqPRBOzDZD-931BmgGWwJavtzn_BTCvMNyqirYnISrWLyr3fQEhWARziFQP2dWrMpIJnX_Z7EZSIaAnr4PK9M9EAzHWAqR7s36zY2p2pHXSLhVH1UdTWA0CJeOB82GI\/s1600\/AI-on-Android-Google-AI-Edge%20%285%29.png\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjBlnDoRECljZdnZDWoxF5TfurA_Y8_5zfLBqAniIsAhSNHKMhmmZDuOqfJ3-FWSqPRBOzDZD-931BmgGWwJavtzn_BTCvMNyqirYnISrWLyr3fQEhWARziFQP2dWrMpIJnX_Z7EZSIaAnr4PK9M9EAzHWAqR7s36zY2p2pHXSLhVH1UdTWA0CJeOB82GI\/s1600\/AI-on-Android-Google-AI-Edge%20%285%29.png\"\/><\/a><\/p>\n<p>Earlier this year we launched <a href=\"https:\/\/ai.google.dev\/edge\" target=\"_blank\" rel=\"noopener\">Google AI Edge<\/a>, a suite of tools with easy access to ready-to-use ML tasks, frameworks that enable you to build ML pipelines, and run popular LLMs and custom models \u2013 all on-device. For AI on Android Spotlight Week, the Google team is highlighting various ways that Android developers can use machine learning to help improve their applications.<\/p>\n<p>In this post, we&#8217;ll dive into Google AI Edge Torch, which enables you to convert PyTorch models to run locally on Android and other platforms, using the Google AI Edge <a href=\"https:\/\/developers.googleblog.com\/en\/tensorflow-lite-is-now-litert\/\" target=\"_blank\" rel=\"noopener\">LiteRT<\/a> (formerly TensorFlow Lite) and <a href=\"https:\/\/ai.google.dev\/edge\/mediapipe\/solutions\/tasks\" target=\"_blank\" rel=\"noopener\">MediaPipe Tasks<\/a> libraries. For insights on other powerful tools, be sure to explore the rest of the  <a href=\"https:\/\/android-developers.googleblog.com\/2024\/09\/welcome-to-ai-on-android-spotlight-week.html\" target=\"_blank\" rel=\"noopener\">AI on Android Spotlight Week<\/a> content.<\/p>\n<p>To get started with Google AI Edge easier, we&#8217;ve provided <a href=\"https:\/\/github.com\/google-ai-edge\/models-samples\/tree\/main\/convert_pytorch\" target=\"_blank\" rel=\"noopener\">samples<\/a> available on GitHub as an executable codelab. They demonstrate how to convert the <a href=\"https:\/\/huggingface.co\/apple\/mobilevit-small\" target=\"_blank\" rel=\"noopener\">MobileViT<\/a> model for image classification (compatible with MediaPipe Tasks) and the <a href=\"https:\/\/github.com\/xuebinqin\/DIS\" target=\"_blank\" rel=\"noopener\">DIS<\/a> model for segmentation (compatible with LiteRT).<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"a red Android figurine is shown next to a black and white silhouette of the same figure, labeled 'Original Image' and 'PT Mask' respectively, demonstrating image segmentation.\" border=\"0\" height=\"267\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgaJcGDf2XurjFZFuAX272fP7qqiSnNulbaQ3aG_SUALgpdWObCDeTB11yFuuZkoKqiKrI1uKJ-XikdofnlsaPGnbJcpp57cuJGGGywa5xZtuqcfazeWGJSTCfGWM3JeyG6tXpe9kPUKhBqBksvQKL7871VKX_ypCE_0b_qa_Ecn_-tMOR3WYontiJoLyM\/w640-h267\/image1.png\" width=\"80%\"\/><\/div>\n<p><imgcaption><center><em>DIS model output<\/em><\/center><\/imgcaption><\/image><\/p>\n<p>This blog guides you through how to use the MobileViT model with MediaPipe Tasks. Keep in mind that the LiteRT runtime provides similar capabilities, enabling you to build custom pipelines and features.<\/p>\n<h3>Convert MobileViT model for image classification compatible with MediaPipe Tasks<\/h3>\n<p>Once you&#8217;ve installed the necessary dependencies and utilities for your app, the first step is to retrieve the PyTorch model you wish to convert, along with any other MobileViT components you might need (such as an image processor for testing).<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">from transformers import MobileViTImageProcessor, MobileViTForImageClassification\n\nhf_model_path=\"apple\/mobilevit-small\"\nprocessor = MobileViTImageProcessor.from_pretrained(hf_model_path)\npt_model = MobileViTForImageClassification.from_pretrained(hf_model_path)\n<\/pre>\n<\/div>\n<p>Since the end result of this tutorial should work with MediaPipe Tasks, take an extra step to match the expected input and output shapes for image classification to what is used by the MediaPipe image classification Task.<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">class<\/span> <span style=\"color: blue;\">HF2MP_ImageClassificationModelWrapper<\/span>(nn.Module):\n\n  def <span style=\"color: blue;\">__init__<\/span>(self, hf_image_classification_model, hf_processor):\n    super().__init__()\n    self.model = hf_image_classification_model\n    <span style=\"color: green; font-weight: bold;\">if<\/span> hf_processor.do_rescale:\n      self.rescale_factor = hf_processor.rescale_factor\n    <span style=\"color: green; font-weight: bold;\">else<\/span>:\n      self.rescale_factor = <span style=\"color: #666666;\">1.0<\/span>\n\n  def <span style=\"color: blue;\">forward<\/span>(self, image: torch.Tensor):\n    # BHWC -&gt; BCHW.\n    image = image.permute(<span style=\"color: #666666;\">0<\/span>, <span style=\"color: #666666;\">3<\/span>, <span style=\"color: #666666;\">1<\/span>, <span style=\"color: #666666;\">2<\/span>)\n    # RGB -&gt; BGR.\n    image = image.flip(dims=(<span style=\"color: #666666;\">1<\/span>,))\n    # Scale [<span style=\"color: #666666;\">0<\/span>, <span style=\"color: #666666;\">255<\/span>] -&gt; [<span style=\"color: #666666;\">0<\/span>, <span style=\"color: #666666;\">1<\/span>].\n    image = image * self.rescale_factor\n    logits = self.model(pixel_values=image).logits  # [B, <span style=\"color: #666666;\">1000<\/span>] float32.\n    # Softmax <span style=\"color: green; font-weight: bold;\">is<\/span> required <span style=\"color: green; font-weight: bold;\">for<\/span> MediaPipe classification model.\n    logits = torch.nn.functional.softmax(logits, dim=-<span style=\"color: #666666;\">1<\/span>)\n\n    <span style=\"color: green; font-weight: bold;\">return<\/span> logits\n<\/pre>\n<\/div>\n<p><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">hf_model_path=\"apple\/mobilevit-small\"\nhf_mobile_vit_processor = MobileViTImageProcessor.from_pretrained(hf_model_path)\nhf_mobile_vit_model = MobileViTForImageClassification.from_pretrained(hf_model_path)\nwrapped_pt_model = HF2MP_ImageClassificationModelWrapper(\nhf_mobile_vit_model, hf_mobile_vit_processor).eval()\n<\/pre>\n<\/div>\n<p>Whether you plan to use the converted MobileViT model with MediaPipe Tasks or LiteRT, the next step is to convert the model to the <span style=\"color: #OD904F; font-family: Courier;\">.tflite<\/span> format.<\/p>\n<p>First, match the input shape. In this example, the input shape is <i>1, 256, 256, 3<\/i> for a 256&#215;256 pixel three-channel RGB image.<\/p>\n<p>Then, call AI Edge Torch&#8217;s <span style=\"color: #OD904F; font-family: Courier;\">convert<\/span> function to complete the conversion process.<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">import ai_edge_torch\n\nsample_args = (torch.rand((<span style=\"color: #666666;\">1<\/span>, <span style=\"color: #666666;\">256<\/span>, <span style=\"color: #666666;\">256<\/span>, <span style=\"color: #666666;\">3<\/span>)),)\nedge_model = ai_edge_torch.convert(wrapped_pt_model, sample_args)\n<\/pre>\n<\/div>\n<p>After converting the model, you can further refine it by incorporating metadata for the image classification labels. MediaPipe Tasks will utilize this metadata to display or return pertinent information after classification.<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">from mediapipe.tasks.python.metadata.metadata_writers import image_classifier\nfrom mediapipe.tasks.python.metadata.metadata_writers import metadata_writer\nfrom mediapipe.tasks.python.vision.image_classifier import ImageClassifier\nfrom pathlib import Path\n\nflatbuffer_file = Path('hf_mobile_vit_mp_image_classification_raw.tflite')\nedge_model.export(flatbuffer_file)\ntflite_model_buffer = flatbuffer_file.read_bytes()\n\n<span style=\"color: #408080; font-style: italic;\">\/\/Extract the image classification labels from the HF models for later integration into the TFLite model.<\/span>\nlabels = list(hf_mobile_vit_model.config.id2label.values())\n\nwriter = image_classifier.MetadataWriter.create(\n    tflite_model_buffer,\n    input_norm_mean=[<span style=\"color: #666666;\">0.0<\/span>], #  Normalization <span style=\"color: green; font-weight: bold;\">is<\/span> not needed <span style=\"color: green; font-weight: bold;\">for<\/span> <span style=\"color: green; font-weight: bold;\">this<\/span> model.\n    input_norm_std=[<span style=\"color: #666666;\">1.0<\/span>],\n    labels=metadata_writer.Labels().add(labels),\n)\ntflite_model_buffer, _ = writer.populate()\n<\/pre>\n<\/div>\n<p>With all of that completed, it&#8217;s time to integrate your model into an Android app. If you&#8217;re following the official Colab notebook, this involves saving the model locally. For an example of image classification with MediaPipe Tasks, explore the <a href=\"https:\/\/github.com\/google-ai-edge\/mediapipe-samples\/tree\/main\/examples\/image_classification\/android\" target=\"_blank\" rel=\"noopener\">GitHub<\/a> repository. You can find more information in the official <a href=\"https:\/\/ai.google.dev\/edge\/mediapipe\/solutions\/vision\/image_classifier\/android\" target=\"_blank\" rel=\"noopener\">Google AI Edge documentation<\/a>.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"moving image of Newly converted ViT model with MediaPipe Tasks\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhrSKAbbp3X_KGq9RYH5BXLC0PUMnOl7L1JgzXwRZeKc9d8YGlt33hucBfLrf-lb63Ye_kEFcHqwyuG46-YPWH4v6oeVMVM0fnLmy1lHi24QY4rpaM_PM-ZZr7qzfdhmls-kZlEje3e3M_N1bCspYRun85pmsDLnmirDDRegOWmMK6X9SO12oOSIPFVNjg\/s16000\/image4.gif\"\/><\/div>\n<p><imgcaption><center><em>Newly converted ViT model with MediaPipe Tasks<\/em><\/center><\/imgcaption><\/image><\/p>\n<p>After understanding how to convert a simple image classification model, you can use the same techniques to adapt various PyTorch models for Google AI Edge LiteRT or MediaPipe Tasks tooling on Android.<\/p>\n<p>For further model optimization, consider methods like <a href=\"https:\/\/github.com\/google-ai-edge\/ai-edge-torch\/blob\/main\/docs\/pytorch_converter\/README.md#quantization\" target=\"_blank\" rel=\"noopener\">quantizing<\/a> during conversion. Check out the <a href=\"https:\/\/github.com\/google-ai-edge\/models-samples\/blob\/main\/convert_pytorch\/DIS_segmentation_and_quantization.ipynb\" target=\"_blank\" rel=\"noopener\">GitHub example<\/a> to learn more about how to convert a PyTorch image segmentation model to LiteRT and quantize it.<\/p>\n<h3>What&#8217;s Next<\/h3>\n<p>To keep up to date on Google AI Edge developments, look for announcements on the <a href=\"https:\/\/www.youtube.com\/user\/googledevelopers\" target=\"_blank\" rel=\"noopener\">Google for Developers YouTube channel<\/a> and <a href=\"https:\/\/developers.googleblog.com\" target=\"_blank\" rel=\"noopener\">blog<\/a>.<\/p>\n<p>We look forward to hearing about how you&#8217;re using these features in your projects. Use #AndroidAI hashtag to share your feedback or what you&#8217;ve built in social media and check out other content in <a href=\"https:\/\/android-developers.googleblog.com\/2024\/09\/welcome-to-ai-on-android-spotlight-week.html\" target=\"_blank\" rel=\"noopener\">AI on Android Spotlight Week<\/a>!<\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2024\/10\/pytorch-machine-learning-models-on-android.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by Paul Ruiz \u2013 Senior Developer Relations Engineer Earlier this year we launched Google AI Edge, a suite of tools with easy access<\/p>\n","protected":false},"author":1,"featured_media":261547,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/261546"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=261546"}],"version-history":[{"count":0,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/261546\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/261547"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=261546"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=261546"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=261546"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}