ใน ep นี้เราจะสร้าง Convolutional Neural Network (ConvNet, CNN) ด้วยภาษา Python โดยใช้ TensorFlow สำหรับจำแนกรูปภาพแฟชั่น เสื้อผ้า กางเกง กระโปรง รองเท้า กระเป๋า แบบ Single Label Multiclass Classification จากชุดข้อมูล Fashion MNIST Dataset เซฟเป็น SavedModel แล้วใช้ TensorFlow Lite Converter ทำการ Convert เป็น TensorFlow Lite

Fashion MNIST Dataset

25 images from Fashion MNIST training set and display the class name below each image.
25 images from Fashion MNIST training set and display the class name below each image.

อ่านต่อ Fashion MNIST Dataset คืออะไร

TensorFlow Lite (TFLite) คืออะไร

How TensorFlow Lite Works - Pick a model, Convert, Deploy, Optimize. Credit https://www.tensorflow.org/lite
How TensorFlow Lite Works – Pick a model, Convert, Deploy, Optimize. Credit https://www.tensorflow.org/lite

อ่านต่อ TensorFlow Lite (TFLite) คืออะไร

TensorFlow Lite Converter คืออะไร

android gpu deligate demo.  Credit https://www.tensorflow.org/lite/performance/gpu
android gpu deligate demo. Credit https://www.tensorflow.org/lite/performance/gpu

อ่านต่อ TensorFlow Lite Converter คืออะไร

อ่านต่อ Post-Training Quantization คืออะไร

เรามาเริ่มกันเลยดีกว่า

Open In Colab
In [0]:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

Train Your Own Model and Convert It to TFLite

0. Setup

Uninstall TensorFlow เวอร์ชันที่อยู่ใน Colab, Install Version nightly แล้ว Restart Runtime

In [0]:
# !pip3 uninstall tensorflow
# !pip3 install tf-nightly

ใน ep นี้ เราจะใช้ TensorFlow 2 ด้วยคำสั่ง Magic %tensorflow_version 2.x (สำหรับ Google Colab)

In [0]:
try:
    %tensorflow_version 2.x
except:
    pass

1. Import

Import Library ที่เกี่ยวข้อง และ Print เลข Version

In [34]:
import pathlib
import numpy as np
import matplotlib.pylab as plt

import tensorflow as tf
import tensorflow_datasets as tfds
tfds.disable_progress_bar()

print("\u2022 Using TensorFlow Version:", tf.__version__)
print('\u2022 GPU Device Found.' if tf.test.is_gpu_available() else '\u2022 GPU Device Not Found. Running on CPU')
• Using TensorFlow Version: 2.1.0-rc1
• GPU Device Found.

2. Dataset

2.1 Split Data to Training / Validation / Test Set

เราจะใช้ TensorFlow Dataset tfds โหลดชุดข้อมูล Fashion MNIST Dataset ขึ้นมา แล้ว Split Training / Validation / Test Set ด้วยสัดส่วน 80/10/10

In [13]:
splits = tfds.Split.ALL.subsplit(weighted=(80, 10, 10))

splits, info = tfds.load('fashion_mnist', with_info=True, as_supervised=True, split = splits)

(train_examples, validation_examples, test_examples) = splits

num_examples = info.splits['train'].num_examples
num_classes = info.features['label'].num_classes

num_examples, num_classes
Out[13]:
(60000, 10)

จะได้ Dataset ที่มีข้อมูล Training Set 60,000 ตัวอย่าง มี 10 Class เนื่องจาก ชื่อ Class Name ไม่มีใน Dataset เราจะประกาศใส่ List ไว้ดังด้านล่าง

In [0]:
class_names = ['T-shirt_top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

สร้างไฟล์เก็บ Label ตั้งชื่อว่า labels.txt

In [0]:
# Create a labels.txt file with the class names
with open('labels.txt', 'w') as f:
    f.write('\n'.join(class_names))

ขนาดรูปของ Fashion MNIST เหมือนกับ MNIST คือ 28 x 28 Pixel

In [0]:
# The images in the dataset are 28 by 28 pixels.
IMG_SIZE = 28

2.2 Preprocessing data

ประกาศฟังก์ชัน ใช้ tf.image เพื่อแปลงรูปใน Dataset ให้อยู่ในรูปแบบที่โมเดลต้องการ ในที่นี้คือ Resize เป็นขนาดที่กำหนด และ Rescale ค่าสี จาก 0-255 หาร 255 ให้เป็น Float 0-1

In [0]:
def format_example(image, label):
    # Cast image to float32
    image = tf.dtypes.cast(image, tf.float32)
        
    # Normalize the image in the range [0, 1]
    image = image / 255.0
    
    return image, label

กำหนดขนาด Batch Size ให้ DataLoader

In [0]:
# Specify the batch size
BATCH_SIZE = 256

Shuffle สับไพ่ข้อมูล และแบ่งข้อมูลเป็น Batch ตาม Batch Size ที่กำหนดด้านบน

In [0]:
# Create Datasets
train_batches = train_examples.cache().shuffle(num_examples//4).batch(BATCH_SIZE).map(format_example).prefetch(1)
validation_batches = validation_examples.cache().batch(BATCH_SIZE).map(format_example)
test_batches = test_examples.batch(1).map(format_example)

3. Building the Model

สร้างโมเดล Convolutional Neural Network ที่มี 10 Class

In [0]:
model = tf.keras.Sequential([
    # Set the input shape to (28, 28, 1), kernel size=3, filters=16 and use ReLU activation,
    tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(28, 28, 1)),
      
    tf.keras.layers.MaxPooling2D(),
      
    # Set the number of filters to 32, kernel size to 3 and use ReLU activation 
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
      
    # Flatten the output layer to 1 dimension
    tf.keras.layers.Flatten(),
      
    # Add a fully connected layer with 64 hidden units and ReLU activation
    tf.keras.layers.Dense(64, activation='relu'),
      
    # Attach a final softmax classification head
    tf.keras.layers.Dense(10, activation='softmax')])

ใช้ Adam Optimizer ใช้ Categorical Cross Entropy Loss สำหรับงาน Multi-class Classification และ ใช้ Accuracy เป็น Metrics วัดผล

In [0]:
# Set the appropriate loss function and use accuracy as your metric
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

ดู Model Architecture ที่เราสร้างด้านบน

In [24]:
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 26, 26, 16)        160       
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 16)        0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 11, 11, 32)        4640      
_________________________________________________________________
flatten_2 (Flatten)          (None, 3872)              0         
_________________________________________________________________
dense_4 (Dense)              (None, 64)                247872    
_________________________________________________________________
dense_5 (Dense)              (None, 10)                650       
=================================================================
Total params: 253,322
Trainable params: 253,322
Non-trainable params: 0
_________________________________________________________________

4. Training the Model

In [0]:
model.fit(train_batches, 
          epochs=10,
          validation_data=validation_batches)

5. Export the Model

Export โมเดลที่เทรนเสร็จเรียบร้อยแล้ว ในรูปแบบ ไฟล์ SavedModel Format

In [0]:
export_dir = 'saved_model/1'

tf.saved_model.save(model, export_dir)

6. Convert ไฟล์ SavedModel ด้วย TFLite Converter

ใช้ TFLite Converter โหลดไฟล์โมเดล SavedModel ที่เรา Export ไว้ด้านบน

In [0]:
#@title เลือกโหมดที่จะทำ optimization
mode = "Speed" #@param ["Default", "Storage", "Speed"]

if mode == 'Storage':
    optimization = tf.lite.Optimize.OPTIMIZE_FOR_SIZE
elif mode == 'Speed':
    optimization = tf.lite.Optimize.OPTIMIZE_FOR_LATENCY
else:
    optimization = tf.lite.Optimize.DEFAULT

Convert โมเดลเป็นไฟล์ tflite แล้ว Save ลง Disk

In [0]:
converter = tf.lite.TFLiteConverter.from_saved_model(export_dir)
converter.experimental_new_converter = True

# Set the optimzations
converter.optimizations = mode

# Invoke the converter to finally generate the TFLite model
tflite_model = converter.convert()

ได้ไฟล์รวม ขนาด 1015768 Bytes

In [0]:
tflite_model_file = pathlib.Path('./model.tflite')
tflite_model_file.write_bytes(tflite_model)

7. Test โมเดล tflite ด้วย TFLite Intepreter

ใช้ TFLite Intepreter โหลดไฟล์ tflite ขึ้นมา

In [0]:
# Load TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()

input_index = interpreter.get_input_details()[0]["index"]
output_index = interpreter.get_output_details()[0]["index"]

สุ่มเลือกรูปจาก Test Set มาให้โมเดล ทำ Inference จำนวน 50 รูป

In [0]:
# Gather results for the randomly sampled test images
predictions = []
test_labels = []
test_images = []

for img, label in test_batches.take(50):
    interpreter.set_tensor(input_index, img)
    interpreter.invoke()
    predictions.append(interpreter.get_tensor(output_index))
    test_labels.append(label[0])
    test_images.append(np.array(img))

ฟังก์ชันสำหรับการพล็อตแสดงผล

In [0]:
#@title Utility functions for plotting
# Utilities for plotting

def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    
    img = np.squeeze(img)
    
    plt.imshow(img, cmap=plt.cm.binary)
    
    predicted_label = np.argmax(predictions_array)
    
    if predicted_label == true_label.numpy():
        color = 'green'
    else:
        color = 'red'
    
    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                         100*np.max(predictions_array),
                                         class_names[true_label]), color=color)

def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array[i], true_label[i]
    plt.grid(False)
    plt.xticks(list(range(10)), class_names, rotation='vertical')
    plt.yticks([])
    thisplot = plt.bar(range(10), predictions_array[0], color="#777777")
    plt.ylim([0, 1])
    predicted_label = np.argmax(predictions_array[0])

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('green')

นำผลลัพธ์ที่ได้ มาพล็อตแสดงรูป เปรียบเทียบ label และ prediction เราสามารถเลื่อนดู ตัวอย่างต่าง ๆ ได้ทั้ง 50 ตัวอย่าง

In [0]:
#@title Visualize the outputs { run: "auto" }
index = 44 #@param {type:"slider", min:1, max:50, step:1}
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(index, predictions, test_labels, test_images)
plt.show()
plot_value_array(index, predictions, test_labels)
plt.show()

8. Save และ Download ไฟล์ tflite

Save ไฟล์ และ Download โมเดล และ Label มาที่ Local Disk เพื่อนำไปใส่ Device ที่ต้องการต่อไป

หมายเหตุ: เราอาจจะต้อง กดอนุญาตให้ Web Browser สามารถ Download หลาย ๆ ไฟล์ได้พร้อมกัน

In [0]:
try:
    from google.colab import files
    
    files.download(tflite_model_file)
    files.download('labels.txt')
except:
    pass

9. Credit

แชร์ให้เพื่อน:

Keng Surapong on FacebookKeng Surapong on GithubKeng Surapong on Linkedin
Keng Surapong
Project Manager at Bua Labs
The ultimate test of your knowledge is your capacity to convey it to another.

Published by Keng Surapong

The ultimate test of your knowledge is your capacity to convey it to another.

Enable Notifications    Ok No thanks