gpt4 book ai didi

python - 为什么我允许 pickle 是 Theano 函数的实例方法,而不是普通的实例方法?

转载 作者:太空狗 更新时间:2023-10-29 21:52:46 24 4
gpt4 key购买 nike

在使用 joblib 并行化一些涉及 Theano 函数的模型拟合代码的过程中,我偶然发现了一些对我来说似乎很奇怪的行为。

考虑这个非常简单的例子:

from joblib import Parallel, delayed
import theano
from theano import tensor as te
import numpy as np

class TheanoModel(object):
def __init__(self):
X = te.dvector('X')
Y = (X ** te.log(X ** 2)).sum()
self.theano_get_Y = theano.function([X], Y)

def get_Y(self, x):
return self.theano_get_Y(x)

def run(niter=100):
x = np.random.randn(1000)
model = TheanoModel()
pool = Parallel(n_jobs=-1, verbose=1, pre_dispatch='all')

# this fails with `TypeError: can't pickle instancemethod objects`...
results = pool(delayed(model.get_Y)(x) for _ in xrange(niter))

# # ... but this works! Why?
# results = pool(delayed(model.theano_get_Y)(x) for _ in xrange(niter))

if __name__ == '__main__':
run()

我明白为什么第一种情况会失败,因为 .get_Y() 显然是 TheanoModel 的实例方法。我不明白的是为什么第二种情况有效,因为XYtheano_get_Y() 是仅在 TheanoModel__init__() 方法中声明。在创建 TheanoModel 实例之前,无法评估 theano_get_Y()。那么,当然,它也应该被视为一个实例方法,因此应该是 unpickleable 的?事实上,如果我明确声明 XYTheanoModel 实例的属性,Even 仍然有效。

谁能解释一下这是怎么回事?


更新

为了说明为什么我认为这种行为特别奇怪,下面是一些其他不将 self 作为第一个参数的可调用成员对象的示例:

from joblib import Parallel, delayed
import theano
from theano import tensor as te
import numpy as np

class TheanoModel(object):
def __init__(self):
X = te.dvector('X')
Y = (X ** te.log(X ** 2)).sum()
self.theano_get_Y = theano.function([X], Y)
def square(x):
return x ** 2
self.member_function = square
self.static_method = staticmethod(square)
self.lambda_function = lambda x: x ** 2

def run(niter=100):
x = np.random.randn(1000)
model = TheanoModel()
pool = Parallel(n_jobs=-1, verbose=1, pre_dispatch='all')

# # not allowed: `TypeError: can't pickle function objects`
# results = pool(delayed(model.member_function)(x) for _ in xrange(niter))

# # not allowed: `TypeError: can't pickle function objects`
# results = pool(delayed(model.lambda_function)(x) for _ in xrange(niter))

# # also not allowed: `TypeError: can't pickle staticmethod objects`
# results = pool(delayed(model.static_method)(x) for _ in xrange(niter))

# but this is totally fine!?
results = pool(delayed(model.theano_get_Y)(x) for _ in xrange(niter))

if __name__ == '__main__':
run()

除了 theano.function 之外,它们都不可 pickleable!

最佳答案

Theano 函数不是 Python 函数。相反,它们是覆盖 __call__ 的 python 对象。这意味着您可以像调用函数一样调用它们,但在内部它们实际上是某个自定义类的对象。因此,您可以 pickle 它们。

关于python - 为什么我允许 pickle 是 Theano 函数的实例方法,而不是普通的实例方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25365440/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com