Подтвердить что ты не робот

Tensorflow: как заменить node на графике расчета?

Если у вас есть два непересекающихся графика и вы хотите связать их, включите это:

x = tf.placeholder('float')
y = f(x)

y = tf.placeholder('float')
z = f(y)

в это:

x = tf.placeholder('float')
y = f(x)
z = g(y)

Есть ли способ сделать это? Похоже, что в некоторых случаях это может сделать конструкцию проще.

Например, если у вас есть граф, который имеет входное изображение как tf.placeholder, и вы хотите оптимизировать входное изображение, стиль глубокой мечты, есть способ просто заменить местозаполнитель на tf.variable node? Или вы должны думать об этом перед построением графика?

4b9b3361

Ответ 1

TL; DR: Если вы можете определить два вычисления как функции Python, вы должны это сделать. Если вы не можете, в TensorFlow есть более расширенные функции для сериализации и импорта графиков, что позволяет составлять графики из разных источников.

Один из способов сделать это в TensorFlow - построить непересекающиеся вычисления как отдельные объекты tf.Graph, а затем преобразовать их в последовательные буферы протокола, используя Graph.as_graph_def():

with tf.Graph().as_default() as g_1:
  input = tf.placeholder(tf.float32, name="input")
  y = f(input)
  # NOTE: using identity to get a known name for the output tensor.
  output = tf.identity(y, name="output")

gdef_1 = g_1.as_graph_def()

with tf.Graph().as_default() as g_2:  # NOTE: g_2 not g_1       
  input = tf.placeholder(tf.float32, name="input")
  z = g(input)
  output = tf.identity(y, name="output")

gdef_2 = g_2.as_graph_def()

Затем вы могли бы составить gdef_1 и gdef_2 в третий график, используя tf.import_graph_def():

with tf.Graph().as_default() as g_combined:
  x = tf.placeholder(tf.float32, name="")

  # Import gdef_1, which performs f(x).
  # "input:0" and "output:0" are the names of tensors in gdef_1.
  y, = tf.import_graph_def(gdef_1, input_map={"input:0": x},
                           return_elements=["output:0"])

  # Import gdef_2, which performs g(y)
  z, = tf.import_graph_def(gdef_2, input_map={"input:0": y},
                           return_elements=["output:0"]

Ответ 2

Если вы хотите объединить подготовленные модели (например, повторно использовать части предварительно обработанной модели в новой модели), вы можете использовать Saver для сохранения контрольной точки первой модели, затем восстановить эту модель (полностью или частично ) в другую модель.

Например, скажем, вы хотите повторно использовать вес модели w в модели 2, а также преобразовать x из заполнитель в переменную:

with tf.Graph().as_default() as g1:
    x = tf.placeholder('float')
    w = tf.Variable(1., name="w")
    y = x * w
    saver = tf.train.Saver()

with tf.Session(graph=g1) as sess:
    w.initializer.run()
    # train...
    saver.save(sess, "my_model1.ckpt")

with tf.Graph().as_default() as g2:
    x = tf.Variable(2., name="v")
    w = tf.Variable(0., name="w")
    z = x + w
    restorer = tf.train.Saver([w]) # only restore w

with tf.Session(graph=g2) as sess:
    x.initializer.run()  # x now needs to be initialized
    restorer.restore(sess, "my_model1.ckpt") # restores w=1
    print(z.eval())  # prints 3.

Ответ 3

Оказывается, что tf.train.import_meta_graph передает все дополнительные аргументы базовому import_scoped_meta_graph, у которого есть аргумент input_map, и использует его, когда получает доступ к собственному (внутреннему) вызову import_graph_def.

Это не задокументировано, и он взял меня waaaay много времени, чтобы найти его, но он работает!