如何在每次K次训练迭代后评估验证集,使用单独的队列进行训练和验证数据,而不需要tf.Sessions在多个进程中分开?鉴于我的特殊问题,似乎没有一种干净的方法来实现这一点,而我目前的解决方法(我认为可行)会给我一些未定义的行为.救命!
我想在每次K训练迭代中评估验证集,我无法弄清楚如何在TensorFlow中正确实现这一点.这应该是最常见的操作之一,但感觉TensorFlow的API /架构在这里对我有用,或者至少让事情变得不必要.
我的假设是:
训练输入管道设置如下:
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_producer为None.
在这种情况下,验证集会无休止地循环,但我需要提前知道验证集的大小,以明确限制每次运行验证集时要评估的批次数.此外,如果验证集大小不能被批量大小整除,我将在最后一批中总是拉一点.由于这会每次都改变验证数据的评估顺序,因此这是不可接受的.
[B2]将num_epochs验证的参数设置tf.train.slice_input_producer为1,并另外将函数的allow_smaller_final_batch参数设置tf.train.batch为True.
在这种情况下,验证集只循环一次,之后相应的队列永远关闭.默认情况下,这将使评估验证集不可能两次或多次.由于我不知道在TensorFlow中重新打开队列的好方法,我需要解决这个限制.
由于选项[B1]的更大限制,我选择解决选项[B2]的问题.概述我当前方法的(伪)代码如下:
训练循环应该是相当规范的.每次K次迭代,都会调用一个评估验证集的函数.请注意,我只启动名称以"train_"开头的队列; 这些是为收集生成的训练数据而设置的队列.为了做到这一点,我创建了两个辅助函数,get_queues_by_name和start_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) 我想使用以下函数专门化一个类模板:
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++,但为什么呢?有没有办法优雅地实现这种类型的模式?
为什么我不能用上面的构造函数实例化一个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)