在深度学习教程中,所有训练数据都存储在shared
数组中,只有该数组的索引被传递给训练函数以切割出一个minibatch。我理解这允许数据留在GPU内存中,而不是将小块数据作为参数传递给每个minibatch的训练函数。在前面的一些问题中,这是作为为什么在教程中使用givens
机制的答案给出的。
我还没有看到这两个概念之间的联系,所以我可能错过了一些重要的东西。据我所知,给定的机制用给定的符号表达式交换出图中的变量(即,插入一些给定的子图来代替该变量)。那么为什么不从一开始就按我们需要的方式定义计算图呢?
这里是一个最小的例子。我定义了一个共享变量X
和一个整数index
,并且我要么创建一个已经包含切片操作的图,要么创建一个通过givens
插入切片操作的图。从表面上看,两个结果函数get_nogivens
和get_tutorial
是相同的(参见末尾的debugprint)。
但是为什么教程使用givens
模式呢?
import numpy as np
import theano
import theano.tensor as T
X = theano.shared(np.arange(100),borrow=True,name='X')
index = T.scalar(dtype='int32',name='index')
X_slice = X[index:index+5]
get_tutorial = theano.function([index], X, givens={X: X[index:index+5]}, mode='DebugMode')
get_nogivens = theano.function([index], X_slice, mode='DebugMode')
> theano.printing.debugprint(get_tutorial)
DeepCopyOp [@A] '' 4
|Subtensor{int32:int32:} [@B] '' 3
|X [@C]
|ScalarFromTensor [@D] '' 0
| |index [@E]
|ScalarFromTensor [@F] '' 2
|Elemwise{add,no_inplace} [@G] '' 1
|TensorConstant{5} [@H]
|index [@E]
> theano.printing.debugprint(get_nogivens)
DeepCopyOp [@A] '' 4
|Subtensor{int32:int32:} [@B] '' 3
|X [@C]
|ScalarFromTensor [@D] '' 0
| |index [@E]
|ScalarFromTensor [@F] '' 2
|Elemwise{add,no_inplace} [@G] '' 1
|TensorConstant{5} [@H]
|index [@E]
他们在这里使用givens
只是为了从输入数据变量中解耦传递给图的实际数据。您可以显式地将输入变量替换为X[index * batch_size: (index + 1) * batch_size]
,但这只是有点混乱。