小言_互联网的博客

TensorFlow.NET 支持队列操作

403人阅读  评论(0)

ThensorFlow能够并行处理多个任务,而队列是一种强大的异步计算机制。 如果我们拥有大型数据集,则可以大大加快模型的训练过程。 当以小批量读取,预处理和提取我们的训练数据时,此功能特别方便。 能够对我们的模型进行专业且高性能的训练的秘诀是使用TensorFlow提供的排队操作。 TensorFlow已经实现了4种类型的队列:FIFOQueuePaddingFIFOQueuePriorityQueueRandomShuffleQueue

就像TensorFlow中的所有操作一样,队列也是计算图中的一个节点。 它是一个有状态的节点,就像变量一样:其他节点可以修改其内容,特别是节点可以将新元素加入到队列,或从队列中弹出现有元素。

为了开始学习队列操作,让我们先从一个简单的示例开始。 我们将创建一个“先进先出”队列(FIFOQueue)并用数字填充。 然后,我们将构建一个计算图,该图将一个元素从队列中移出,然后将一个元素添加到该项目中,最后将其放回队列的末尾。

[TestMethod]
public void FIFOQueue()
{
	// create a first in first out queue with capacity up to 2
	// and data type set as int32
	var queue = tf.FIFOQueue(2, tf.int32);
	// init queue, push 2 elements into queue.
	var init = queue.enqueue_many(new[] { 10, 20 });
	// pop out the first element
	var x = queue.dequeue();
	// add 1
	var y = x + 1;
	// push back into queue
	var inc = queue.enqueue(y);

	using (var sess = tf.Session())
	{
		// init queue
		init.run();

		// pop out first element and push back calculated y
		(int dequeued, _) = sess.run((x, inc));
		Assert.AreEqual(10, dequeued);

		(dequeued, _) = sess.run((x, inc));
		Assert.AreEqual(20, dequeued);

		(dequeued, _) = sess.run((x, inc));
		Assert.AreEqual(11, dequeued);

		(dequeued, _) = sess.run((x, inc));
		Assert.AreEqual(21, dequeued);
        
		// thread will hang or block if you run sess.run(x) again
		// until queue has more element.
	}
}

Enqueue_EnqueueMany__Dequeue_是特殊的节点。他们使用一个指向队列的指针而不是普通值,从而允许他们对其进行更改。我首先创建一个最大为2的FIFOQueue队列,然后将两个值放入队列。然后,我立即尝试从中取出一个值并将其分配给y,在这里我只需将1添加到已出列的变量。接下来,我们开始一个会话并运行。运行几次该操作后,队列将为空-如果尝试再次运行该操作,则程序的主线程将挂起或阻塞-这是因为它将等待另一个操作运行到将更多值放入队列。

FIFOQueue
创建一个队列,以先进先出的顺序使元素出队。 FIFO队列具有有限的容量;支持多个并发的生产者和消费者;并提供一次精确消费。 FIFOQueue包含最多容量元素的列表。每个元素都是张量的定长元组,其张量类型由dtypes描述,其形状可选地由shapes参数描述。

PaddingFIFOQueue
一个FIFOQueue通过填充支持批量可变大小张量。 PaddingFIFOQueue可以包含具有动态形状的组件,同时还支持dequeue_manyPaddingFIFOQueue最多可容纳一个容量元素列表。每个元素都是张量的定长元组,其张量由dtypes描述,其形状由shapes参数描述。

PriorityQueue
一个按优先级出队元素的队列实现。 PriorityQueue具有有限的容量;支持多个并发的生产者和消费者;并提供一次精确的投放。 PriorityQueue包含最多容量元素的列表。每个元素都是张量的定长元组,其张量类型由类型描述,其形状可选地由shapes参数描述。

RandomShuffleQueue
一个以随机顺序使元素出队的队列实现。 RandomShuffleQueue具有有限的容量;支持多个并发的生产者和消费者;并提供一次精确的投放。 RandomShuffleQueue包含最多容量元素的列表。每个元素都是张量的定长元组,其张量类型由dtypes描述,其形状可选地由shapes参数描述。

队列方法必须与队列在同一设备上运行。 FIFOQueueRandomShuffleQueue是重要的TensorFlow对象,用于在图形中异步计算张量。例如,典型的输入体系结构是使用RandomShuffleQueue为训练模型准备输入:

多个线程准备培训示例并将其放入队列。
训练线程执行训练操作,以使迷你批处理从队列中出队。
这种架构体系结构简化了输入管道的构造。

查看C#程序代码

在上面的示例中,一旦队列里没有元素,您必须在程序被阻止时终止程序。很显然,这不是很有用。我们真正想要的事情是,只要队列为空或将要为空,我们的程序就可以重新加载或排队更多的值。我们可以通过在上面的代码中再次明确运行enqueue_op来重新加载值,从而解决此问题。但是,对于大型,更实际的程序,这显然不可行。幸运的是,TensorFlow有一个解决方案。

TensorFlow提供了两个类来帮助执行多线程任务:tf.Coordinatortf.QueueRunner。有两个类可以一起使用。 Coordinator类可帮助多个线程停在一起并将异常报告给主线程。 QueueRunner类用于创建多个线程,以将张量推入同一队列。


转载:https://blog.csdn.net/SciSharp/article/details/101205118
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场