首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的‘泡菜’/‘gpflow .利用.gpflow模型的冻结行为

奇怪的‘泡菜’/‘gpflow .利用.gpflow模型的冻结行为
EN

Stack Overflow用户
提问于 2020-06-03 14:09:01
回答 1查看 220关注 0票数 1

我一直试图(粗略地)在一个玩具数据集中训练和保存一个gpflow SVGP模型,主要遵循这个笔记本例子

在使用pickle保存模型时(我很感谢这不是推荐的,但我不认为这是这里的主要问题),我发现了一些不寻常的地方,我认为是意外的行为:如果我们不调用gpflow.utilities.freeze(model),在尝试pickle model之前,我们就会出错。如果我们确实调用了gpflow.utilities.freeze(model) (丢弃返回的冻结模型),那么model就可以在没有错误的情况下被腌制。

再生产

最小、可重复的示例

代码语言:javascript
复制
import numpy as np
import gpflow
import tensorflow as tf
import pickle
rng = np.random.RandomState(123)

N = 10000  # Number of training observations
X = rng.rand(N, 1)
Y = rng.randn(N, 1)
data = (X, Y)

n_inducing_vars = 100
Z = X[:n_inducing_vars]
minibatch_size = 100
n_iterations = 100

#Define model object
model = gpflow.models.SVGP(gpflow.kernels.Matern12(), gpflow.likelihoods.Bernoulli(), inducing_variable=Z, num_data=N)

#Create minibatch object
data_minibatch = (
tf.data.Dataset.from_tensor_slices(data).prefetch(
    N).repeat().shuffle(N).batch(minibatch_size)
    )
data_minibatch_it = iter(data_minibatch)
model_objective = model.training_loss_closure(data_minibatch_it)

#Define optimiser
optimizer = tf.keras.optimizers.Adam(0.001)
#Optimise both variational parameters and kernel hyperparameters.
for step in range(n_iterations):
    optimizer.minimize(model_objective,
                       var_list=model.trainable_variables
                       )

freeze = False
if not freeze:
    # pickle doesn't work
    pickle.dump(model, open('test1', 'wb'))
else:
    # if following code is executed, pickle works fine
    _ = gpflow.utilities.freeze(model)  # ignore return value
    pickle.dump(model, open('test1', 'wb'))

堆栈跟踪,或错误消息

代码语言:javascript
复制
TypeError                                 Traceback (most recent call last)
<ipython-input-6-3d5f537ca994> in <module>
----> 1 pickle.dump(model, open('test1', 'wb'))

TypeError: can't pickle HashableWeakRef objects

预期行为

并不是说我期望泡菜在第一个实例中起作用,因为我知道这并不是一般保存tensorflow-related对象的推荐方法。然而,我当然不会期望它在第一次失败,但在第二次成功。从代码库的角度来看,我认为gpflow.utilities.freeze(model)不应该改变model,因为它似乎正在这样做。

系统信息

  • 用GPflow版本2.0.0 . 2.0.4测试
  • TensorFlow版本: 2.1.0,tensorflow_probability 0.9.0
  • Python版本:Python3.6.9

我猜想,在model上调用model时,它实际上莫名其妙地将model转换为一个“冻结”模型,然后该模型具有“常量”属性(模型),从而使其能够被腌制。

对这一问题的任何澄清都将不胜感激。

注意,我将其作为一个issue发布在gpflow github (https://github.com/GPflow/GPflow/issues/1493)上,但是决定在这里向更广泛的gpflow社区广播这个问题。

EN

回答 1

Stack Overflow用户

发布于 2020-06-03 15:09:17

让我们看看下面几行发生了什么:

代码语言:javascript
复制
if not freeze:
    # pickle doesn't work
    pickle.dump(model, open('test1', 'wb'))  # Line 1
else:
    # if following code is executed, pickle works fine
    gpflow.utilities.freeze(model)           # Line 2
    pickle.dump(model, open('test1', 'wb'))  # Line 3

Line 1中,经过训练的模型包含Parameters实例,这些实例将TensorFlow概率双射器作为从约束空间到无约束空间的变压器。TFP双射器缓存所有正反运算。双射器的缓存是用一个映射实现的,其中键是正向输入的张量输入,反函数和值也是张量返回的对象。不幸的是,不能散列张量(例如np.arrays),为此目的,TFP为张量实现了包装器HashableWeakRef。错误消息"TypeError:无法对HashableWeakRef对象进行筛选“具有误导性。这实际上意味着HashableWeakRef python不能复制该实例,因为它是对尚未创建的对象的引用。因此,不能对这些对象进行腌制。

Line 2中,有一个由两个调用组成的freeze方法:第一个调用移除双对象的内容,即缓存,第二个调用是copy.deepcopyfreeze背后的神奇之处在于它删除了引用。是的,它修改了现有的对象,但它既不影响急切的计算,也不影响tf.functioned函数。清洗使deepcopy成为可能。

Line 3之所以工作,是因为对象没有要复制的引用。

这个问题有一个长期跟踪报告和试图修复它在GPflow:TFP#547TFP#944GPflow#1479GPflow#1293GPflow#1338

这是TensorFlow概率中的一个建议修正:TFP#947

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62174955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档