Учитывая график модели тензорного потока, как найти входные данные node и выводить имена node
Я использую пользовательскую модель для классификации в Tensor Flow Camera Demo.
Я сгенерировал файл .pb (сериализованный файл protobuf) и смог отобразить огромный график, который в нем содержится.
Чтобы преобразовать этот график в оптимизированный, как указано в [https://www.oreilly.com/learning/tensorflow-on-android], можно использовать следующую процедуру:
$ bazel-bin/tensorflow/python/tools/optimize_for_inference \
--input=tf_files/retrained_graph.pb \
--output=tensorflow/examples/android/assets/retrained_graph.pb
--input_names=Mul \
--output_names=final_result
Здесь показано, как найти входные и выходные имена из графика.
Когда я не использую собственные имена, происходит сбой устройства:
E/TensorFlowInferenceInterface(16821): Failed to run TensorFlow inference
with inputs:[AvgPool], outputs:[predictions]
E/AndroidRuntime(16821): FATAL EXCEPTION: inference
E/AndroidRuntime(16821): java.lang.IllegalArgumentException: Incompatible
shapes: [1,224,224,3] vs. [32,1,1,2048]
E/AndroidRuntime(16821): [[Node: dropout/dropout/mul = Mul[T=DT_FLOAT,
_device="/job:localhost/replica:0/task:0/cpu:0"](dropout/dropout/div,
dropout/dropout/Floor)]]
Ответы
Ответ 1
Попробуйте следующее:
запустить python
>>> import tensorflow as tf
>>> gf = tf.GraphDef()
>>> gf.ParseFromString(open('/your/path/to/graphname.pb','rb').read())
а затем
>>> [n.name + '=>' + n.op for n in gf.node if n.op in ( 'Softmax','Placeholder')]
Затем вы можете получить результат, подобный этому:
['Mul=>Placeholder', 'final_result=>Softmax']
Но я не уверен, что проблема с именами node в отношении сообщений об ошибках.
Я полагаю, вы указали неверные аргументы при загрузке графического файла, или ваш сгенерированный графический файл что-то не так?
Проверьте эту часть:
E/AndroidRuntime(16821): java.lang.IllegalArgumentException: Incompatible
shapes: [1,224,224,3] vs. [32,1,1,2048]
UPDATE: Сожалею, если вы используете (повторно) подготовленный график, попробуйте следующее:
[n.name + '=>' + n.op for n in gf.node if n.op in ( 'Softmax','Mul')]
Кажется, что (re) подготовленный график сохраняет имя ввода/вывода op как "Mul" и "Softmax", а оптимизированный и/или квантованный график сохраняет их как "Placeholder" и "Softmax".
BTW, с использованием пересмотренного графика в мобильной среде не рекомендуется в соответствии с сообщением Питера Уордена: https://petewarden.com/2016/09/27/tensorflow-for-mobile-poets/. Лучше использовать квантованный или memmapped graph из-за производительности и размера файла, я не мог узнать, как загрузить memmapped graph в android, хотя...:(
(без проблем загружает оптимизированный/квантованный график в android)
Ответ 2
Недавно я наткнулся на эту опцию прямо из тензорного потока:
bazel build tensorflow/tools/graph_transforms:summarize_graph
bazel-bin/tensorflow/tools/graph_transforms/summarize_graph
--in_graph=custom_graph_name.pb
Ответ 3
Я написал простой скрипт для анализа отношений зависимостей в вычислительном графе (обычно DAG, непосредственно ациклический граф). Это настолько очевидно, что входами являются узлы, в которых отсутствует вход. Однако выходные данные могут быть определены как любые узлы на графике, потому что в самом странном, но все же действительном случае выходные данные могут быть входными данными, тогда как все остальные узлы являются фиктивными. Я все еще определяю операции вывода как узлы без вывода в коде. Вы можете пренебречь этим по своему желанию.
import tensorflow as tf
def load_graph(frozen_graph_filename):
with tf.io.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.compat.v1.GraphDef()
graph_def.ParseFromString(f.read())
with tf.Graph().as_default() as graph:
tf.import_graph_def(graph_def)
return graph
def analyze_inputs_outputs(graph):
ops = graph.get_operations()
outputs_set = set(ops)
inputs = []
for op in ops:
if len(op.inputs) == 0 and op.type != 'Const':
inputs.append(op)
else:
for input_tensor in op.inputs:
if input_tensor.op in outputs_set:
outputs_set.remove(input_tensor.op)
outputs = list(outputs_set)
return (inputs, outputs)