{"id":14958844,"url":"https://github.com/shubham0204/age-gender_estimation_tf-android","last_synced_at":"2025-05-02T12:31:50.229Z","repository":{"id":52752858,"uuid":"365158478","full_name":"shubham0204/Age-Gender_Estimation_TF-Android","owner":"shubham0204","description":"Age + Gender Estimation on Android with TensorFlow Lite","archived":false,"fork":false,"pushed_at":"2024-02-25T02:10:35.000Z","size":23811,"stargazers_count":67,"open_issues_count":1,"forks_count":16,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-07T02:06:10.829Z","etag":null,"topics":["age-estimation-model","age-gender-estimation","android","android-app","android-application","android-development","kotlin","kotlin-android","kotlin-coroutines","kotlin-language","python","tensorflow","tensorflow-examples","tensorflow-experiments","tensorflow-lite","tensorflow-models","tflite-model"],"latest_commit_sha":null,"homepage":"https://equipintelligence.medium.com/detecting-age-and-gender-with-tf-lite-on-android-33997eed6c25","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shubham0204.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"shubham0204","custom":["https://www.paypal.me/ShubhamPanchal0204"]}},"created_at":"2021-05-07T07:59:39.000Z","updated_at":"2025-03-18T09:04:20.000Z","dependencies_parsed_at":"2024-02-25T03:32:28.320Z","dependency_job_id":null,"html_url":"https://github.com/shubham0204/Age-Gender_Estimation_TF-Android","commit_stats":{"total_commits":28,"total_committers":2,"mean_commits":14.0,"dds":0.5,"last_synced_commit":"48365bc1a541f3ac47b08bf85537849c5fc323e9"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shubham0204%2FAge-Gender_Estimation_TF-Android","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shubham0204%2FAge-Gender_Estimation_TF-Android/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shubham0204%2FAge-Gender_Estimation_TF-Android/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shubham0204%2FAge-Gender_Estimation_TF-Android/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shubham0204","download_url":"https://codeload.github.com/shubham0204/Age-Gender_Estimation_TF-Android/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252038198,"owners_count":21684647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["age-estimation-model","age-gender-estimation","android","android-app","android-application","android-development","kotlin","kotlin-android","kotlin-coroutines","kotlin-language","python","tensorflow","tensorflow-examples","tensorflow-experiments","tensorflow-lite","tensorflow-models","tflite-model"],"created_at":"2024-09-24T13:18:23.382Z","updated_at":"2025-05-02T12:31:45.216Z","avatar_url":"https://github.com/shubham0204.png","language":"Kotlin","funding_links":["https://github.com/sponsors/shubham0204","https://www.paypal.me/ShubhamPanchal0204"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eAge + Gender Estimation in Android with TensorFlow\u003c/h1\u003e\n\u003c/div\u003e\n\n![repo_banner](images/repo_banner.png)\n\n---\n\n### **Contents**\n\n*[**Python project**](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#%EF%B8%8F-python-project)*\n\n* [Google Colab Notebooks](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-colab-notebooks)\n* [Dataset](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-dataset)\n* [Model ( *Vanilla* vs. Lite )](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-model)\n\n*[**Android project**](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-android-project)*\n\n * [Overview](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-overview)\n * [Usage](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-usage)\n * [Project Configuration ( + Firebase Services )](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-project-configuration)\n * [TensorFlow Lite models](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-tensorflow-lite-models)\n * [NNAPI and `GpuDelegate` compatibility](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-nnapi-and-gpudelegate-compatibility)\n\n*[Issues and Suggestions](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-issues-and-suggestions)*\n\n*[License](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#%EF%B8%8F-license)*\n\n\u003e  I'm open for **freelancing** in Android + ML projects and also in Technical Content Writing. You may send me an email/message on [**Google Chat**](https://mail.google.com/chat) at **equipintelligence@gmail.com**.\n\n---\n\n![results](images/results.png)\n\n---\n\n\n## 🖥️ Python Project\n\n### 👉🏻 Colab Notebooks\n\nAs the application uses two different models for age and gender estimation, we provide two notebooks to train the age and gender detection models. These are Google Colab notebooks and are capable of downloading the dataset, training the model, and finally exporting the TFLite model ( used in the Android app ).\n\n* [`Age Estimation in TensorFlow - Google Colab`](https://github.com/shubham0204/Google_Colab_Notebooks/blob/main/Age_Estimation_(W1).ipynb)\n\n[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/shubham0204/Google_Colab_Notebooks/blob/main/Age_Estimation_(W1).ipynb)\n\n* [`Gender Classification in TensorFlow - Google Colab`](https://github.com/shubham0204/Google_Colab_Notebooks/blob/main/Gender_Estimation_(W2).ipynb)\n\n[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/shubham0204/Google_Colab_Notebooks/blob/main/Gender_Estimation_(W2).ipynb)\n\n\u003e The notebooks describe each step in the implementation and are self explanatory. For any questions/issues/suggestions regarding the notebooks, see *[Issues and Suggestions](https://github.com/shubham0204/Age-Gender_Estimation_TF-Android#-issues-and-suggestions)*\n\nThe Keras models ( `.h5` ) are available here,\n\n* [`Keras models for age and gender estimation`](https://drive.google.com/drive/folders/13478oTfOHD9Fkf53FtLXQEXO_IlgIPP5?usp=sharing)\n\n\n### 👉🏻 Dataset\n\nThe TensorFlow models are trained on the [UTKFace dataset](https://susanqq.github.io/UTKFace/)  which contains 23K images with age, gender and ethnicity annotations. We use 20K samples from the dataset, in which 14K images are used for training and 6K images are used to evaluate the model.\n\nFor both the models, we use 3-channeled RGB images as inputs. The age estimation model takes in `200 * 200` images as inputs whereas the gender classification model takes in images of size `128 * 128`.\n\n* For the age estimation model, we normalize the target variable i.e the age of the person. Hence the model's output is in the range `( 0 , 1 ]`. The predicted age is obtained by multiplying the model's output with a suitable factor ( which in our case is `116` ).\n* For gender classification, the model outputs a probability distribution for the two labels `male` and `female` .\n\n### 👉🏻 Model\n\nWe provide two different variants of our models. We refer these variants as `vanilla` and `lite`.  **The `lite` models are identical to the `vanilla` models except that they use separable convolutions instead of the standard convolutions.** You'll notice the change in the Colab notebook,\n\n```\n# Define the conv block.\nif lite_model:\n        x = tf.keras.layers.SeparableConv2D( num_filters ,\n                                            kernel_size=kernel_size ,\n                                            strides=strides \n                                            , use_bias=False ,\n                                            kernel_initializer=tf.keras.initializers.HeNormal() ,\n                                            kernel_regularizer=tf.keras.regularizers.L2( 1e-5 )\n                                             )( x )\n else:\n        x = tf.keras.layers.Conv2D( num_filters ,\n                                   kernel_size=kernel_size ,\n                                   strides=strides ,\n                                   use_bias=False ,\n                                   kernel_initializer=tf.keras.initializers.HeNormal() ,\n                                   kernel_regularizer=tf.keras.regularizers.L2( 1e-5 )\n                                    )( x )\n \n    x = tf.keras.layers.BatchNormalization()( x )\n    x = tf.keras.layers.LeakyReLU( leaky_relu_alpha )( x )\n```\n\nSeparable Convolutions have lesser parameters than standard convolutions, and hence reduce the size of our model. Also, the `lite` models run faster as compared to their `vanilla` counterparts. The increase in speed is companioned with a slight decrease in the performance of the model as shown below,\n\n| Model ( Age Estimation ) | `vanilla` model | `lite` model | \n|--|:--:| :--: |\n| No. of parameters| 1,069,297 | 200,956 |\n| MAE | `2.425` | `4.586` |\n\n\n\n| Model ( Gender Classification ) | `vanilla` model | `lite` model | \n|--|:--:| :--: |\n| No. of parameters | 675,090 | 328,733 |\n| Accuracy ( % ) | `99.8` | `96.4` |\n\n---\n\n## 📱 Android Project\n\n### 👉🏻 Overview\n\nThe following GIF displays the basic functionality of the app. You may observe the four options provided for \"Choose Model\" and also the NNAPI and GPU Delegate options. The inference time may change depending on the device you're using.\n\n![working_of_app](images/app_working_s.gif) \n\n### 👉🏻 Usage\n\n* Open the app. A dialog box saying \"Initialize a Model\" pops up. Select any one of the four models.\n* Select the additional options, like \"Use NNAPI\" and \"Use GPU\". If any of these options are not available on your device, a message will be shown for the same. See [NNAPI and `GpuDelegate` compatibility](#nnapi-and-gpudelegate-compatibility)\n* Once the models are initialized, tap \"Take Photo\" to open the default camera app.\n* If none of the faces are identified in the picture, a dialog will be displayed, prompting you to take another picture. If everything goes fine, the results appear on the screen in a couple of seconds.\n* Tap \"Reinitialize\" to try another model provided in the app.\n\n\u003e **Note: If the picture clicked by the user contains multiple faces, results will be shown for a single face only. This is a drawback and we'll try to improve it in the next releases.**\n\n### 👉🏻 Project Configuration\n\nThe project has been configured with the below settings, which can be easily found in the app's `build.gradle` file.\n```\n// SDK Info\ncompileSdkVersion 30  \nbuildToolsVersion \"30.0.0\"  \n\n// App info\napplicationId \"com.ml.projects.age_genderdetection\"  \nminSdkVersion 23  \ntargetSdkVersion 30  \n\n// Version info\nversionCode 1  \nversionName \"1.0\"\n```\n\nThe versions of the Android Gradle plugin and the Gradle Version are mentioned below.\n\n```\nAndroid Gradle Plugin Version: 4.1.3\nGradle Version: 6.5\n```\n\nAs mentioned, the project utilizes Firebase, and specifically [MLKit FaceDetector](https://firebase.google.com/docs/ml-kit/detect-faces). To connect the app with Firebase, follow these [instructions](https://firebase.google.com/docs/android/setup#register-app). Download the `google-services.json` file and place it in the `app` folder. The Firebase library required for the face detection functionality is added in the app's `build.gradle`,\n\n```\nimplementation 'com.google.android.gms:play-services-mlkit-face-detection:16.1.5'\n```\n\n\u003e Why isn't the `google-services.json` file shared alongside the code in this repo?\n\u003e That's because the file contains credentials unique for every user. ( You may need to create a Firebase project. Follow the instructions cited above )\n\n###  👉🏻 TensorFlow Lite models\n\nTo enable TFLite capabilities in our Android project, we add the below libraries to our project,\n\n```\nimplementation 'org.tensorflow:tensorflow-lite:2.4.0'  \nimplementation 'org.tensorflow:tensorflow-lite-gpu:2.4.0'  \nimplementation 'org.tensorflow:tensorflow-lite-support:0.1.0'\n```\n\u003e See the [packages on JFrog Bintray](https://bintray.com/google/tensorflow).\n\nAll TFLite models are placed in the app's `assets` folder. In order to disable the compression performed on files present in the `assets` folder, we add the following flag in app's `build.gradle` ,\n\n```\nandroid {  \n  ...\n  aaptOptions {  \n     noCompress \"tflite\"  \n  }\n  ...\n}  \n```\nThe names of these models are stored in the `modelFilenames` array in `MainActivity.kt`,\n\n```\nprivate val modelFilenames = arrayOf(  \n    arrayOf(\"model_age_q.tflite\", \"model_gender_q.tflite\"),  \n    arrayOf(\"model_age_nonq.tflite\", \"model_gender_nonq.tflite\"),  \n    arrayOf(\"model_lite_age_q.tflite\", \"model_lite_gender_q.tflite\"),  \n    arrayOf(\"model_lite_age_nonq.tflite\", \"model_lite_gender_nonq.tflite\"),  \n)\n```\nWhenever the user selects a particular model, we use the `FileUtil.loadMappedFile()` method to get `MappedByteBuffer` of the model, which is then passed to the constructor of  `Interpreter`,\n\n```\nageModelInterpreter = Interpreter(FileUtil.loadMappedFile( applicationContext , \"model_v6_age_q.tflite\"), options )\n```\n\u003e Note: The method `FileUtil.loadMappedBuffer()` comes from the `tf-lite-support` library, which helps us parse TFLite models and also to preprocess model inputs.\n\n### 👉🏻 NNAPI and `GpuDelegate` compatibility\n\nThe app offers acceleration through the means of NNAPI and `GpuDelegate` provided by TensorFlow Lite.\n\n* [TensorFlow Lite NNAPI delegate](nsorflow.org/lite/performance/nnapi)\n* [TensorFlow Lite GPU delegate](https://www.tensorflow.org/lite/performance/gpu)\n\nAs mentioned in the docs, NNAPI is compatible for Android devices running Android Pie ( API level 27 ) and above. The app checks this compatibility in `MainActivity.kt`,\n\n```\nif ( Build.VERSION.SDK_INT \u003c Build.VERSION_CODES.P ) {  \n    useNNApiCheckBox.isEnabled = false  \n    useNNApiCheckBox.text = \"Use NNAPI ( Not available as your Android version is less than 9 ( Android Pie ).\"  \n    useNNApi = false  \n}\n```\n\nThe `GpuDelegate` also performs the following compatibility check,\n\n```\nif ( !compatList.isDelegateSupportedOnThisDevice ){  \n    useGPUCheckBox.isEnabled = false  \n    useGPUCheckBox.text = \"Use GPU ( GPU acceleration is not available on this device ).\"  \n    useGpu = false  \n}\n```\n\n## 🔧 Issues and Suggestions\n\nIf any issue occurs, you may [open an issue]() or [start a new discussion](). Please mention the following while addressing your issue,\n\n* The name of the device you're using ( along with its Android version ).\n* Crash logs if you think they might be helpful.\n* If you've found something related to the issue elsewhere, mention them as well so that the issue could be resolved as fast as possible.\n\n\n## 👨🏻‍✈️ License\n\n```\nMIT License  \n  \nCopyright (c) 2021 Shubham Panchal  \n  \nPermission is hereby granted, free of charge, to any person obtaining a copy  \nof this software and associated documentation files (the \"Software\"), to deal  \nin the Software without restriction, including without limitation the rights  \nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell  \ncopies of the Software, and to permit persons to whom the Software is  \nfurnished to do so, subject to the following conditions:  \n  \nThe above copyright notice and this permission notice shall be included in all  \ncopies or substantial portions of the Software.  \n  \nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  \nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  \nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  \nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  \nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  \nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  \nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshubham0204%2Fage-gender_estimation_tf-android","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshubham0204%2Fage-gender_estimation_tf-android","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshubham0204%2Fage-gender_estimation_tf-android/lists"}