Як перелічити всі використані операції в Tensorflow SavedModel?


10

Якщо я зберігаю свою модель за допомогою tensorflow.saved_model.saveфункції у форматі SavedModel, то як я можу потім знайти, який Tensorflow Ops буде використаний у цій моделі згодом. Оскільки модель може бути відновлена, ці операції зберігаються у графіку, я здогадуюсь у saved_model.pbфайлі. Якщо я завантажую цей протобуф (так це не вся модель), бібліотечна частина протобуфа перераховує їх, але це поки що не задокументовано та позначено як експериментальна функція. Моделі, створені в Tensorflow 1.x, не матимуть цієї частини.

Отже, який швидкий та надійний спосіб отримати список використаних операцій (на кшталт MatchingFilesабо WriteFile) з моделі у форматі SavedModel?

Зараз я можу заморозити всю річ, як tensorflowjs-converterі. Оскільки вони також перевіряють, чи підтримуються операції. Наразі це не працює, коли LSTM є в моделі, дивіться тут . Чи є кращий спосіб зробити це, оскільки Оп напевно є там?

Приклад моделі:

class FileReader(tf.Module):

@tf.function(input_signature=[tf.TensorSpec(name='filename', shape=[None], dtype=tf.string)])
def read_disk(self, file_name):
    input_scalar = tf.reshape(file_name, [])
    output = tf.io.read_file(input_scalar)
    return tf.stack([output], name='content')

file_reader = FileReader()

tf.saved_model.save(file_reader, 'file_reader')

Очікується у виході всі Ops, що містять у цьому випадку щонайменше:

  • ReadFileяк описано тут
  • ...

1
Важко точно сказати, що ви хочете, що це saved_model.pb, це tf.GraphDefчи SavedModelповідомлення протобуфа? Якщо у вас є tf.GraphDefзателефонований gd, ви можете отримати список використаних операцій sorted(set(n.op for n in gd.node)). Якщо у вас завантажена модель, ви можете це зробити sorted(set(op.type for op in tf.get_default_graph().get_operations())). Якщо це a SavedModel, ви можете отримати tf.GraphDefйого (наприклад saved_model.meta_graphs[0].graph_def).
jdehesa

Я хочу отримати ops зі збереженого SavedModel. Отже, останній варіант, який ви описуєте. Яка saved_modelзмінна у вашому останньому прикладі? Результат tf.saved_model.load('/path/to/model')або завантаження протобуфа файлу save_model.pb.
sampers

Відповіді:


1

Якщо saved_model.pbє SavedModelпротобуф-повідомлення, то ви отримуєте операції безпосередньо звідти. Скажімо, ми створюємо модель наступним чином:

import tensorflow as tf

class FileReader(tf.Module):
    @tf.function(input_signature=[tf.TensorSpec(name='filename', shape=[None], dtype=tf.string)])
    def read_disk(self, file_name):
        input_scalar = tf.reshape(file_name, [])
        output = tf.io.read_file(input_scalar)
        return tf.stack([output], name='content')

file_reader = FileReader()
tf.saved_model.save(file_reader, 'tmp')

Тепер ми можемо знайти такі операції, як ця модель:

from tensorflow.core.protobuf.saved_model_pb2 import SavedModel

saved_model = SavedModel()
with open('tmp/saved_model.pb', 'rb') as f:
    saved_model.ParseFromString(f.read())
model_op_names = set()
# Iterate over every metagraph in case there is more than one
for meta_graph in saved_model.meta_graphs:
    # Add operations in the graph definition
    model_op_names.update(node.op for node in meta_graph.graph_def.node)
    # Go through the functions in the graph definition
    for func in meta_graph.graph_def.library.function:
        # Add operations in each function
        model_op_names.update(node.op for node in func.node_def)
# Convert to list, sorted if you want
model_op_names = sorted(model_op_names)
print(*model_op_names, sep='\n')
# Const
# Identity
# MergeV2Checkpoints
# NoOp
# Pack
# PartitionedCall
# Placeholder
# ReadFile
# Reshape
# RestoreV2
# SaveV2
# ShardedFilename
# StatefulPartitionedCall
# StringJoin

Я спробував щось подібне, але, на жаль, це не те, на що я очікував, що це робить: скажіть, у мене є модель, яка робить це: input_scalar = tf.reshape(file_name, []) output = tf.io.read_file(input_scalar) return tf.stack([output], name='content')тоді ReadFile Op, як зазначено тут , знаходиться там, але не друкується.
sampers

1
@sampers Я відредагував відповідь на прикладі, як ти пропонуєш. Я дійсно отримую ReadFileоперацію на виході. Чи можливо, у вашому фактичному випадку ця операція не знаходиться між входом та виходом збереженої моделі? У такому випадку я думаю, що це може стати обрізаним.
jdehesa

Дійсно з даною моделлю вона працює. На жаль, для модуля, виготовленого в tf2, він цього не робить. Якщо я створю tf.Module з 1 функцією з анотацією file_nameаргументу @tf.function, що містить дзвінки, перелічені в попередньому коментарі, він дає такий список:Const, NoOp, PartitionedCall, Placeholder, StatefulPartitionedCall
sampers

додав модель до мого запитання
sampers

@sampers Я оновив свою відповідь. Раніше я використовував TF 1.x, я не був знайомий зі змінами об’єктів визначення графіків у TF 2.x, я думаю, що відповідь тепер охоплює все в збереженій моделі. Я думаю, що операції, відповідні функції Python, про яку ви писали, знаходяться saved_model.meta_graphs[0].graph_def.library.function[0]( node_defколекція в межах цього об’єкта функції).
jdehesa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.