<jupyter_start><jupyter_text>This notebook shows how to create an image classifier with the TensorFlow Lite Model Maker with just a few lines of code. We will use the Icons-50 dataset for model training and evaluation.<jupyter_code># Install TFLite Model Maker
!pip install git+git://github.com/tensorflow/examples.git#egg=tensorflow-examples[model_maker]
# Enable TensorFlow 2.x
%tensorflow_version 2.x
# Import Tensorflow
import tensorflow as tf
tf.__version__
# Import Numpy & Matplotlib
import numpy as np
import matplotlib.pyplot as plt

# Import TFLite model maker related classes
from tensorflow_examples.lite.model_maker.core.data_util.image_dataloader import ImageClassifierDataLoader
from tensorflow_examples.lite.model_maker.core.task import image_classifier
from tensorflow_examples.lite.model_maker.core.task.model_spec import mobilenet_v2_spec
from tensorflow_examples.lite.model_maker.core.task.model_spec import ImageModelSpec<jupyter_output>WARNING:tensorflow:Needs to install tflite-support package.<jupyter_text>Data pipeline  Prepare Icons-50 dataGo to Kaggle to download the icons-50.zip data https://www.kaggle.com/danhendrycks/icons50And upload the zip file somewhere to your Google Drive.<jupyter_code>!mkdir datasets<jupyter_output><empty_output><jupyter_text>Mount GDrive and copy over icons50.zip<jupyter_code>from google.colab import drive
drive.mount('/content/drive')
!cp /content/drive/My\ Drive/icons50.zip datasets/
# !unzip datasets/icons50.zip -d datasets/
!unzip datasets/icons50.zip -d datasets<jupyter_output>[1;30;43mStreaming output truncated to the last 5000 lines.[0m
  inflating: datasets/icons-50/Icons-50/flower/apple_5_hibiscus.png  
  inflating: datasets/icons-50/Icons-50/flower/apple_5_rose.png  
  inflating: datasets/icons-50/Icons-50/flower/apple_5_sunflower.png  
  inflating: datasets/icons-50/Icons-50/flower/apple_5_tulip.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_blossom.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_bouquet.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_cherry_blossom.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_hibiscus.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_rose.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_rosette.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_sunflower.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_tulip.png  
  inflating: datasets/icons-50/Icons-50/flower/emoji-one_0_wilted_flower[...]<jupyter_text>Load the Icons 50 dataWith the TFLite model maker, loading the data takes just one line of code:`data = ImageClassifierDataLoader.from_folder(image_path)`<jupyter_code>image_path = "/content/datasets/Icons-50/Icons-50"
# Load all data from the image path
data = ImageClassifierDataLoader.from_folder(image_path)<jupyter_output>INFO:tensorflow:Load image with size: 10000, num_label: 50, labels: airplane, arrow_directions, ball, biking, bird, blade, boat, books, building, bunny_ears, cartwheeling, clock, cloud, disk, drinks, emotion_face, envelope, family, fast_train, feline, flag, flower, footwear, golfing, hand, hat, heart, holding_hands, japanese_ideograph, kiss, lock, mailbox, marine_animals, medal, money, monkey, moon, mountain, numbers, phone, prohibit_sign, star, surfing, tree, umbrella, vehicle, water_polo, worker, wrestling, writing_utensil.<jupyter_text>Data split: train (80%), validation (10%) and test (10%)<jupyter_code># Split 80% of the data into train_data
train_data, rest_data = data.split(0.8)

# Then split the rest of data into 50% each for validation & test
validation_data, test_data = rest_data.split(0.5)
print('Number of classes: {} '.format(data.num_classes))
print('Number of training examples: {} '.format(train_data.size))
print('Number of validation examples: {} '.format(validation_data.size))
print('Number of test examples: {} '.format(test_data.size))
label_names = data.index_to_label
label_names<jupyter_output><empty_output><jupyter_text>Visualize the data<jupyter_code>for image, label in train_data.dataset.take(2):
  print(image.shape)
  plt.figure()
  plt.imshow(image)
  plt.title(label_names[label])<jupyter_output>(120, 120, 3)
(64, 64, 3)<jupyter_text>ModelWith one line of code we can create an image classifier with our own data.Under the hood, image_classifier.create will compile and train the model with transfer learning. By default it uses a pretrained EfficientNet-Lite0.  Create & train the modelCreate and train the model takes just one line of code `image_classifier.create()`.Here are the defaults in the TFLite Model Maker:* model - EfficientNet-Lite0* Input image shape - [224, 224]* number of epochs - 5* batch size = 32<jupyter_code>model = image_classifier.create(train_data, 
                                validation_data=validation_data, 
                                epochs = 10)<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
hub_keras_layer_v1v2 (HubKer (None, 1280)              3413024   
_________________________________________________________________
dropout (Dropout)            (None, 1280)              0         
_________________________________________________________________
dense (Dense)                (None, 50)                64050     
=================================================================
Total params: 3,477,074
Trainable params: 64,050
Non-trainable params: 3,413,024
_________________________________________________________________
None
INFO:tensorflow:Retraining the models...<jupyter_text>Test accuracy<jupyter_code>loss, accuracy = model.evaluate(test_data)<jupyter_output>32/32 [==============================] - 2s 48ms/step - loss: 0.9729 - accuracy: 0.9660<jupyter_text>Visualize predictionsFirst we get images and labels from a test batch, and then use the retrained model to make predictions.<jupyter_code># Take 16 images from the test dataset
test_batch = test_data.dataset.take(16)
predictions = model.predict_top_k(test_data)
predictions[:4]
plt.figure(figsize=(8, 8))

# Display 16 test images with predictions
for i, (image, label_index) in enumerate(test_batch):
  plt.subplot(4, 4, i+1)
  plt.tight_layout() # add space between subplots
  plt.xticks([]) 
  plt.yticks([])
  plt.grid(False) # remove grids
  plt.imshow(image)
  prediction = str(predictions[i][0][0])
  title_color = "green" if prediction == label_names[label_index] else "red"
  plt.title(prediction, color = title_color)<jupyter_output><empty_output><jupyter_text>Export the modelCreate model and labels file, download them from Colab left sidebar.These files are ready to be used in mobile apps and edge devices.<jupyter_code># Create tflite model and labels file 
model.export('model.tflite', 'labels.txt')<jupyter_output>INFO:tensorflow:Export to tflite model in model.tflite.<jupyter_text>Change the pretrained modelWe could switch the pretrained model by just setting parameter `model_spec ` in the `image_classifier.create()` method.  Change to another model supported by Model MakerThe default model in the Model Maker is EfficientNet-Lite0. [EfficientNet-Lite](https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/lite) are a family of image classification models that could achieve state-of-art accuracy and suitable for Edge devices. For now the TFLite Model Maker supports EfficientNet-Lite models, MobileNetV2 and ResNet50.<jupyter_code># change pretrained model to EfficientNet1
model = image_classifier.create(train_data, model_spec=efficientnet_lite1_spec, validation_data=validation_data)

# change pretrained model to mobilenet v2
model = image_classifier.create(train_data, model_spec=mobilenet_v2_spec, validation_data=validation_data)

# change pretrained model to ResNet 50
model = image_classifier.create(train_data, model_spec=resnet_50_spec, validation_data=validation_data)<jupyter_output><empty_output><jupyter_text>Change to another model supported on TensorFlow Hub<jupyter_code>inception_v3_spec = ImageModelSpec(uri='https://tfhub.dev/google/imagenet/inception_v3/feature_vector/1')
inception_v3_spec.input_image_shape = [299, 299]

# change to Inception V3
model = image_classifier.create(train_data, model_spec=inception_v3_spec, validation_data=validation_data)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10705882352941176, 'fraction_numerical': 0.028941176470588234, 'mean_word_length': 5.779106858054226, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 42, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '516639', 'license': 'MIT', 'n_tokens_mistral': 2815, 'n_tokens_neox': 2590, 'n_words': 656, 'path': '4.1 TFLite Model Maker_Icons-50.ipynb', 'repo_name': 'tvquynh/Hands-On-Transfer-Learning-with-TensorFlow-2.0-Video', 'size': '8500'}