【问题标题】:theano define function which repeatedly calls another function?theano 定义重复调用另一个函数的函数?
【发布时间】:2014-08-03 15:25:37
【问题描述】:

我的训练功能:

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]})

然后从其他地方:

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

所以我希望它看起来像

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

我真的不知道如何开始,因为 theano 对我来说仍然非常令人费解。我能够做到这一点,但循环非常具有挑战性。

我有一个模糊的概念,如果我可以将 theano.function 转换为 theano.scan,然后在其周围放置一个外部 theano.function - 这可能会起作用。然而,theano.scan 对我来说仍然很神奇(尽管我尽了最大的努力)。

如何才能将小批量的循环合并到单个函数调用中?

更新:

我以为我拥有它!我得到了这个:

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]})

但不幸的是,由于我使用索引来计算给定中的批次,我也无法对其进行更新:

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)>.

更新 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]})

这实际上运行,但它的输出很奇怪:

[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)]

每次我运行它时,我都会得到相同的输出,即使每次运行时 X 和 y 都被初始化为随机值。

【问题讨论】:

  • 我基本上认为这不可能按照我现在想做的方式进行。实际上,我认为代码使用 theano.scan 是正确的,但后来意识到我无法推进 X 的索引,因为 theano 不支持操作中的高级索引。因此,我将输入预分组为小批量作为预处理操作。

标签: python machine-learning theano


【解决方案1】:

我认识的每个人都在 python 中对 minibatch 进行循环。这可以通过扫描来完成,但是您在这里的所有尝试都没有使用扫描。所以他们没有工作是正常的。您需要在某处调用扫描函数才能使用它(或其更高级别的接口,如地图)。其实就你的情况,我觉得你可以用theano.scan(fn, theano.tensor.arange(N))

由于代码的 sn-p 不完整,我无法在这篇文章中回答您的所有问题,但这里有一些信息:

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

这里:[self.cost] * n_batches 是纯 Python 代码。这将创建一个n_batches 元素列表,其中每个元素都是self.cost。因此,如果n_batches 为 3,您将拥有outputs=[self.cost, self.cost, self.cost]。这就是为什么您多次输出相同的值的原因。

我无法告诉你为什么你总是添加相同的答案,因为我需要未提供的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    相关资源
    最近更新 更多