【问题标题】:duplicate a tensorflow graph复制张量流图
【发布时间】:2016-06-14 00:24:58
【问题描述】:

复制 TensorFlow 图并保持更新的最佳方法是什么?

理想情况下,我想将复制的图形放在另一台设备上(例如从 GPU 到 CPU),然后不时更新副本。

【问题讨论】:

  • 为什么不并行构建多个图而不是复制现有的?
  • 这个问题很模糊。您是在询问更新 TensorFlow Graph 数据结构原位 (hard) 的问题吗?或者您是否在询问如何在不改变结构的情况下从另一个 (not so bad) 更新一个图中的参数?还是这与神经网络的版本控制有关(更广泛地说,这是一个软件工程问题)?
  • @rdadolf 第二个。我只需要在不同的机器上保留相同模型的副本并不时同步参数。
  • @这也可以。但我仍然需要确保它们具有相同的初始值并且它们将保持同步。

标签: python tensorflow


【解决方案1】:

简答:您可能想要checkpoint files (permalink)。


长答案:

让我们清楚这里的设置。我假设您有两个设备,A 和 B,并且您正在 A 上进行训练并在 B 上运行推理。 您希望定期使用在另一台训练期间发现的新参数更新运行推理的设备上的参数。 上面链接的教程是一个很好的起点。它向您展示了 tf.train.Saver 对象的工作原理,您不需要在这里做任何更复杂的事情。

这是一个例子:

import tensorflow as tf

def build_net(graph, device):
  with graph.as_default():
    with graph.device(device):
      # Input placeholders
      inputs = tf.placeholder(tf.float32, [None, 784])
      labels = tf.placeholder(tf.float32, [None, 10])
      # Initialization
      w0 = tf.get_variable('w0', shape=[784,256], initializer=tf.contrib.layers.xavier_initializer())
      w1 = tf.get_variable('w1', shape=[256,256], initializer=tf.contrib.layers.xavier_initializer())
      w2 = tf.get_variable('w2', shape=[256,10], initializer=tf.contrib.layers.xavier_initializer())
      b0 = tf.Variable(tf.zeros([256]))
      b1 = tf.Variable(tf.zeros([256]))
      b2 = tf.Variable(tf.zeros([10]))
      # Inference network
      h1  = tf.nn.relu(tf.matmul(inputs, w0)+b0)
      h2  = tf.nn.relu(tf.matmul(h1,w1)+b1)
      output = tf.nn.softmax(tf.matmul(h2,w2)+b2)
      # Training network
      cross_entropy = tf.reduce_mean(-tf.reduce_sum(labels * tf.log(output), reduction_indices=[1]))
      optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)    
      # Your checkpoint function
      saver = tf.train.Saver()
      return tf.initialize_all_variables(), inputs, labels, output, optimizer, saver

训练程序的代码:

def programA_main():
  from tensorflow.examples.tutorials.mnist import input_data
  mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
  # Build training network on device A
  graphA = tf.Graph()
  init, inputs, labels, _, training_net, saver = build_net(graphA, '/cpu:0')
  with tf.Session(graph=graphA) as sess:
    sess.run(init)
    for step in xrange(1,10000):
      batch = mnist.train.next_batch(50)
      sess.run(training_net, feed_dict={inputs: batch[0], labels: batch[1]})
      if step%100==0:
        saver.save(sess, '/tmp/graph.checkpoint')
        print 'saved checkpoint'

...以及推理程序的代码:

def programB_main():
  from tensorflow.examples.tutorials.mnist import input_data
  mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
  # Build inference network on device B
  graphB = tf.Graph()
  init, inputs, _, inference_net, _, saver = build_net(graphB, '/cpu:0')
  with tf.Session(graph=graphB) as sess:
    batch = mnist.test.next_batch(50)

    saver.restore(sess, '/tmp/graph.checkpoint')
    print 'loaded checkpoint'
    out = sess.run(inference_net, feed_dict={inputs: batch[0]})
    print out[0]

    import time; time.sleep(2)

    saver.restore(sess, '/tmp/graph.checkpoint')
    print 'loaded checkpoint'
    out = sess.run(inference_net, feed_dict={inputs: batch[0]})
    print out[1]

如果您启动训练程序,然后启动推理程序,您会看到推理程序产生两个不同的输出(来自同一个输入批次)。这是它获取了训练程序检查点的参数的结果。

现在,这个程序显然不是你的终点。我们不进行任何真正的同步,您必须确定“周期性”对于检查点的含义。但这应该让您了解如何将参数从一个网络同步到另一个网络。

最后一个警告:这不是意味着这两个网络必然是确定性的。 TensorFlow 中有已知的非确定性元素(例如,this),所以如果您需要完全相同相同的答案,请小心。但这是在多台设备上运行的硬道理。

祝你好运!

【讨论】:

    【解决方案2】:

    我将尝试使用一个非常简化的答案,看看通用方法是否是 OP 所描述的:

    我会通过 tf.train.Saver 对象来实现它。

    假设您的权重在变量 W1、W2 和 b1 中

    mysaver = tf.train.Saver(({'w1': W1, 'w2': W2, 'b1': b1}))
    

    在训练循环中,您可以添加每 n 次迭代:

    saver.save(session_var, 'model1', global_step=step)
    

    然后在加载实例中,当需要时,你运行:

    tf.train.Saver.restore(other_session_object, 'model1')
    

    希望这与您所要求的解决方案相似。

    【讨论】:

      【解决方案3】:

      只需往返tf.Graph > tf.GraphDef > tf.Graph:

      import tensorflow as tf
      
      
      def copy_graph(graph: tf.Graph) -> tf.Graph:
          with tf.Graph().as_default() as copied_graph:
              graph_def = graph.as_graph_def(add_shapes=True)
              tf.graph_util.import_graph_def(graph_def)
              return copied_graph
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-04
        • 2016-08-10
        相关资源
        最近更新 更多