简体   繁体   English

theano定义了重复调用另一个函数的函数?

[英]theano define function which repeatedly calls another function?

My training function: 我的训练功能:

def fit(self, X, y):
    batch_size = 20

    index = T.lscalar()  # index to a [mini]batch
    updates = {}

    return theano.function(
        inputs=[index], outputs=self.cost, updates=updates,
        givens={
            self.sym_X: X[index * batch_size:(index + 1) * batch_size],
            self.sym_y: y[index * batch_size:(index + 1) * batch_size]})

Then from elsewhere: 然后从其他地方:

fn = obj.fit(X, y)
for i in range(10):
    fn(i)

So what I'd like this to look like is 所以我想要的是这样的

fn = obj.fit(X, y)
fn()

I'm really not even sure how to start on this, as theano is still pretty mind-bending for me. 我真的不确定如何开始这个,因为theano对我来说仍然非常令人折服。 I was able to get this far but loops are seriously challenging. 我能够做到这一点,但循环是非常具有挑战性的。

I have the vague notion that if I can turn the theano.function into a theano.scan, and then put an outer theano.function around it - that might work. 我有一个模糊的概念,如果我可以将theano.function转换为theano.scan,然后在它周围放置一个外部theano.function - 这可能会起作用。 However, theano.scan is still magical to me (despite my best efforts). 然而,theano.scan对我来说仍然是神奇的(尽管我付出了最大的努力)。

How can I make it so that the looping over minibatches is incorporated into a single function call? 我怎样才能将循环的小型数据集合并到单个函数调用中?

Update: 更新:

I thought I had it! 我以为我拥有它! I got this: 我懂了:

def fit(self, X, y):
    batch_size = 20
    n_batches = 5

    index = theano.shared(0)

    ## index to a [mini]batch
    updates = {
        index: index + batch_size
    }

    return theano.function(
        inputs=[], outputs=[self.cost] * n_batches, updates=updates,
        givens={
            index: 0,
            self.sym_X: X[index * batch_size:(index + 1) * batch_size],
            self.sym_y: y[index * batch_size:(index + 1) * batch_size]})

But unfortunately it seems like since I use index to calculate the batches in the givens, I can't also update on it: 但不幸的是,似乎因为我使用索引来计算批次中的批次,我也无法更新它:

Traceback (most recent call last):
  File "skdeeplearn/classifiers/test/test_classifiers.py", line 79, in test_logistic_sgd
    fn = clf.fit(self.shared_X, self.shared_y)
  File "skdeeplearn/classifiers/logistic_sgd.py", line 139, in fit
    self.sym_y: y[index * batch_size:(index + 1) * batch_size]})
  File "/Users/aelaguiz/workspace/pyvotune/venv/lib/python2.7/site-    packages/theano/compile/function.py", line 206, in function
    profile=profile)
  File "/Users/aelaguiz/workspace/pyvotune/venv/lib/python2.7/site-packages/theano/compile/pfunc.py", line 461, in pfunc
    no_default_updates=no_default_updates)
  File "/Users/aelaguiz/workspace/pyvotune/venv/lib/python2.7/site-packages/theano/compile/pfunc.py", line 162, in rebuild_collect_shared
    "to be replaced by %s." % (v_orig, v_repl))
AssertionError: When using 'givens' or 'replace' with several (old_v, new_v) replacement pairs, you can not have a new_v variable depend on an old_v one. For instance, givens = {a:b, b:(a+1)} is not allowed. Here, the old_v <TensorType(int64, scalar)> is used to compute other new_v's, but it is scheduled to be replaced by <TensorType(int64, scalar)>.

Update 2: 更新2:

def fit(self, X, y):
    batch_size = 20
    n_batches = 5

    index = theano.shared(0)

    ## index to a [mini]batch
    updates = {
        index: index + batch_size
    }

    return theano.function(
        inputs=[], outputs=[self.cost] * n_batches, updates=updates,
        givens={
            self.sym_X: X[index * batch_size:(index + 1) * batch_size],
            self.sym_y: y[index * batch_size:(index + 1) * batch_size]})

This actually runs, but it's output is weird: 这实际上运行,但它的输出很奇怪:

[array(0.6931471824645996, dtype=float32), array(0.6931471824645996, dtype=float32), array(0.6931471824645996, dtype=float32), array(0.6931471824645996, dtype=float32), array(0.6931471824645996, dtype=float32)]

Everytime I run it I get the same output, even though X & y are initialized to random values each run. 每次我运行它时,我得到相同的输出,即使X&y被初始化为每次运行的随机值。

Everybody I know do the loop over minibatch in python. 我认识的每个人都在python中循环使用minibatch。 This can be done with scan, but all your tries here did not used scan. 这可以通过扫描完成,但您在此处的所有尝试都没有使用扫描。 So it is normal that they didn't worked. 所以他们没有工作是正常的。 You need to call the scan function somewhere to use it (or its higher level interface like map). 您需要在某处调用扫描功能才能使用它(或者更高级别的界面,如地图)。 In fact, in your case, I think you can use theano.scan(fn, theano.tensor.arange(N)) . 事实上,在你的情况下,我认为你可以使用theano.scan(fn, theano.tensor.arange(N))

I can't answer all your questions in this post as the snippet of code is incomplete, but here is some information: 我不能在这篇文章中回答你的所有问题,因为代码片段不完整,但这里有一些信息:

return theano.function(
    inputs=[], outputs=[self.cost] * n_batches,

Here: [self.cost] * n_batches is pure python code. 这里: [self.cost] * n_batches是纯Python代码。 This create a list of n_batches element, where each elements are self.cos t. 这将创建一个n_batches元素列表,其中每个元素都是self.cos t。 So if n_batches is 3, you will have outputs=[self.cost, self.cost, self.cost] . 因此,如果n_batches为3,则outputs=[self.cost, self.cost, self.cost] That is why you got the same value outputed multiple time. 这就是为什么你多次输出相同的值。

I can't tell you why you always add the same answer as I need information that wasn't provided. 我不能告诉你为什么你总是添加相同的答案,因为我需要未提供的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM