首页 文章

Tensorflow培训与Eager和Graph模式无关

提问于
浏览
1

我花了一些时间在Tensorflow中编写新的(我希望的)RNN细胞 . 为了原型,我使用急切模式(更容易调试) . 为了训练,我将代码迁移到图表(运行得更快) .

我正在寻找一个包装代码/示例,它可以以一种与我运行它的模式无关的方式运行前传和训练 - 尽可能地渴望或图形 . 我想到了一组函数/类,可以插入特定的神经网络/优化器/数据,并且这些函数/类集可以在两种模式下运行,两者之间的变化很小 . 此外,它与许多类型的NN /优化器/数据实例兼容当然是好的 .

我很确定很多人都有这个想法 . 我想知道在TF中当前的热切/图形集成是否可行 .

1 回答

  • 1

    是 . 我一直想知道同样的事情 . 在Tensorflow documentation你可以看到:

    为急切执行而编写的相同代码也将在图形执行期间构建图形 . 只需在未启用eager执行的新Python会话中运行相同的代码即可 .

    但这很难实现,主要是因为使用图表意味着处理占位符,这些占位符不能在Eager模式下使用 . 我试图使用面向对象的层和数据集API来摆脱占位符 . 这是我最接近完全兼容的代码:

    m = 128  # num_examples
    n = 5    # num features
    
    epochs = 2
    batch_size = 32
    steps_per_epoch = m // 32
    
    dataset = tf.data.Dataset.from_tensor_slices(
        (tf.random_uniform([m, n], dtype=tf.float32),
         tf.random_uniform([m, 1], dtype=tf.float32)))
    dataset = dataset.repeat(epochs)
    dataset = dataset.batch(batch_size)
    
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(64, activation='relu', input_dim=n),
        tf.keras.layers.Dense(32, activation='relu'),
        tf.keras.layers.Dense(1)
    ])
    
    def train_eagerly(model, dataset):
    
        optimizer = tf.train.AdamOptimizer()
        iterator = dataset.make_one_shot_iterator()
    
        print('Training graph...')
        for epoch in range(epochs):
            print('Epoch', epoch)
            progbar = tf.keras.utils.Progbar(target=steps_per_epoch, stateful_metrics='loss')
            for step in range(steps_per_epoch):
                with tf.GradientTape() as tape:
                    features, labels = iterator.get_next()
                    predictions = model(features, training=True)
                    loss_value = tf.losses.mean_squared_error(labels, predictions)
                grads = tape.gradient(loss_value, model.variables)
                optimizer.apply_gradients(zip(grads, model.variables))
                progbar.add(1, values=[('loss', loss_value.numpy())])
    
    def train_graph(model, dataset):
    
        optimizer = tf.train.AdamOptimizer()
        iterator = dataset.make_initializable_iterator()
    
        print('Training graph...')
        with tf.Session() as sess:
            sess.run(iterator.initializer)
            sess.run(tf.global_variables_initializer())
            for epoch in range(epochs):
                print('Epoch', epoch)
                progbar = tf.keras.utils.Progbar(target=steps_per_epoch, stateful_metrics='loss')
                for step in range(steps_per_epoch):
                    with tf.GradientTape() as tape:
                        features, labels = sess.run(iterator.get_next())
                        predictions = model(features, training=True)
                        loss_value = tf.losses.mean_squared_error(labels, predictions)
                    grads = tape.gradient(loss_value, model.variables)
                    optimizer.apply_gradients(zip(grads, model.variables))
                    progbar.add(1, values=[('loss', loss_value.eval())])
    

    如您所见,主要区别在于我在Eager培训期间使用one_shot_iterator(当然,在图训练期间,我必须在会话中运行操作) .

    我尝试使用 optimizer.minimize 而不是自己应用渐变来做同样的事情,但我无法想出一个既适用于渴望又适用于图形模式的代码 .

    此外,我敢肯定,对于不那么简单的模型,例如你正在使用的模型,这会变得更加困难 .

相关问题