TypeError: ('Not JSON Serializable:', <tf.Tensor: shape=(), dtype=float32, numpy=123.0>) [英] TypeError: ('Not JSON Serializable:', <tf.Tensor: shape=(), dtype=float32, numpy=123.0>)
问题描述
我有一个 production 模型,它可以通过我自己编写的 ModelConfig
进行配置,它本身就是一个 class Config(dict)
.在那个 ModelConfig
中,我正在设置 hidden_size=123
.以下是我的生产模型代码的简化:
I have a production model which is configurable over a ModelConfig
I wrote myself which itself is a class Config(dict)
. In that ModelConfig
I am setting hidden_size=123
. The following s a simplification of my production model-code:
class Config(dict):
# ..
def as_dict(self) -> dict:
return self._serialize()
class ModelConfig(Config):
hidden_size: int = 123
现在,我有一个自定义的 keras 模型,其实现方式如下:
Now, I have a custom keras Model which is implemented like this:
class MyModel(keras.Model):
def __init__(self, config: ModelConfig):
self.config = config
self.dense = layers.Dense(config.hidden_size)
# ...
def get_config():
return self.config.as_dict()
除了调用 MyModel#save
外,一切正常:
Everything works except calling MyModel#save
:
model.save(model_path, save_format='tf')
我收到一个 TypeError
说:
TypeError: ('Not JSON Serializable:', <tf.Tensor: shape=(), dtype=float32, numpy=123.0>)
我知道 ModelConfig#hidden_size
是这里成为 Tensor/EagerTensor 的属性.
I know it's ModelConfig#hidden_size
that is being the property that's becoming a Tensor/EagerTensor here.
这里奇怪的是,在我的一个测试脚本中,一切都按预期工作.我创建它是为了查看 Config
是否会导致 save()
出现问题,但情况似乎并非如此:
The weird thing here is that in one of my test-scripts everything is working as intended. I created it in order to see if Config
causes a problem on save()
but this appears not to be the case:
所以这里的以下内容按预期工作:
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from config import Config
class ModelConfig(Config):
hidden_size: int = 123
class MyLayer(layers.Layer):
def __init__(self, config, other=None, **kwargs):
super().__init__(**kwargs)
self.config = config
self.other = other if other is not None else None
self.dense = layers.Dense(config.hidden_size + 1)
def call(self, inputs, **kwargs):
x = self.other(inputs, **kwargs) if self.other is not None else inputs
return self.dense(x, **kwargs)
class MyModel(keras.Model):
def __init__(self, config: ModelConfig, *args, **kwargs):
super().__init__(*args, **kwargs)
self.config = config
self.other = MyLayer(config, other=MyLayer(config))
self.dense = layers.Dense(config.hidden_size)
def call(self, inputs, **kwargs):
x = self.dense(inputs, **kwargs)
return self.other(x, **kwargs)
def get_config(self):
return self.config.to_dict()
@tf.function(
input_signature=[tf.TensorSpec(shape=(None, 100))]
)
def infer(self, inputs):
return self.call(inputs)
def main():
fp = '/tmp/mymodel'
config = ModelConfig()
model = MyModel(config)
model(np.random.rand(1, 100))
model.save(fp, save_format='tf')
model = tf.saved_model.load(fp)
print(model.infer(np.random.rand(1, 100)))
print('All done.')
if __name__ == '__main__':
main()
这意味着问题不在于 Config
对象,但由于某种原因,在我的生产模型中,它的一个属性导致它在调用 save()
时失败.
This means the problem is not the Config
object but for some reason in my production-model one of its properties is causing it to fail on calling save()
.
这可能是一个大问题,但有人知道在哪里可以找到问题吗?
It's probably a big shot but does anybody have an idea where to look for the issue here?
在一种情况下,该属性变成了一个无法序列化的 Tensor/EagerTensor(这是有道理的),而在测试脚本的情况下,它仍然是一个按预期工作的 int
..
In one case the property becomes a Tensor/EagerTensor which cannot be serialized (which makes sense) and in the test-script case it stays an int
which works as intended..
我也尝试了 tf.saved_model.save
,结果相同.
I also tried tf.saved_model.save
with the same result.
推荐答案
我猜是 tf.Tensor 不是 JSON Serializable.您可以尝试将 tf.Tensor 的对象转换为 numpy 数组,然后您应该可以保存配置以供以后重新加载.
I guess it is tf.Tensor that is not JSON Serializable. You can try to convert an object of tf.Tensor to a numpy array, then you should be able to save the config for later reloading.
这篇关于TypeError: ('Not JSON Serializable:', <tf.Tensor: shape=(), dtype=float32, numpy=123.0>)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!