title: TypeError: ('Not JSON Serializable:', <tf.Tensor: shape=(), dtype=float32, numpy=123.0>)
body: <p>I have a <em>production</em> model which is configurable over a <code>ModelConfig</code>  I wrote myself which itself is a <code>class Config(dict)</code>. In that <code>ModelConfig</code> I am setting <code>hidden_size=123</code>. The following s a simplification of my <em>production</em> model-code:</p>
  <pre class="lang-py prettyprint-override"><code>class Config(dict):
    # ..
  
    def as_dict(self) -&gt; dict:
      return self._serialize()
  
  class ModelConfig(Config):
    hidden_size: int = 123
  </code></pre>
  <p>Now, I have a custom keras Model which is implemented like this:</p>
  <pre class="lang-py prettyprint-override"><code>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()
  </code></pre>
  <p>Everything works except calling <code>MyModel#save</code>:</p>
  <pre class="lang-py prettyprint-override"><code>model.save(model_path, save_format='tf')
  </code></pre>
  <p>I am getting a <code>TypeError</code> saying:</p>
  <pre class="lang-none prettyprint-override"><code>TypeError: ('Not JSON Serializable:', &lt;tf.Tensor: shape=(), dtype=float32, numpy=123.0&gt;)
  </code></pre>
  <p>I know it's <code>ModelConfig#hidden_size</code> that is being the property that's becoming a Tensor/EagerTensor here.</p>
  <p>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 <code>Config</code> causes a problem on <code>save()</code> but this appears not to be the case:</p>
  <p>So the following here <strong>is working as expected</strong>:</p>
  <pre class="lang-py prettyprint-override"><code>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()
  </code></pre>
  <p>This means the problem is not the <code>Config</code> object but for some reason in my production-model one of its properties is causing it to fail on calling <code>save()</code>.</p>
  <p>It's probably a big shot but does anybody have an idea where to look for the issue here?</p>
  <p>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 <code>int</code> which works as intended..</p>
  <p>I also tried <code>tf.saved_model.save</code> with the same result.</p>