Closed razorx89 closed 4 years ago
This also happens when using nsl.keras.adversarial_loss
in a custom training loop.
Thanks for reporting the issue.
AdversarialRegularization
calls adversarial_loss
, which in turn calls model(input)
. Unfortunately model.__call__
doesn't handle the name lookup. Following your example, this won't work:
model = tf.keras.Model([input_meta, input_image], [net])
prediction = model({'image': x_train, 'meta': m_train}) # Error
An alternative way is to create Keras models with dictionary input, so that the model will sequence the input features in a consistent order. Both AdversarialRegularization
and adversarial_loss
can work for this kind of models.
model = tf.keras.Model({'meta': input_meta, 'image': input_image}, [net])
prediction = model({'image': x_train, 'meta': m_train}) # Works
adv_loss = nsl.keras.adversarial_loss(
features={'image': tf.constant(x_test), 'meta': tf.constant(m_test)},
labels=tf.constant(y_test),
model=model,
loss_fn=tf.keras.losses.SparseCategoricalCrossentropy()) # Also works
This is indeed a problem when using adverserial_loss
directly. However, there is still a different behaviour between tf.keras.Model
and nsl.keras.AdversarialRegularization
. If I am wrapping the base model with the regularization model, then I would expect the same behaviour when calling fit
.
Actually, I did not know that one can define the model inputs with a dictionary. Almost all tutorials and documentation examples show the model construction with a list. Your proposed solution indeed solves the issue, however, I think API compatibility to tf.keras.Model.fit
should still be ensured.
The following code shows the introductory example with a simple modification. It uses an additional input tensor with (random) meta information, aka wide&deep model. Both input layers are named, so the normal behaviour of the keras model would be to make a name lookup and assign the values based on the key in the input dictionary. However, with the adverserial regularized model, the inputs seem to be assigned by a different order.
Here is the error log:
As you can see, the 2d input tensor with the meta information was assigned the 4d input placeholder and which was then passed to the 2d convolutional layer.