【问题标题】:Have 2 versions of the same TensorFlow network with different weights and update one from the other拥有 2 个具有不同权重的相同 TensorFlow 网络版本,并从另一个版本中更新一个
【发布时间】:2018-07-12 09:32:27
【问题描述】:

我正在尝试实现 DeepMind 用来训练 AI 玩 Atari 游戏的深度 q 学习程序。他们使用并在多个教程中提到的功能之一是拥有两个版本的神经网络;一个在您循环浏览小批量训练数据时更新(称为 Q),另一个在您这样做时调用以帮助构建训练数据(Q')。然后定期(比如每 10k 个数据点)将 Q' 中的权重设置为 Q 的当前值。

我的问题是在 TensorFlow 中执行此操作的最佳方法是什么?既要同时存储两个相同的架构网络,又要定期更新彼此的权重?我当前的网络如下所示,目前仅使用默认图表和交互式会话。

sess = tf.InteractiveSession()

x = tf.placeholder(tf.float32, shape=[None, height, width, m])
y_ = tf.placeholder(tf.float32, shape=[None, env.action_space.n])

W_conv1 = weight_variable([8, 8, 4, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x, W_conv1, 4, 4) + b_conv1)

W_conv2 = weight_variable([4, 4, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2, 2, 2) + b_conv2)

W_conv3 = weight_variable([3, 3, 64, 64])
b_conv3 = bias_variable([64])
h_conv3 = tf.nn.relu(conv2d(h_conv2, W_conv3, 1, 1) + b_conv3)

# Flattern conv to dense
flat_input_size = 14*10*64
h_conv3_reshape = tf.reshape(h_conv3, [-1, flat_input_size])

# Dense layers
W_fc1 = weight_variable([flat_input_size, 512])
b_fc1 = bias_variable([512])
h_fc1 = tf.nn.relu(tf.matmul(h_conv3_reshape, W_fc1) + b_fc1)

W_fc2 = weight_variable([512, env.action_space.n])
b_fc2 = bias_variable([env.action_space.n])
y_conv = tf.matmul(h_fc1, W_fc2) + b_fc2

accuracy = tf.squared_difference(y_, y_conv)
loss = tf.reduce_mean(accuracy)
optimizer = tf.train.AdamOptimizer(0.0001).minimize(loss)

tf.global_variables_initializer().run()

【问题讨论】:

    标签: python tensorflow neural-network reinforcement-learning q-learning


    【解决方案1】:

    这是一种安排方式。首先,您为每个网络制作一个单独的图表,以便在不同的会话中并行运行它们:

    graph1 = tf.Graph()
    with graph1.as_default():
      model1 = build_model()
    
    graph2 = tf.Graph()
    with graph2.as_default():
      model2 = build_model()
    

    ... 其中build_model() 定义了所有占位符、变量和训练操作。两个模型应该对变量使用相同的命名,这将允许它们轻松交换状态。

    每个网络都可以使用另一个网络的快照来训练目标(最新或以前的最佳,由您决定)。每个网络都会定期通过tf.Saver() 保存到磁盘,并使用其中一个网络的权重进行恢复。例如,这段代码会将第二个网络的权重加载到第一个图中:

    with tf.Session(graph=graph1) as sess:
      saver = tf.train.import_meta_graph('/tmp/model-2/network.meta')
      saver.restore(sess, '/tmp/model-2/network')
      ... continue training
    

    这就是模型的保存方式:

    with tf.Session(graph=graph1) as sess:
      ... do some training
      save_path = saver.save(sess, '/tmp/model-1/network')
    

    this question 中有关保存和恢复的更多信息。您可以在同一会话中执行此操作,也可以开始一个新会话。

    事实上,您甚至可以尝试为两个网络使用磁盘上的相同位置,以便从同一个文件进行保存和恢复。但这将迫使您拥有最新的快照,而以前的方法更灵活。

    您需要注意的一件事是会话的使用:为graph1 创建的会话只能评估来自graph1 的张量和操作。示例:

    def build_model():
      x = tf.placeholder(tf.float32, name='x')
      y = tf.placeholder(tf.float32, name='y')
      z = x + y
      return x, y, z
    
    graph1 = tf.Graph()
    with graph1.as_default():
      x1, y1 ,z1 = build_model()
    
    graph2 = tf.Graph()
    with graph2.as_default():
      x2, y2, z2 = build_model()
    
    with tf.Session(graph=graph1) as sess1:
      with tf.Session(graph=graph2) as sess2:
        # Good
        print(sess1.run(z1, feed_dict={x1: 1, y1: 2}))  # 3.0
        print(sess2.run(z2, feed_dict={x2: 3, y2: 1}))  # 4.0
    
        # BAD! Wrong graph
        # print(sess1.run(z2, feed_dict={x2: 3, y2: 1}))
    

    【讨论】:

      猜你喜欢
      • 2019-10-12
      • 1970-01-01
      • 2013-04-02
      • 2021-01-24
      • 1970-01-01
      • 2013-05-24
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多