Ответ 1
Мы можем оптимизировать или уменьшить размер модели Tensorflow, используя следующие методы:
-
Замораживание: преобразование переменных, хранящихся в файле контрольных точек SavedModel, в константы, хранящиеся непосредственно в графе модели. Это уменьшает общий размер модели.
-
Сокращение: удаление неиспользуемых узлов в пути прогнозирования и выходных данных графика, объединение дублирующих узлов, а также очистка других операций узлов, таких как сводка, идентификация и т.д.
-
Свертывание констант: найдите все подграфы в модели, которые всегда оцениваются как константные выражения, и замените их этими константами. Складные нормы партии: сложите умножения, введенные при нормализации партии, в умножения веса предыдущего слоя.
-
Квантование: преобразование весов с плавающей запятой в более низкую точность, например, 16 или 8 бит.
Код для замораживания графика указан ниже:
from tensorflow.python.tools import freeze_graph
output_graph_filename = os.path.join(saved_model_dir, output_filename)
initializer_nodes = ''
freeze_graph.freeze_graph(input_saved_model_dir=saved_model_dir,
output_graph=output_graph_filename,
saved_model_tags = tag_constants.SERVING,
output_node_names=output_node_names,initializer_nodes=initializer_nodes,
input_graph=None, input_saver=False, input_binary=False,
input_checkpoint=None, restore_op_name=None, filename_tensor_name=None,
clear_devices=False, input_meta_graph=False)
Код для Обрезки и Постоянного Сгибания упомянут ниже:
from tensorflow.tools.graph_transforms import TransformGraph
def get_graph_def_from_file(graph_filepath):
with ops.Graph().as_default():
with tf.gfile.GFile(graph_filepath, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
return graph_def
def optimize_graph(model_dir, graph_filename, transforms, output_node):
input_names = []
output_names = [output_node]
if graph_filename is None:
graph_def = get_graph_def_from_saved_model(model_dir)
else:
graph_def = get_graph_def_from_file(os.path.join(model_dir,
graph_filename))
optimized_graph_def = TransformGraph(graph_def, input_names,
output_names, transforms)
tf.train.write_graph(optimized_graph_def, logdir=model_dir, as_text=False,
name='optimized_model.pb')
print('Graph optimized!')
Мы вызываем код нашей модели, передавая список желаемых оптимизаций, например так:
transforms = ['remove_nodes(op=Identity)', 'merge_duplicate_nodes',
'strip_unused_nodes','fold_constants(ignore_errors=true)',
'fold_batch_norms']
optimize_graph(saved_model_dir, "frozen_model.pb" , transforms, 'head/predictions/class_ids')
Код для квантования упоминается ниже:
transforms = ['quantize_nodes', 'quantize_weights',]
optimize_graph(saved_model_dir, None, transforms, 'head/predictions/class_ids')
После применения Оптимизации нам нужно преобразовать Оптимизированный график обратно в GraphDef. Код для этого показан ниже:
def convert_graph_def_to_saved_model(export_dir, graph_filepath):
if tf.gfile.Exists(export_dir):
tf.gfile.DeleteRecursively(export_dir)
graph_def = get_graph_def_from_file(graph_filepath)
with tf.Session(graph=tf.Graph()) as session:
tf.import_graph_def(graph_def, name='')
tf.saved_model.simple_save(
session,
export_dir,
inputs={
node.name: session.graph.get_tensor_by_name(
'{}:0'.format(node.name))
for node in graph_def.node if node.op=='Placeholder'},
outputs={'class_ids': session.graph.get_tensor_by_name(
'head/predictions/class_ids:0')}
)
print('Optimized graph converted to SavedModel!')
Пример кода показан ниже:
optimized_export_dir = os.path.join(export_dir, 'optimized')
optimized_filepath = os.path.join(saved_model_dir, 'optimized_model.pb')
convert_graph_def_to_saved_model(optimized_export_dir, optimized_filepath)
Для получения дополнительной информации перейдите по ссылке ниже, которая упоминалась @gobrewers14:
https://medium.com/google-cloud/optimizing-tensorflow-models-for-serving-959080e9ddbf