Квантовать модель нейронной сети Keras

Недавно я начал создавать нейронные сети с Tensorflow + Keras и хотел бы попробовать функцию квантования, доступную в Tensorflow. До сих пор экспериментирование с примерами из учебных пособий по TF работало просто отлично, и у меня есть этот базовый рабочий пример (из https://www.tensorflow.org/tutorials/keras/basic_classification):

import tensorflow as tf
from tensorflow import keras

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# fashion mnist data labels (indexes related to their respective labelling in the data set)
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

# preprocess the train and test images
train_images = train_images / 255.0
test_images = test_images / 255.0

# settings variables
input_shape = (train_images.shape[1], train_images.shape[2])

# create the model layers
model = keras.Sequential([
keras.layers.Flatten(input_shape=input_shape),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])

# compile the model with added settings
model.compile(optimizer=tf.train.AdamOptimizer(),
          loss='sparse_categorical_crossentropy',
          metrics=['accuracy'])

# train the model
epochs = 3
model.fit(train_images, train_labels, epochs=epochs)

# evaluate the accuracy of model on test data
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)

Теперь я хотел бы использовать квантование в процессе обучения и классификации. Документация по квантованию ( https://www.tensorflow.org/performance/quantization) (страница больше не доступна с 15 сентября 2018 г.) предлагает использовать этот фрагмент кода:

loss = tf.losses.get_total_loss()
tf.contrib.quantize.create_training_graph(quant_delay=2000000)
optimizer = tf.train.GradientDescentOptimizer(0.00001)
optimizer.minimize(loss)

Тем не менее, он не содержит никакой информации о том, где этот код должен использоваться или как он должен быть связан с кодом TF (даже не упоминая модель высокого уровня, созданную с помощью Keras). Я понятия не имею, как эта часть квантования связана с ранее созданной моделью нейронной сети. Просто вставив его после кода нейронной сети, вы получите следующую ошибку:

Traceback (most recent call last):
  File "so.py", line 41, in <module>
    loss = tf.losses.get_total_loss()
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/losses/util.py", line 112, in get_total_loss
    return math_ops.add_n(losses, name=name)
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/math_ops.py", line 2119, in add_n
    raise ValueError("inputs must be a list of at least one Tensor with the "
ValueError: inputs must be a list of at least one Tensor with the same dtype and shape

Можно ли квантовать таким образом, чтобы квантовать модель Keras NN таким образом, или я упускаю что-то базовое? Возможное решение, которое приходило мне в голову, могло бы использовать низкоуровневый TF API вместо Keras (для создания модели потребовалось немало работы) или, возможно, попытка извлечь некоторые из методов более низкого уровня из моделей Keras.

1 ответ

Как упоминалось в других ответах, TensorFlow Lite может помочь вам с квантованием сети.

TensorFlow Lite предоставляет несколько уровней поддержки квантования.

Посттренировочное квантование Tensorflow Lite легко квантует веса и активации после тренировки. Обучение с учетом квантования позволяет обучать сети, которые можно квантовать с минимальным падением точности; это доступно только для подмножества архитектур сверточных нейронных сетей.

Итак, сначала вам нужно решить, нужно ли вам квантование после обучения или обучение с учетом квантования. Например, если вы уже сохранили модель как файлы *.h5, вы, вероятно, захотите последовать инструкциям @Mitiku и выполнить квантование после обучения.

Если вы предпочитаете достичь более высокой производительности, моделируя эффект квантования при обучении (используя метод, который вы указали в вопросе), и ваша модель находится в подмножестве архитектуры CNN, поддерживаемой обучением с учетом квантования, этот пример может помочь вам с точки зрения взаимодействия Keras и TensorFlow. По сути, вам нужно только добавить этот код между определением модели и ее подгонкой:

sess = tf.keras.backend.get_session()
tf.contrib.quantize.create_training_graph(sess.graph)
sess.run(tf.global_variables_initializer())

Поскольку ваша сеть выглядит довольно простой, вы можете использовать Tensorflow lite.

Tensorflow lite можно использовать для квантования модели keras.

Следующий код был написан для tensorflow 1.14. Это может не работать для более ранних версий.

Во-первых, после обучения модели вы должны сохранить ее в h5

model.fit(train_images, train_labels, epochs=epochs)

# evaluate the accuracy of model on test data
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)
model.save("model.h5")

Для загрузки модели keras используйте tf.lite.TFLiteConverter.from_keras_model_file

# load the previously saved model
converter  = tf.lite.TFLiteConverter.from_keras_model_file("model.h5")
tflite_model = converter.convert()
# Save the model to file
with open("tflite_model.tflite", "wb") as output_file:
    output_file.write(tflite_model)

Сохраненную модель можно загрузить в скрипт Python или на другие платформы и языки. Чтобы использовать сохраненную модель tflite, tensorlfow.lite предоставляет интерпретатор. Следующий пример из здесь показано, как загрузить tflite модель из локального файла с использованием питона сценариев.

import numpy as np
import tensorflow as tf

# Load TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path="tflite_model.tflite")
interpreter.allocate_tensors()

# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Test model on random input data.
input_shape = input_details[0]['shape']
input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)

interpreter.invoke()

# The function `get_tensor()` returns a copy of the tensor data.
# Use `tensor()` in order to get a pointer to the tensor.
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

Имея тот же вопрос. Вы поняли это? Кстати, веб-страница Tensorflow ( https://www.tensorflow.org/performance/quantization) поддельного квантования составляет 404 с прошлой недели.

Другие вопросы по тегам