Я пытаюсь объединить несколько моделей Tensorflow на отдельных графиках в одну модель на одном графике (я предполагаю, что типичными сценариями будут модели передачи обучения, ансамбли и т. д., которые необходимо заморозить).
Я могу соединить два графика с помощью tf.import_graph_def. Однако, когда один из исходных графиков содержит переменную, я не могу ввести в нее значения на новом графике. Операции назначения копируются как часть графа, и если я запускаю их вручную, я получаю ожидаемые результаты. (Раскомментировать sess.run
-вызов в четвертом with graph...
-блоке)
import tensorflow as tf
graph1 = tf.Graph()
with graph1.as_default():
with tf.Session(graph=graph1) as sess:
var1 = tf.Variable([1, 1, 1], name='var1')
tensor1 = tf.multiply(var1, 2, name='tensor1')
graph2 = tf.Graph()
with graph2.as_default():
with tf.Session(graph=graph2) as sess:
placeholder = tf.placeholder(tf.int32, [3], name='placeholder')
tensor2 = tf.multiply(placeholder, 2, name='tensor2')
graph3 = tf.Graph()
with graph3.as_default():
with tf.Session(graph=graph3) as sess:
graph1out, = tf.import_graph_def(graph1.as_graph_def(), name='graph1', return_elements=['tensor1:0'])
tf.import_graph_def(graph2.as_graph_def(), name='graph2', input_map={'placeholder:0': graph1out})
with graph3.as_default():
with tf.Session(graph=graph3) as sess:
sess.run(tf.global_variables_initializer())
#sess.run(graph3.get_tensor_by_name('graph1/var1/Assign:0'))
tensor = graph3.get_tensor_by_name('graph2/tensor2:0')
result = sess.run(tensor)
Запуск этого фрагмента как есть дает:
FailedPreconditionError (see above for traceback): Attempting to use uninitialized value graph1/var1
Ручной запуск assign-ops — это очень мало общего подхода, который будет грязно писать как часть общей функции. Это также требует, чтобы эти вызовы назначения выполнялись каждый раз, когда я повторно инициализирую сеанс с графом.
Есть ли более общий способ сделать это? Например, создавая новые переменные на основе старых и привязывая их к существующей структуре?
Если нет, есть ли способ обернуть вызовы назначения? Так что, по крайней мере, я могу запустить одну общую init-операцию вместо неизвестного количества конкретных для каждого случая?