{"id":36632,"date":"2018-04-23T14:51:28","date_gmt":"2018-04-23T21:51:28","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=36632"},"modified":"2019-04-04T07:47:00","modified_gmt":"2019-04-04T14:47:00","slug":"android-apps-tensorflow","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/android-apps-tensorflow\/","title":{"rendered":"Using TensorFlow and Azure to Add Image Classification to Your Android Apps"},"content":{"rendered":"<p>\t\t\t\t<em>TensorFlow<\/em> is a well established, open source machine learning and deep learning framework that can be used to create and run a wide range of different models, usually using powerful machines in the cloud. In addition, TensorFlow also supports running models on mobile devices through the <a href=\"https:\/\/www.tensorflow.org\/mobile\/mobile_intro\">TensorFlow.Mobile library<\/a>, taking advantage of the hardware acceleration available on modern phones to run models incredibly fast on low powered mobile devices.<\/p>\n<p>In this post, we&#8217;ll discuss how to build an image classifier to identify different fruits using the Azure Custom Vision service, and create a simple Android app to use this model to classify images.<\/p>\n<h2>Getting Started<\/h2>\n<p>Creating ML models can be time consuming and require large data sets. To make it easier to create image classification models,\u00a0Microsoft has created the <a href=\"https:\/\/customvision.ai\/?WT.mc_id=tensorflow-xamarinblog-jabenn\">Custom Vision Service<\/a>, which uses a technique called transfer learning to allow you to train an image classifier using only a small number of images, instead of the thousands that traditionally would be required to train such a model. These models can be exported as TensorFlow models (or <a href=\"https:\/\/blog.xamarin.com\/coreml-azure-create-simple-xamarin-ios-apps\/?WT.mc_id=tensorflow-xamarinblog-jabenn\">CoreML if you are on iOS<\/a>) and used from inside an Android app.<\/p>\n<p>Lets start by creating a project in the Custom Vision service. Make sure you select one of the <code>compact<\/code> domains, the compact domains create models that are small enough to be exported and used from a mobile device.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-36637 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/TensorFlowMobile_TensorFlow_Pic1.png\" alt=\"Creating a new Custom Vision project with a General (compact) domain\" width=\"934\" height=\"736\" \/><\/p>\n<p>Image classifiers are trained by being given images with one or more <strong>tags<\/strong>, which are text labels that indicate what is in that image. For example, you might upload five pictures of oranges with the tag of <code>orange<\/code>, five pictures of bananas with the tag <code>banana<\/code>,\u00a0and so on for different fruits.<\/p>\n<p>To train your model, you will need at least five images for each tag you want to use, so the first step is to gather the data by photographing whatever fruit you have to hand. Next, click the <strong>Add Images<\/strong>\u00a0button and upload the images of the first fruit, setting the appropriate tag. Repeat this for the rest of the fruits. Finally click the <strong>Train<\/strong> button on the top menu to train the model.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-36636 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/TensorFlowMobile_TagAndTrain.gif\" alt=\"Uploading and tagging images, and training the model\" width=\"670\" height=\"344\" \/><\/p>\n<p>Once trained, click the <strong>Export<\/strong> button to export the model for use with TensorFlow.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-36634 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/TensorFlowMobile_ExportAsTensorflow.png\" alt=\"Exporting the model to be used with TensorFlow\" width=\"580\" height=\"236\" \/><\/p>\n<p>This will download a zip file containing two files: <em>model.pb<\/em> and <em>labels.txt<\/em>.<\/p>\n<h2>Adding the Model to Your Android App<\/h2>\n<p>Now that we have the model, it&#8217;s time to add it to an Android app project and use it to classify images.<\/p>\n<h3>Add the Model and TensorFlow.mobile to the Project<\/h3>\n<p>Create a new Android app by going to <strong>File -&gt; New Project -&gt; Android -&gt; Single View App<\/strong> in Visual Studio. Add the <em>model.pb<\/em>\u00a0and <em>labels.txt<\/em>\u00a0files to the <code>Assets<\/code>\u00a0folder, and make sure the build action is set to <code>Android Asset<\/code>.<\/p>\n<p>TensorFlow.Mobile is available as a NuGet package that wraps the native Android libraries. Install the <strong><a href=\"https:\/\/www.nuget.org\/packages\/Xam.Android.Tensorflow\/1.0.0\">Xam.Android.Tensorflow<\/a><\/strong> package in your Android app.<\/p>\n<h3>Initializing the Model and Labels<\/h3>\n<p>To use the model, we need to create an instance of the TensorFlow interface using our model file. We also need to load the labels file; the model from TensorFlow doesn&#8217;t contain the actual tag values, so these come from the labels file.<\/p>\n<pre>\n<code>\n    using using Org.Tensorflow.Contrib.Android;\n    ...\n    var assets = Application.Context.Assets;\n    inferenceInterface = new TensorFlowInferenceInterface(assets, \"model.pb\");\n    var sr = new StreamReader(assets.Open(\"labels.txt\"));\n    var labels = sr.ReadToEnd()\n                   .Split('\\n')\n                   .Select(s =&gt; s.Trim())\n                   .Where(s =&gt; !string.IsNullOrEmpty(s))\n                   .ToList();\n<\/code>\n<\/pre>\n<h2>Recognizing Images<\/h2>\n<p>To recognize an image, first we need to capture one from somewhere. To use the camera, I&#8217;d recommend using the <a href=\"https:\/\/www.nuget.org\/packages\/Xam.Plugin.Media\/\"><strong>Xam.Plugin.Media<\/strong> NuGet package<\/a>. This package has helpers to open the camera and extract the photo taken by the user.<\/p>\n<h3>Preparing the Input for the Model<\/h3>\n<p>Once you have a photo, it needs to be converted for the Custom Vision model. These models require the input to be of the correct size and format to work; they don&#8217;t understand images, as such, but instead understand binary data. For the models created by the Custom Vision service, you need the images to be 227&#215;227 pixels in size, converted to an array of floating point values, one per red, green, and blue value for each pixel, with some model-specific adjustments to the color value. The following code converts an Android <code>Bitmap<\/code> to the correct format.<\/p>\n<pre>\n<code>\n    var resizedBitmap = Bitmap.CreateScaledBitmap(bitmap, 227, 227, false)\n                              .Copy(Bitmap.Config.Argb8888, false);\n    var floatValues = new float[227 * 227 * 3];\n    var intValues = new int[227 * 227];\n    resizedBitmap.GetPixels(intValues, 0, 227, 0, 0, 227, 227);\n    for (int i = 0; i &gt; 8) &amp; 0xFF) - 117);\n        floatValues[i * 3 + 2] = (((val &gt;&gt; 16) &amp; 0xFF) - 123);\n    }\n<\/code>\n<\/pre>\n<h3>Running the Model<\/h3>\n<p>Now that we have our image in the right format, we can run the model against our data. Running the model involves feeding it named inputs, running it for named outputs, then retrieving the output you&#8217;re interested in by name. Each model can take multiple inputs and give multiple outputs, but in our case we only have one input and need one output. The following code shows this for our Custom Vision model.<\/p>\n<pre>\n<code>\n    var outputs = new float[labels.Count];\n    inferenceInterface.Feed(\"Placeholder\", floatValues, 1, 227, 227, 3);\n    inferenceInterface.Run(new[] { \"loss\" });\n    inferenceInterface.Fetch(\"loss\", outputs);\n<\/code>\n<\/pre>\n<p>The <code>outputs<\/code> array is filled with floating point values, each one representing the confidence that the image matching a tag in the labels list at the same array position. For example, if you had three labels in the list in the following order:<\/p>\n<ul>\n<li>Apple<\/li>\n<li>Banana<\/li>\n<li>Mango<\/li>\n<\/ul>\n<p>Then <code>output[0]<\/code> would be the confidence that the image is an <em>apple<\/em>, using values ranging from 0-1 with 1 representing 100%. <code>output[1]<\/code> would be the confidence that the image is a <em>banana<\/em>, and so on. You can then use the tag with the highest confidence as the most likely result.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-36635\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/TensorFlowMobile_Result.gif\" alt=\"The app takes a photo of a Mango and detects this successfully\" width=\"288\" height=\"530\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>It&#8217;s easy to get started building image classifiers using Azure, and access them from Xamarin.Android, using TensorFlow.Mobile. Head to\u00a0<a href=\"https:\/\/github.com\/jimbobbennett\/blog-samples\/tree\/master\/UsingTensorFlowAndAzureInAndroid\">GitHub<\/a>\u00a0to see the final sample code. Check out the documentation <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cognitive-services\/custom-vision-service\/home\/?WT.mc_id=tensorflow-xamarinblog-jabenn\">here<\/a> to learn more about training your own Custom Vision models.<\/p>\n<p><a href=\"https:\/\/forums.xamarin.com\/125943\/using-tensorflow-and-azure-to-add-image-classification-to-your-android-apps\/\">Discuss the post on the forums!<\/a>\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TensorFlow is a well established, open source machine learning and deep learning framework that can be used to create and run a wide range of different models, usually using powerful machines in the cloud. In addition, TensorFlow also supports running models on mobile devices through the TensorFlow.Mobile library, taking advantage of the hardware acceleration available [&hellip;]<\/p>\n","protected":false},"author":575,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[5,4],"class_list":["post-36632","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-android","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>TensorFlow is a well established, open source machine learning and deep learning framework that can be used to create and run a wide range of different models, usually using powerful machines in the cloud. In addition, TensorFlow also supports running models on mobile devices through the TensorFlow.Mobile library, taking advantage of the hardware acceleration available [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/36632","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/575"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=36632"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/36632\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=36632"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=36632"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=36632"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}