Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gheesung/557397e5f777483939de38af081b0a55 to your computer and use it in GitHub Desktop.
Save gheesung/557397e5f777483939de38af081b0a55 to your computer and use it in GitHub Desktop.
Image Classification With Keras for edge TPU using TF2
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Image Classification With Keras for edge TPU using TF2",
"version": "0.3.2",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true,
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/gheesung/557397e5f777483939de38af081b0a55/image-classification-with-keras-for-edge-tpu-using-tf2.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "prOt_VofnYCo",
"colab_type": "text"
},
"source": [
"#Image Classification/Quantisation/Transfer Learning/Edge TPU.\n",
"\n",
"."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "OakAxtbW2hbA",
"colab_type": "text"
},
"source": [
"# Transfer Learning using Mobilenet V1\n",
"\n",
"This notebook demostrate how to perform Transfer Learning, post training quantization and then convert to edge TPU format to perform inferencing using edge TPU.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "11pSbc28mFIb",
"colab_type": "text"
},
"source": [
"## Install Tensorflow 2.0"
]
},
{
"cell_type": "code",
"metadata": {
"id": "6IKHm_2YfTj-",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 546
},
"outputId": "4527cc75-ac95-4cda-bb63-63dde79e51a2"
},
"source": [
"# Install Tensorflow 2.0\n",
"!pip install tensorflow-gpu==2.0-beta1"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"Collecting tensorflow-gpu==2.0-beta1\n",
"\u001b[?25l Downloading https://files.pythonhosted.org/packages/2b/53/e18c5e7a2263d3581a979645a185804782e59b8e13f42b9c3c3cfb5bb503/tensorflow_gpu-2.0.0b1-cp36-cp36m-manylinux1_x86_64.whl (348.9MB)\n",
"\u001b[K |████████████████████████████████| 348.9MB 58kB/s \n",
"\u001b[?25hRequirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.1.0)\n",
"Collecting tf-estimator-nightly<1.14.0.dev2019060502,>=1.14.0.dev2019060501 (from tensorflow-gpu==2.0-beta1)\n",
"\u001b[?25l Downloading https://files.pythonhosted.org/packages/32/dd/99c47dd007dcf10d63fd895611b063732646f23059c618a373e85019eb0e/tf_estimator_nightly-1.14.0.dev2019060501-py2.py3-none-any.whl (496kB)\n",
"\u001b[K |████████████████████████████████| 501kB 46.0MB/s \n",
"\u001b[?25hRequirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.11.2)\n",
"Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (0.7.1)\n",
"Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.12.0)\n",
"Requirement already satisfied: google-pasta>=0.1.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (0.1.7)\n",
"Requirement already satisfied: keras-applications>=1.0.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.0.8)\n",
"Requirement already satisfied: gast>=0.2.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (0.2.2)\n",
"Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (3.7.1)\n",
"Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (0.8.0)\n",
"Collecting tb-nightly<1.14.0a20190604,>=1.14.0a20190603 (from tensorflow-gpu==2.0-beta1)\n",
"\u001b[?25l Downloading https://files.pythonhosted.org/packages/a4/96/571b875cd81dda9d5dfa1422a4f9d749e67c0a8d4f4f0b33a4e5f5f35e27/tb_nightly-1.14.0a20190603-py3-none-any.whl (3.1MB)\n",
"\u001b[K |████████████████████████████████| 3.1MB 51.1MB/s \n",
"\u001b[?25hRequirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.15.0)\n",
"Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.1.0)\n",
"Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (0.33.4)\n",
"Requirement already satisfied: numpy<2.0,>=1.14.5 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.0-beta1) (1.16.4)\n",
"Requirement already satisfied: h5py in /usr/local/lib/python3.6/dist-packages (from keras-applications>=1.0.6->tensorflow-gpu==2.0-beta1) (2.8.0)\n",
"Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from protobuf>=3.6.1->tensorflow-gpu==2.0-beta1) (41.0.1)\n",
"Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/dist-packages (from tb-nightly<1.14.0a20190604,>=1.14.0a20190603->tensorflow-gpu==2.0-beta1) (0.15.5)\n",
"Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/dist-packages (from tb-nightly<1.14.0a20190604,>=1.14.0a20190603->tensorflow-gpu==2.0-beta1) (3.1.1)\n",
"Installing collected packages: tf-estimator-nightly, tb-nightly, tensorflow-gpu\n",
"Successfully installed tb-nightly-1.14.0a20190603 tensorflow-gpu-2.0.0b1 tf-estimator-nightly-1.14.0.dev2019060501\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "2Z4E3BNH5VUB",
"colab_type": "code",
"outputId": "748127b5-33ce-4a40-8497-b49ce058888e",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 54
}
},
"source": [
"from __future__ import absolute_import, division, print_function, unicode_literals\n",
"\n",
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"from tensorflow.keras import layers, applications\n",
"print(tf.version.VERSION)\n",
"print(tf.keras.__version__)"
],
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"text": [
"2.0.0-beta1\n",
"2.2.4-tf\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "qJKw0elEWY3x",
"colab_type": "code",
"outputId": "5b69bae9-0815-46c0-d7c3-46055aa5f1a6",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
}
},
"source": [
"import numpy as np\n",
"\n",
"from tensorflow.keras.applications import MobileNet\n",
"\n",
"from tensorflow.keras.optimizers import Adam\n",
"from tensorflow.keras.metrics import categorical_crossentropy\n",
"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
"from tensorflow.keras.preprocessing import image\n",
"from tensorflow.keras.models import Model\n",
"from keras.applications import imagenet_utils\n",
"from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\n",
"from tensorflow.keras.applications.mobilenet import preprocess_input"
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mALpuuZql_PD",
"colab_type": "text"
},
"source": [
"## Get the flower dataset"
]
},
{
"cell_type": "code",
"metadata": {
"id": "t-6gYty7R3u8",
"colab_type": "code",
"outputId": "9848618b-e32c-4a3f-e467-ede7dcf47135",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 90
}
},
"source": [
"# Download the flower photos\n",
"\n",
"%cd /content\n",
"!curl -LO http://download.tensorflow.org/example_images/flower_photos.tgz\n",
"!tar xzf flower_photos.tgz"
],
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"text": [
"/content\n",
" % Total % Received % Xferd Average Speed Time Time Time Current\n",
" Dload Upload Total Spent Left Speed\n",
"100 218M 100 218M 0 0 82.4M 0 0:00:02 0:00:02 --:--:-- 82.5M\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ppyoaE89nZkV",
"colab_type": "text"
},
"source": [
"## Setup the training parameters"
]
},
{
"cell_type": "code",
"metadata": {
"id": "qN8wA-GN3AJK",
"colab_type": "code",
"colab": {}
},
"source": [
"# the parameters\n",
"IMAGE_SIZE = 224\n",
"ALPHA=1.00\n",
"EPOCHS=20"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "wsWFPaOcOyS-",
"colab_type": "code",
"colab": {}
},
"source": [
"def prepare_image(file):\n",
" img_path = ''\n",
" img = image.load_img(img_path + file, target_size=(IMAGE_SIZE, IMAGE_SIZE))\n",
" img_array = image.img_to_array(img)\n",
" #img_array= img_array/255.0\n",
" img_array_expanded_dims = np.expand_dims(img_array, axis=0)\n",
" return preprocess_input(img_array_expanded_dims)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "TchVYHdLnfNd",
"colab_type": "text"
},
"source": [
"## Define the model\n",
"For this example, I have created a few layers for transfer learning."
]
},
{
"cell_type": "code",
"metadata": {
"id": "S7uWGZLdE55g",
"colab_type": "code",
"colab": {}
},
"source": [
"def build_keras_model():\n",
" base_model=MobileNet(input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3), alpha = ALPHA, \n",
" include_top = False, weights = \"imagenet\", classes = 1000 )\n",
"\n",
" for layer in base_model.layers:\n",
" layer.trainable = False\n",
" \n",
" # the last few layers\n",
" # for the flowers dataset, we are predicting 5 types of flower which is reason for the final layer to have 5 outputs.\n",
"\n",
" x=base_model.output\n",
" x=GlobalAveragePooling2D()(x)\n",
" x=Dense(100,activation='relu')(x) #we add dense layers so that the model can learn more complex functions and classify for better results.\n",
" x=Dropout(0.5)(x)\n",
" x=Dense(50,activation='relu')(x) #dense layer 3\n",
" preds=Dense(5,activation='softmax')(x) #final layer with softmax activation \n",
" model=Model(inputs=base_model.input,outputs=preds)\n",
" for layer in model.layers[86:]:\n",
" layer.trainable=True \n",
" return model"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "TcRKnfeDn1OO",
"colab_type": "text"
},
"source": [
"### ImageDataGenerator"
]
},
{
"cell_type": "code",
"metadata": {
"id": "BayNJNWYSbr0",
"colab_type": "code",
"outputId": "3821908d-7ba8-4ea3-80e7-97996e30b88f",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
}
},
"source": [
"train_datagen=ImageDataGenerator(preprocessing_function=preprocess_input) #included in our dependencies\n",
"\n",
"train_generator=train_datagen.flow_from_directory('/content/flower_photos',\n",
" target_size=(IMAGE_SIZE,IMAGE_SIZE),\n",
" color_mode='rgb',\n",
" batch_size=32,\n",
" class_mode='categorical', shuffle=True)"
],
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"text": [
"Found 3670 images belonging to 5 classes.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pS800TZVn7fa",
"colab_type": "text"
},
"source": [
"###Training"
]
},
{
"cell_type": "code",
"metadata": {
"id": "R6hbts_Sclxu",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"outputId": "7e01b6a4-a1ba-4bfc-87ff-158d11d1bf8b"
},
"source": [
"#train\n",
"step_size_train=train_generator.n//train_generator.batch_size\n",
"model = build_keras_model()\n",
"model.summary()\n",
"model.compile(optimizer='Adam',loss='categorical_crossentropy',metrics=['accuracy'])\n",
"model.fit_generator(generator=train_generator,steps_per_epoch=step_size_train,epochs=EPOCHS)\n",
"model.save('model.h5')"
],
"execution_count": 9,
"outputs": [
{
"output_type": "stream",
"text": [
"Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.6/mobilenet_1_0_224_tf_no_top.h5\n",
"17227776/17225924 [==============================] - 3s 0us/step\n",
"Model: \"model\"\n",
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"input_1 (InputLayer) [(None, 224, 224, 3)] 0 \n",
"_________________________________________________________________\n",
"conv1_pad (ZeroPadding2D) (None, 225, 225, 3) 0 \n",
"_________________________________________________________________\n",
"conv1 (Conv2D) (None, 112, 112, 32) 864 \n",
"_________________________________________________________________\n",
"conv1_bn (BatchNormalization (None, 112, 112, 32) 128 \n",
"_________________________________________________________________\n",
"conv1_relu (ReLU) (None, 112, 112, 32) 0 \n",
"_________________________________________________________________\n",
"conv_dw_1 (DepthwiseConv2D) (None, 112, 112, 32) 288 \n",
"_________________________________________________________________\n",
"conv_dw_1_bn (BatchNormaliza (None, 112, 112, 32) 128 \n",
"_________________________________________________________________\n",
"conv_dw_1_relu (ReLU) (None, 112, 112, 32) 0 \n",
"_________________________________________________________________\n",
"conv_pw_1 (Conv2D) (None, 112, 112, 64) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_1_bn (BatchNormaliza (None, 112, 112, 64) 256 \n",
"_________________________________________________________________\n",
"conv_pw_1_relu (ReLU) (None, 112, 112, 64) 0 \n",
"_________________________________________________________________\n",
"conv_pad_2 (ZeroPadding2D) (None, 113, 113, 64) 0 \n",
"_________________________________________________________________\n",
"conv_dw_2 (DepthwiseConv2D) (None, 56, 56, 64) 576 \n",
"_________________________________________________________________\n",
"conv_dw_2_bn (BatchNormaliza (None, 56, 56, 64) 256 \n",
"_________________________________________________________________\n",
"conv_dw_2_relu (ReLU) (None, 56, 56, 64) 0 \n",
"_________________________________________________________________\n",
"conv_pw_2 (Conv2D) (None, 56, 56, 128) 8192 \n",
"_________________________________________________________________\n",
"conv_pw_2_bn (BatchNormaliza (None, 56, 56, 128) 512 \n",
"_________________________________________________________________\n",
"conv_pw_2_relu (ReLU) (None, 56, 56, 128) 0 \n",
"_________________________________________________________________\n",
"conv_dw_3 (DepthwiseConv2D) (None, 56, 56, 128) 1152 \n",
"_________________________________________________________________\n",
"conv_dw_3_bn (BatchNormaliza (None, 56, 56, 128) 512 \n",
"_________________________________________________________________\n",
"conv_dw_3_relu (ReLU) (None, 56, 56, 128) 0 \n",
"_________________________________________________________________\n",
"conv_pw_3 (Conv2D) (None, 56, 56, 128) 16384 \n",
"_________________________________________________________________\n",
"conv_pw_3_bn (BatchNormaliza (None, 56, 56, 128) 512 \n",
"_________________________________________________________________\n",
"conv_pw_3_relu (ReLU) (None, 56, 56, 128) 0 \n",
"_________________________________________________________________\n",
"conv_pad_4 (ZeroPadding2D) (None, 57, 57, 128) 0 \n",
"_________________________________________________________________\n",
"conv_dw_4 (DepthwiseConv2D) (None, 28, 28, 128) 1152 \n",
"_________________________________________________________________\n",
"conv_dw_4_bn (BatchNormaliza (None, 28, 28, 128) 512 \n",
"_________________________________________________________________\n",
"conv_dw_4_relu (ReLU) (None, 28, 28, 128) 0 \n",
"_________________________________________________________________\n",
"conv_pw_4 (Conv2D) (None, 28, 28, 256) 32768 \n",
"_________________________________________________________________\n",
"conv_pw_4_bn (BatchNormaliza (None, 28, 28, 256) 1024 \n",
"_________________________________________________________________\n",
"conv_pw_4_relu (ReLU) (None, 28, 28, 256) 0 \n",
"_________________________________________________________________\n",
"conv_dw_5 (DepthwiseConv2D) (None, 28, 28, 256) 2304 \n",
"_________________________________________________________________\n",
"conv_dw_5_bn (BatchNormaliza (None, 28, 28, 256) 1024 \n",
"_________________________________________________________________\n",
"conv_dw_5_relu (ReLU) (None, 28, 28, 256) 0 \n",
"_________________________________________________________________\n",
"conv_pw_5 (Conv2D) (None, 28, 28, 256) 65536 \n",
"_________________________________________________________________\n",
"conv_pw_5_bn (BatchNormaliza (None, 28, 28, 256) 1024 \n",
"_________________________________________________________________\n",
"conv_pw_5_relu (ReLU) (None, 28, 28, 256) 0 \n",
"_________________________________________________________________\n",
"conv_pad_6 (ZeroPadding2D) (None, 29, 29, 256) 0 \n",
"_________________________________________________________________\n",
"conv_dw_6 (DepthwiseConv2D) (None, 14, 14, 256) 2304 \n",
"_________________________________________________________________\n",
"conv_dw_6_bn (BatchNormaliza (None, 14, 14, 256) 1024 \n",
"_________________________________________________________________\n",
"conv_dw_6_relu (ReLU) (None, 14, 14, 256) 0 \n",
"_________________________________________________________________\n",
"conv_pw_6 (Conv2D) (None, 14, 14, 512) 131072 \n",
"_________________________________________________________________\n",
"conv_pw_6_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_6_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_dw_7 (DepthwiseConv2D) (None, 14, 14, 512) 4608 \n",
"_________________________________________________________________\n",
"conv_dw_7_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_dw_7_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pw_7 (Conv2D) (None, 14, 14, 512) 262144 \n",
"_________________________________________________________________\n",
"conv_pw_7_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_7_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_dw_8 (DepthwiseConv2D) (None, 14, 14, 512) 4608 \n",
"_________________________________________________________________\n",
"conv_dw_8_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_dw_8_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pw_8 (Conv2D) (None, 14, 14, 512) 262144 \n",
"_________________________________________________________________\n",
"conv_pw_8_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_8_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_dw_9 (DepthwiseConv2D) (None, 14, 14, 512) 4608 \n",
"_________________________________________________________________\n",
"conv_dw_9_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_dw_9_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pw_9 (Conv2D) (None, 14, 14, 512) 262144 \n",
"_________________________________________________________________\n",
"conv_pw_9_bn (BatchNormaliza (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_9_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_dw_10 (DepthwiseConv2D) (None, 14, 14, 512) 4608 \n",
"_________________________________________________________________\n",
"conv_dw_10_bn (BatchNormaliz (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_dw_10_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pw_10 (Conv2D) (None, 14, 14, 512) 262144 \n",
"_________________________________________________________________\n",
"conv_pw_10_bn (BatchNormaliz (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_10_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_dw_11 (DepthwiseConv2D) (None, 14, 14, 512) 4608 \n",
"_________________________________________________________________\n",
"conv_dw_11_bn (BatchNormaliz (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_dw_11_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pw_11 (Conv2D) (None, 14, 14, 512) 262144 \n",
"_________________________________________________________________\n",
"conv_pw_11_bn (BatchNormaliz (None, 14, 14, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_pw_11_relu (ReLU) (None, 14, 14, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pad_12 (ZeroPadding2D) (None, 15, 15, 512) 0 \n",
"_________________________________________________________________\n",
"conv_dw_12 (DepthwiseConv2D) (None, 7, 7, 512) 4608 \n",
"_________________________________________________________________\n",
"conv_dw_12_bn (BatchNormaliz (None, 7, 7, 512) 2048 \n",
"_________________________________________________________________\n",
"conv_dw_12_relu (ReLU) (None, 7, 7, 512) 0 \n",
"_________________________________________________________________\n",
"conv_pw_12 (Conv2D) (None, 7, 7, 1024) 524288 \n",
"_________________________________________________________________\n",
"conv_pw_12_bn (BatchNormaliz (None, 7, 7, 1024) 4096 \n",
"_________________________________________________________________\n",
"conv_pw_12_relu (ReLU) (None, 7, 7, 1024) 0 \n",
"_________________________________________________________________\n",
"conv_dw_13 (DepthwiseConv2D) (None, 7, 7, 1024) 9216 \n",
"_________________________________________________________________\n",
"conv_dw_13_bn (BatchNormaliz (None, 7, 7, 1024) 4096 \n",
"_________________________________________________________________\n",
"conv_dw_13_relu (ReLU) (None, 7, 7, 1024) 0 \n",
"_________________________________________________________________\n",
"conv_pw_13 (Conv2D) (None, 7, 7, 1024) 1048576 \n",
"_________________________________________________________________\n",
"conv_pw_13_bn (BatchNormaliz (None, 7, 7, 1024) 4096 \n",
"_________________________________________________________________\n",
"conv_pw_13_relu (ReLU) (None, 7, 7, 1024) 0 \n",
"_________________________________________________________________\n",
"global_average_pooling2d (Gl (None, 1024) 0 \n",
"_________________________________________________________________\n",
"dense (Dense) (None, 100) 102500 \n",
"_________________________________________________________________\n",
"dropout (Dropout) (None, 100) 0 \n",
"_________________________________________________________________\n",
"dense_1 (Dense) (None, 50) 5050 \n",
"_________________________________________________________________\n",
"dense_2 (Dense) (None, 5) 255 \n",
"=================================================================\n",
"Total params: 3,336,669\n",
"Trainable params: 107,805\n",
"Non-trainable params: 3,228,864\n",
"_________________________________________________________________\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"WARNING: Logging before flag parsing goes to stderr.\n",
"W0721 14:29:34.174033 140118843246464 deprecation.py:323] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_grad.py:1250: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use tf.where in 2.0, which has the same broadcast rule as np.where\n"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"114/114 [==============================] - 17s 149ms/step - loss: 0.9565 - accuracy: 0.6374\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1RuVSgLOoHVO",
"colab_type": "text"
},
"source": [
"### Representative dataset"
]
},
{
"cell_type": "code",
"metadata": {
"id": "WMfI30oXiOU7",
"colab_type": "code",
"colab": {}
},
"source": [
"def representative_dataset_gen():\n",
" for i in range(0,5):\n",
" x,y=train_generator.next()\n",
" image=x[i:i+1]\n",
" yield [image]\n"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ht625PTXoSnp",
"colab_type": "text"
},
"source": [
"### Dummy Test for the tflite model and h2 model (optional)\n",
"\n",
"This is to test both models have the similar result."
]
},
{
"cell_type": "code",
"metadata": {
"id": "TYmVAmDKObSA",
"colab_type": "code",
"outputId": "74ee19a2-a37f-46cc-a8b2-611375c89d54",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 54
}
},
"source": [
"#https://www.tensorflow.org/lite/r2/convert/python_api\n",
"# Convert the model.\n",
"converter = tf.lite.TFLiteConverter.from_keras_model(model)\n",
"tflite_model = converter.convert()\n",
"\n",
"# Load TFLite model and allocate tensors.\n",
"interpreter = tf.lite.Interpreter(model_content=tflite_model)\n",
"interpreter.allocate_tensors()\n",
"\n",
"# Get input and output tensors.\n",
"input_details = interpreter.get_input_details()\n",
"output_details = interpreter.get_output_details()\n",
"\n",
"# Test the TensorFlow Lite model on random input data.\n",
"input_shape = input_details[0]['shape']\n",
"input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)\n",
"interpreter.set_tensor(input_details[0]['index'], input_data)\n",
"\n",
"interpreter.invoke()\n",
"\n",
"# The function `get_tensor()` returns a copy of the tensor data.\n",
"# Use `tensor()` in order to get a pointer to the tensor.\n",
"tflite_results = interpreter.get_tensor(output_details[0]['index'])\n",
"\n",
"# Test the TensorFlow model on random input data.\n",
"tf_results = model(tf.constant(input_data))\n",
"\n",
"# Compare the result.\n",
"for tf_result, tflite_result in zip(tf_results, tflite_results):\n",
" np.testing.assert_almost_equal(tf_result, tflite_result, decimal=5)\n",
" print('tfresult', tf_results)\n",
" print('tflite', tflite_result)"
],
"execution_count": 11,
"outputs": [
{
"output_type": "stream",
"text": [
"tfresult tf.Tensor([[0.20722924 0.7139299 0.04168681 0.02492464 0.01222938]], shape=(1, 5), dtype=float32)\n",
"tflite [0.20722835 0.7139314 0.04168659 0.02492442 0.01222929]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "m3S809JLomL1",
"colab_type": "text"
},
"source": [
"### Convert to tflite model"
]
},
{
"cell_type": "code",
"metadata": {
"id": "125-TnWAdfYD",
"colab_type": "code",
"colab": {}
},
"source": [
"# Convert to tflite model\n",
"converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file('model.h5')\n",
"converter.representative_dataset = representative_dataset_gen\n",
"converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]\n",
"converter.inference_input_type = tf.uint8\n",
"converter.inference_output_type = tf.uint8\n",
"converter.optimizations = [tf.lite.Optimize.DEFAULT]\n",
"\n",
"tflite_model = converter.convert()\n",
"with open('model.tflite', 'wb') as o_:\n",
" o_.write(tflite_model) "
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "_Xxud2zyXAfU",
"colab_type": "code",
"outputId": "578c4786-3d2c-4e19-bd15-318c261f045b",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
}
},
"source": [
"# do a random test to confirm the model is working\n",
"preprocessed_image = prepare_image('/content/flower_photos/roses/13342823005_16d3df58df_n.jpg')\n",
"predictions_flower = model.predict(preprocessed_image) \n",
"print (predictions_flower)\n"
],
"execution_count": 13,
"outputs": [
{
"output_type": "stream",
"text": [
"[[0.12399618 0.01161416 0.79529613 0.00525301 0.06384043]]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XYtSUfWnouln",
"colab_type": "text"
},
"source": [
"### Test the tensorflowlite model"
]
},
{
"cell_type": "code",
"metadata": {
"id": "UcbRv2QP824h",
"colab_type": "code",
"outputId": "08322011-6e69-4b56-a53c-cbd6f89dcd34",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
}
},
"source": [
"import numpy as np\n",
"import tensorflow as tf\n",
"\n",
"# Load TFLite model and allocate tensors.\n",
"interpreter = tf.lite.Interpreter(model_path=\"model.tflite\")\n",
"interpreter.allocate_tensors()\n",
"\n",
"# Get input and output tensors.\n",
"input_details = interpreter.get_input_details()\n",
"output_details = interpreter.get_output_details()\n",
"\n",
"def quantize(real_value):\n",
" std, mean = input_details[0]['quantization']\n",
" return (real_value/std + mean).astype(np.uint8)\n",
"\n",
"input_shape = input_details[0]['shape']\n",
"preprocessed_image = prepare_image('/content/flower_photos/tulips/116343334_9cb4acdc57_n.jpg')\n",
"sample_input = quantize(preprocessed_image).reshape(input_shape)\n",
" \n",
"# Test model on random input data.\n",
"# change the following line to feed into your own data.\n",
"interpreter.set_tensor(input_details[0]['index'], sample_input)\n",
"\n",
"interpreter.invoke()\n",
"output_data = interpreter.get_tensor(output_details[0]['index'])\n",
"print(output_data/255)\n",
"\n",
"\n",
"\n"
],
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"text": [
"[[0.07843137 0.00392157 0.18823529 0.02745098 0.70588235]]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XKv8AsmJo5tj",
"colab_type": "text"
},
"source": [
"## Convert to Edge TPU format"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Yx-rWl1HIYEc",
"colab_type": "code",
"outputId": "2021245d-0782-4ba7-81f3-d03dae8f26b4",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 363
}
},
"source": [
"%%bash\n",
"# install edgetpu_compiler\n",
"echo \"deb https://packages.cloud.google.com/apt coral-edgetpu-stable main\" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list\n",
"sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6A030B21BA07F4FB\n",
"\n",
"sudo apt update > /dev/null\n",
"sudo apt install edgetpu > /dev/null\n"
],
"execution_count": 15,
"outputs": [
{
"output_type": "stream",
"text": [
"deb https://packages.cloud.google.com/apt coral-edgetpu-stable main\n",
"Executing: /tmp/apt-key-gpghome.xzG4pvhOxe/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys 6A030B21BA07F4FB\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"Warning: apt-key output should not be parsed (stdout is not a terminal)\n",
"gpg: key 6A030B21BA07F4FB: public key \"Google Cloud Packages Automatic Signing Key <[email protected]>\" imported\n",
"gpg: Total number processed: 1\n",
"gpg: imported: 1\n",
"\n",
"WARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n",
"\n",
"\n",
"WARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n",
"\n",
"debconf: unable to initialize frontend: Dialog\n",
"debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76, <> line 5.)\n",
"debconf: falling back to frontend: Readline\n",
"debconf: unable to initialize frontend: Readline\n",
"debconf: (This frontend requires a controlling tty.)\n",
"debconf: falling back to frontend: Teletype\n",
"dpkg-preconfigure: unable to re-open stdin: \n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "s4Ha_vF9Ipq8",
"colab_type": "code",
"outputId": "b334d8fa-8e55-412e-f431-7259f8fc588c",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 472
}
},
"source": [
"!edgetpu_compiler --show_operations 'model.tflite'"
],
"execution_count": 16,
"outputs": [
{
"output_type": "stream",
"text": [
"Edge TPU Compiler version 1.0.249710469\n",
"INFO: Initialized TensorFlow Lite runtime.\n",
"\n",
"Model compiled successfully in 307 ms.\n",
"\n",
"Input model: model.tflite\n",
"Input size: 3.45MiB\n",
"Output model: model_edgetpu.tflite\n",
"Output size: 3.53MiB\n",
"On-chip memory available for caching model parameters: 7.14MiB\n",
"On-chip memory used for caching model parameters: 3.43MiB\n",
"Off-chip memory used for streaming uncached model parameters: 0.00B\n",
"Number of Edge TPU subgraphs: 1\n",
"Total number of operations: 39\n",
"Operation log: model_edgetpu.log\n",
"\n",
"Operator Count Status\n",
"\n",
"SOFTMAX 1 Mapped to Edge TPU\n",
"FULLY_CONNECTED 3 Mapped to Edge TPU\n",
"QUANTIZE 2 Mapped to Edge TPU\n",
"PAD 5 Mapped to Edge TPU\n",
"CONV_2D 14 Mapped to Edge TPU\n",
"DEPTHWISE_CONV_2D 13 Mapped to Edge TPU\n",
"MEAN 1 Mapped to Edge TPU\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YY2vTRWPG7P_",
"colab_type": "text"
},
"source": [
"# Download to local drive"
]
},
{
"cell_type": "code",
"metadata": {
"id": "qM2ngall41ZC",
"colab_type": "code",
"colab": {}
},
"source": [
"from google.colab import files\n",
"\n",
"files.download('/content/model_edgetpu.tflite')"
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment