title: A function that creates a Keras model with a customized loss function only work for once
body: <p>I have a contractive autoencoder built using Keras, when I tried to wrap the code in a function, I got some strange errors. The function will work when I run it for the first time, but crash if I run it again.</p>
  
  <pre><code>ae, encoder = cae(fm, lam=1e-4) # this works 
  ae, encoder = cae(fm, lam=1e-5) # this second call will crash
  </code></pre>
  
  <p>I think it's because of the inner function, but I don't know to fix it.</p>
  
  <p>Here is the code of the function:</p>
  
  <pre><code>def cae(feat_mat, hidden_size=800, lam=1e-5, batch_size=128, epochs=2000):
  
      input_size = feat_mat.shape[1]
      x = Input(shape=(input_size,))
      h = Dense(hidden_size, activation='relu', name='encoded')(x)
      r = Dense(input_size, activation='sigmoid')(h)
  
      ae= Model(inputs=x, outputs=r)
  
      def contractive_loss(y_pred, y_true):
          mse = K.mean(K.square(y_true - y_pred), axis=1)
  
          W = K.variable(value=ae.get_layer('encoded').get_weights()[0])  # N x N_hidden
          W = K.transpose(W)  # N_hidden x N
          h = ae.get_layer('encoded').output
          dh = h * (1 - h)  # N_batch x N_hidden
  
          # N_batch x N_hidden * N_hidden x 1 = N_batch x 1
          contractive = lam * K.sum(dh**2 * K.sum(W**2, axis=1), axis=1)
  
          return mse + contractive
  
  
      ae.compile(optimizer='adam', loss=contractive_loss, metrics=['accuracy'])
      history = ae.fit(feat_mat, feat_mat, batch_size=batch_size,epochs=epochs, callbacks = [early_stopping_monitor])  
      encoder = Model(x, h)
  
  
      return ae, encoder
  </code></pre>
  
  <p>And here is the error message:</p>
  
  <pre><code>---------------------------------------------------------------------------
  ValueError                                Traceback (most recent call last)
  ~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/keras/engine/base_layer.py in assert_input_compatibility(self, inputs)
      278             try:
  --&gt; 279                 K.is_keras_tensor(x)
      280             except ValueError:
  
  ~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py in is_keras_tensor(x)
      473         raise ValueError('Unexpectedly found an instance of type `' +
  --&gt; 474                          str(type(x)) + '`. '
      475                          'Expected a symbolic tensor instance.')
  
  ValueError: Unexpectedly found an instance of type `&lt;class 'numpy.ndarray'&gt;`. Expected a symbolic tensor instance.
  
  During handling of the above exception, another exception occurred:
  
  ValueError                                Traceback (most recent call last)
  &lt;ipython-input-17-78d0f91db066&gt; in &lt;module&gt;()
  ----&gt; 1 cae, c_encoder = cae(data, epochs=20, lam=1e-6)
  
  ~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/keras/engine/base_layer.py in __call__(self, inputs, **kwargs)
      438             # Raise exceptions in case the input is not compatible
      439             # with the input_spec set at build time.
  --&gt; 440             self.assert_input_compatibility(inputs)
      441 
      442             # Handle mask propagation.
  
  ~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/keras/engine/base_layer.py in assert_input_compatibility(self, inputs)
      283                                  'Received type: ' +
      284                                  str(type(x)) + '. Full input: ' +
  --&gt; 285                                  str(inputs) + '. All inputs to the layer '
      286                                  'should be tensors.')
      287 
  
  ValueError: Layer model_5 was called with an input that isn't a symbolic tensor. Received type: &lt;class 'numpy.ndarray'&gt;. Full input: [array([[0.        , 0.00408104, 0.00367454, ..., 0.47897612, 0.37681195,
          0.        ],
         [0.        , 0.        , 0.03629775, ..., 0.06981143, 0.07543451,
          0.        ],
         [0.        , 0.        , 0.        , ..., 0.09040481, 0.09040481,
          0.        ],
         ...,
         [0.        , 0.        , 0.        , ..., 0.09401818, 0.09401818,
          0.11997618],
         [0.        , 0.11205364, 0.        , ..., 0.05691057, 0.05691057,
          0.07582368],
         [0.1818507 , 0.20749162, 0.18682415, ..., 0.        , 0.        ,
          0.        ]])]. All inputs to the layer should be tensors.
  </code></pre>
  
  <p>A workaround would be to have the code as a script instead of inside a function, but I really would like to wrap it and also wonder the solution to the problem.</p>
  
  <p>Thanks! </p>