小编kmh*_*ann的帖子

TensorFlow:如何在培训期间多次评估验证数据队列?

TL;博士

如何在每次K次训练迭代后评估验证集,使用单独的队列进行训练和验证数据,而不需要tf.Sessions在多个进程中分开?鉴于我的特殊问题,似乎没有一种干净的方法来实现这一点,而我目前的解决方法(我认为可行)会给我一些未定义的行为.救命!

整个故事

我想在每次K训练迭代中评估验证集,我无法弄清楚如何在TensorFlow中正确实现这一点.这应该是最常见的操作之一,但感觉TensorFlow的API /架构在这里对我有用,或者至少让事情变得不必要.

我的假设是:

  • [A1]此处描述的培训/验证多进程模型https://www.tensorflow.org/how_tos/reading_data/#multiple_input_pipelines不适用于我的问题,因为我必须假设没有足够的GPU内存可用加载变量两次.
  • [A2]我想在每次K训练迭代中评估验证集.
  • [A3]训练和验证数据都不能简单地从磁盘读取,而是在运行中生成.这使得不可能预先可靠地预先计算验证集的大小.
  • [A4]验证集太大,无法预先计算并存储到磁盘上.
  • [A5]有效验证集大小不一定是批量大小的倍数.

训练输入管道设置如下:

  • A tf.train.slice_input_producer()生成(混洗)文件名列表,每个文件名都引用原始输入数据.
  • 自定义数据生成功能从每个原始输入数据块生成可变数量的训练样本/标签.
  • 生成的培训样本/标签tf.train.shuffle_batch()在被送入网络之前排队等候.

由于[A3],[A4],[A5],验证输入管道以几乎相同的方式设置,除了最终输入队列是通过生成tf.train.batch(),因为不希望进行混洗.由于上述假设,基于feed_dict的方法也是不可行的,并且看起来与使用更高级别的功能(例如,使用更高级别的功能)不相容tf.train.batch.

但是,使用两组不同的队列进行培训和验证的直接实现不起作用.据我了解,我有两个选择:

  • [B1]将num_epochs验证的参数设置tf.train.slice_input_producerNone.

    在这种情况下,验证集会无休止地循环,但我需要提前知道验证集的大小,以明确限制每次运行验证集时要评估的批次数.此外,如果验证集大小不能被批量大小整除,我将在最后一批中总是拉一点.由于这会每次都改变验证数据的评估顺序,因此这是不可接受的.

  • [B2]将num_epochs验证的参数设置tf.train.slice_input_producer1,并另外将函数的allow_smaller_final_batch参数设置tf.train.batchTrue.

    在这种情况下,验证集只循环一次,之后相应的队列永远关闭.默认情况下,这将使评估验证集不可能两次或多次.由于我不知道在TensorFlow中重新打开队列的好方法,我需要解决这个限制.

由于选项[B1]的更大限制,我选择解决选项[B2]的问题.概述我当前方法的(伪)代码如下:

训练循环应该是相当规范的.每次K次迭代,都会调用一个评估验证集的函数.请注意,我只启动名称以"train_"开头的队列; 这些是为收集生成的训练数据而设置的队列.为了做到这一点,我创建了两个辅助函数,get_queues_by_namestart_queue_runners.

def train_loop(train_ops, vali_ops, ...):
    with tf.Session() as sess:
        coord = tf.train.Coordinator()
        sess.run([tf.initialize_all_variables(), tf.initialize_local_variables()])
        load_latest_snapshot(sess, loader, snapshot_file)

        # Launch the queue runners
        queues …
Run Code Online (Sandbox Code Playgroud)

python machine-learning tensorflow

18
推荐指数
1
解决办法
4303
查看次数

具有模板化类型的模板专业化

我想使用以下函数专门化一个类模板:

template <typename T>
class Foo
{
public:
    static int bar();
};
Run Code Online (Sandbox Code Playgroud)

该函数没有参数,应根据Foo的类型返回结果.(在这个玩具示例中,我们返回该类型的字节数,但在实际应用程序中我们要返回一些元数据对象.)专门化适用于完全指定的类型:

// specialization 1: works
template <>
int Foo<int>::bar() { return 4; }

// specialization 2: works
template <>
int Foo<double>::bar() { return 8; }

// specialization 3: works
typedef pair<int, int> IntPair;
template <>
int Foo<IntPair>::bar() { return 2 * Foo<int>::bar(); }
Run Code Online (Sandbox Code Playgroud)

但是,我想将此概括为依赖于(其他)模板参数本身的类型.添加以下特化会产生编译时错误(VS2005):

// specialization 4: ERROR!
template <>
template <typename U, typename V>
int Foo<std::pair<U, V> >::bar() { return Foo<U>::bar() + Foo<V>::bar(); }
Run Code Online (Sandbox Code Playgroud)

我假设这不是合法的C++,但为什么呢?有没有办法优雅地实现这种类型的模式?

c++ templates specialization

9
推荐指数
2
解决办法
3134
查看次数

C++模板化构造函数不会编译

为什么我不能用上面的构造函数实例化一个Foo类型的对象?

我有一个使用内部typedef的类Bar(作为"template typedefs"的解决方法),并打算在构造函数中使用它,如下所示(CASE 1).但是,我似乎没有得到它编译.这是合法的C++吗?案例2似乎表明问题与Bar中的typedef有关.

如何定义一个构造函数来接受带有Bar类型的对象的std :: vectors?

#include <vector>
#include <iostream>
#include <utility>

template <typename T>
struct Bar
{
    typedef std::pair<T, T> type; // or anything else that uses T
};

struct Foo
{
    Foo() {}

    // CASE 1: doesn't compile
    template <typename T> explicit Foo( const std::vector<typename Bar<T>::type>& data )
    {
        std::cout << "Hello\n";
    }

    //// CASE 2: compiles, but it's not what I want
    //template <typename T> explicit Foo( const std::vector<Bar<T> >& data )
    //{
    //  std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ templates constructor typedef typename

7
推荐指数
1
解决办法
5866
查看次数