Создайте модель Tf Lite, используя трансферное обучение на предварительно обученной модели Tensorflow, оптимизируйте ее и выполните выводы.
В этой статье вы научитесь использовать предварительно обученную модель, применять трансферное обучение, преобразовывать модель в TF Lite, применять оптимизацию и делать выводы из модели TFLite.
Предварительные требования:
Базовое введение в TensorFlow Lite
Tensorflow 2.0
Создайте набор данных
Я загрузил набор данных и разархивировал файл в соответствии со следующей структурой.
Код Python для извлечения данных и создания данных в соответствии со структурой ниже доступен здесь.
Импорт необходимых библиотек
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img from tensorflow.python.keras.applications import imagenet_utils from tensorflow.python.keras.layers import Dense,GlobalAveragePooling2D from tensorflow.keras.applications import DenseNet121 from tensorflow.python.keras.applications.densenet import preprocess_input from tensorflow.keras.models import Model
Установка основных параметров тренировки
BASE_PATH = 'Data\\dogs-vs-cats\\train\\' TRAIN_PATH='Data\\dogs-vs-cats\\train_data\\' VAL_PATH='Data\\dogs-vs-cats\\validation_data\\' batch_size = 32 epochs = 60 IMG_HEIGHT = 150 IMG_WIDTH = 150
Измените масштаб и примените различные улучшения к обучающему изображению
train_image_generator = ImageDataGenerator( rescale=1./255, rotation_range=45, width_shift_range=.15, height_shift_range=.15, horizontal_flip=True, zoom_range=0.3)
Изменить масштаб данных проверки
validation_image_generator = ImageDataGenerator(rescale=1./255)
Создание пакетов нормализованных данных для набора данных обучения и проверки
train_data_gen = train_image_generator.flow_from_directory(batch_size = batch_size, directory=TRAIN_PATH, shuffle=True, target_size=(IMG_HEIGHT, IMG_WIDTH), class_mode='categorical') val_data_gen = validation_image_generator.flow_from_directory(batch_size = batch_size, directory=VAL_PATH, target_size=(IMG_HEIGHT, IMG_WIDTH), class_mode='categorical')
Применение трансферного обучения на предварительно обученной модели
Вы можете использовать любую из предварительно обученных моделей. Я использовал DenseNet121, который имеет 427 слоев.
# Create the base model from the pre-trained model MobileNet V2 base_model = tf.keras.applications.DenseNet121( input_shape=(IMG_WIDTH, IMG_HEIGHT,3), include_top=False, weights='imagenet')
Замораживание всех весов базовой предварительно обученной модели и добавление нескольких слоев поверх предварительно обученной модели
base_model.trainable = False x=base_model.output x=Flatten()(x) x=Dense(512,activation='relu')(x) output=Dense(2,activation='softmax')(x) model=Model(inputs=base_model.input,outputs=output) model.summary()
Вы можете видеть, что веса предварительно обученной модели нельзя обучить, и можно обучить только веса добавленных слоев.
Вы можете сделать несколько слоев предварительно обученных весов модели для обучения, чтобы помочь изучить настраиваемый набор данных для большей точности.
TRAINABLE_LAYERS= len(model.layers)-len(base_model.layers)+5 print(TRAINABLE_LAYERS) for layer in model.layers[:-TRAINABLE_LAYERS]: layer.trainable=False for layer in model.layers[-TRAINABLE_LAYERS:]: layer.trainable=True
вы можете увидеть, что количество обучаемых параметров увеличилось, и это также увеличит время обучения.
Скомпилируйте и обучите модель на пользовательском наборе данных
model.compile(loss='categorical_crossentropy', optimizer=tf.keras.optimizers.RMSprop(lr=2e-5), metrics=['acc']) epochs=20 step_size_train=train_data_gen.n//train_data_gen.batch_size history =model.fit_generator(generator=train_data_gen, steps_per_epoch=step_size_train, epochs=epochs)
После того, как модель скомпилирована и обучена, мы можем приступить к преобразованию модели в TF Lite, как показано ниже.
Преобразование предварительно обученной модели передачи обучения в TF Lite
После того, как вы обучили Модель, вам нужно будет сохранить Модель.
Сохраненная модель сериализует архитектуру модели, веса и смещения, а также конфигурацию обучения в одном файле. Сохраненную модель можно легко использовать для публикации или развертывания моделей.
#save your model in the SavedModel format export_dir = 'saved_model' tf.saved_model.save(model, export_dir)
SavedModel содержит полную программу TensorFlow, включая веса и вычисления.
saved_model - это мета-график, сохраненный в export_dir,, который преобразуется в модель TFLite с помощью lite.TFLiteConverter.
# Converting a SavedModel to a TensorFlow Lite model. converter = tf.lite.TFLiteConverter.from_saved_model(export_dir) tflite_model = converter.convert()
Запись модели TFLIte с плоским буфером в двоичный файл, размер которого в настоящее время составляет 61 МБ.
open("model_tl.tflite", "wb").write(tflite_model)
Оптимизация модели
Модели в Edge должны быть легкими и иметь низкую задержку для выполнения выводов. Облегченная модель с низкой задержкой достигается за счет уменьшения объема вычислений, необходимых для прогнозирования, что достигается путем применения квантованной оптимизации к модели TF Lite.
Квантование снижает точность чисел, используемых для представления различных параметров модели TensorFlow, чтобы сделать модель легкой.
Квантование применяется к весу и активациям.
optimize="Speed" if optimize=='Speed': converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_LATENCY] elif optimize=='Storage': converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE] else: converter.optimizations = [tf.lite.Optimize.DEFAULT] #reduce the size of a floating point model by quantizing the weights to float16 converter.target_spec.supported_types = [tf.float16] tflite_quant_model = converter.convert() #save the quanitized model toa binary file open("model_quant_tl.tflite", "wb").write(tflite_quant_model)
Здесь мы оптимизировали модель по скорости, а затем преобразовали 32-разрядные числа с плавающей запятой в 16-разрядные числа с плавающей запятой, чтобы уменьшить размер модели.
Модель TF Lite, которая составляла 61 МБ, теперь уменьшена до 30 МБ после применения оптимизации.
Оптимизированную модель можно развернуть на любом из пограничных устройств, где нам понадобится tflite_runtime.interpreter.
Выполнение выводов на краю
Загрузка интерпретатора с оптимизированной моделью .tflite, содержащей график выполнения модели, и выделение тензоров
import tflite_runtime.interpreter as tflite # Load TFLite model and allocate tensors. interpreter = tf.lite.Interpreter(model_content=tflite_quant_model) #allocate the tensors interpreter.allocate_tensors()
Получите входные и выходные тензоры.
#get input and output tensors input_details = interpreter.get_input_details() output_details = interpreter.get_output_details()
Предварительная обработка входных данных
Входное изображение, для которого мы хотим сделать вывод, должно соответствовать входным данным для модели.
Считайте изображение, декодируйте в тензор и предварительно обработайте изображение до необходимого размера, преобразуйте его в float16 и добавьте размер пакета
import cv2 # Read the image and decode to a tensor image_path='Data\\dogs-vs-cats\\test1\\151.jpg' img = cv2.imread(image_path) img = cv2.resize(img,(IMG_WIDTH,IMG_HEIGHT)) #Preprocess the image to required size and cast input_shape = input_details[0]['shape'] input_tensor= np.array(np.expand_dims(img,0), dtype=np.float16)
Ниже представлено изображение, которое мы пытаемся предсказать.
Выполните вывод
Направьте входные данные в 0-й массив для ввода тензора, задав тензор. Выполните вывод, вызвав интерпретатор
#set the tensor to point to the input data to be inferred input_index = interpreter.get_input_details()[0]["index"] interpreter.set_tensor(input_index, input_tensor) #Run the inference interpreter.invoke() output_details = interpreter.get_output_details()
Интерпретация выходного тензора для нашей классификации изображений
output_data = interpreter.get_tensor(output_details[0]['index']) results = np.squeeze(output_data) top_k = results.argsort() for label, idx in train_data_gen.class_indices.items(): if top_k[idx]==1: print("Prediction: " label)
На выходе получается собака.
Код Github для выводов TF Lite
Вывод:
Используйте настраиваемое, предварительно обученное или применяйте переносное обучение к предварительно обученной модели, сохраните модель, преобразуйте модель в файл с плоским буфером TFLite, оптимизируйте ее либо для задержки, либо для хранения, а затем сделайте выводы с помощью интерпретатора TF Lite.