Tensorflow.Keras: Custom Constraint Not Working

Question:

Im trying to implement the Weights Orthogonality Constraint showed here, in section 2.0. when i try to use it on a Keras Dense Layer, An Value Error is raised.

This is happening too when trying to implement the Custom Uncorrelated Features Constraint in the part 3.0 of the same Article.

import tensorflow as tf
import numpy as np

class WeightsOrthogonalityConstraint(tf.keras.constraints.Constraint):
    def __init__(self, encoding_dim, weightage = 1.0, axis = 0):
        self.encoding_dim = encoding_dim
        self.weightage = weightage
        self.axis = axis

    def weights_orthogonality(self, w):
        if(self.axis==1):
            w = tf.keras.backend.transpose(w)
        if(self.encoding_dim > 1):
            m = tf.keras.backend.dot(tf.keras.backend.transpose(w), w) - tf.keras.backend.eye(self.encoding_dim)
            return self.weightage * tf.keras.backend.sqrt(tf.keras.backend.sum(tf.keras.backend.square(m)))
        else:
            m = tf.keras.backend.sum(w ** 2) - 1.
            return m

    def __call__(self, w):
        return self.weights_orthogonality(w)

rand_samples = np.random.rand(16, 4)
dummy_ds = tf.data.Dataset.from_tensor_slices((rand_samples, rand_samples)).shuffle(16).batch(16)

encoder = tf.keras.layers.Dense(2, "relu", input_shape=(4,), kernel_regularizer=WeightsOrthogonalityConstraint(2))
decoder = tf.keras.layers.Dense(4, "relu")

autoencoder = tf.keras.models.Sequential()
autoencoder.add(encoder)
autoencoder.add(decoder)

autoencoder.compile(metrics=['accuracy'],
                    loss='mean_squared_error',
                    optimizer='sgd')

autoencoder.summary()

autoencoder.fit(dummy_ds, epochs=1)

If i stop using the contraint, there is no errors, but when used, the next error is raised:

2019-09-07 14:20:25.962610: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library nvcuda.dll
2019-09-07 14:20:26.997957: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties: 
name: GeForce GTX 1060 major: 6 minor: 1 memoryClockRate(GHz): 1.733
pciBusID: 0000:01:00.0
2019-09-07 14:20:27.043016: I tensorflow/stream_executor/platform/default/dlopen_checker_stub.cc:25] GPU libraries are statically linked, skip dlopen check.        
2019-09-07 14:20:27.050749: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1763] Adding visible gpu devices: 0
2019-09-07 14:20:27.081369: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2019-09-07 14:20:27.113598: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties: 
name: GeForce GTX 1060 major: 6 minor: 1 memoryClockRate(GHz): 1.733
pciBusID: 0000:01:00.0
2019-09-07 14:20:27.144194: I tensorflow/stream_executor/platform/default/dlopen_checker_stub.cc:25] GPU libraries are statically linked, skip dlopen check.        
2019-09-07 14:20:27.151802: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1763] Adding visible gpu devices: 0
2019-09-07 14:20:27.800616: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1181] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-09-07 14:20:27.817323: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1187]      0 
2019-09-07 14:20:27.840635: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1200] 0:   N 
2019-09-07 14:20:27.848536: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1326] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 4712 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1060, pci bus id: 0000:01:00.0, compute capability: 6.1)
Traceback (most recent call last):
  File "c:Userswhitm.vscodeextensionsms-python.python-2019.9.34911pythonFilesptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "c:Userswhitm.vscodeextensionsms-python.python-2019.9.34911pythonFileslibpythonptvsd__main__.py", line 432, in main
    run()
  File "c:Userswhitm.vscodeextensionsms-python.python-2019.9.34911pythonFileslibpythonptvsd__main__.py", line 316, in run_file
    runpy.run_path(target, run_name='__main__')
  File "C:ProgramDataAnaconda3envstensorflow-gpulibrunpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibrunpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibrunpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "c:UserswhitmDesktopCodeProjectsForestClassifier-DECTest.py", line 35, in <module>
    optimizer='sgd')
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythontrainingtrackingbase.py", line 458, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginetraining.py", line 337, in compile
    self._compile_weights_loss_and_weighted_metrics()
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythontrainingtrackingbase.py", line 458, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginetraining.py", line 1494, in _compile_weights_loss_and_weighted_metrics
    self.total_loss = self._prepare_total_loss(masks)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginetraining.py", line 1601, in _prepare_total_loss
    custom_losses = self.get_losses_for(None) + self.get_losses_for(
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 1209, in get_losses_for
    return [l for l in self.losses if l._unconditional_loss]
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 835, in losses
    return collected_losses + self._gather_children_attribute('losses')
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 2129, in _gather_children_attribute      
    getattr(layer, attribute) for layer in nested_layers))
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 2129, in <genexpr>
    getattr(layer, attribute) for layer in nested_layers))
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 832, in losses
    loss_tensor = regularizer()
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 907, in _tag_unconditional
    loss = loss()
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasenginebase_layer.py", line 1659, in _loss_for_variable
    regularization = regularizer(v)
  File "c:UserswhitmDesktopCodeProjectsForestClassifier-DECTest.py", line 21, in __call__
    return self.weights_orthogonality(w)
  File "c:UserswhitmDesktopCodeProjectsForestClassifier-DECTest.py", line 14, in weights_orthogonality
    m = tf.keras.backend.dot(tf.keras.backend.transpose(w), w) - tf.keras.backend.eye(self.encoding_dim)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasbackend.py", line 1310, in eye
    return variable(linalg_ops.eye(size, dtype=tf_dtype), dtype, name)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonkerasbackend.py", line 785, in variable
    constraint=constraint)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonopsvariables.py", line 264, in __call__
    return super(VariableMetaclass, cls).__call__(*args, **kwargs)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonopsresource_variable_ops.py", line 464, in __init__
    shape=shape)
  File "C:ProgramDataAnaconda3envstensorflow-gpulibsite-packagestensorflowpythonopsresource_variable_ops.py", line 550, in _init_from_args
    raise ValueError("Tensor-typed variable initializers must either be "
ValueError: Tensor-typed variable initializers must either be wrapped in an init_scope or callable (e.g., `tf.Variable(lambda : tf.truncated_normal([10, 40]))`) when building functions. Please file a feature request if this restriction inconveniences you.

Thanks in advance!

PD: Here is a Colab Notebook showing the error

PD2: I anage to found the line causing the problem, is this one:

m = tf.keras.backend.dot(tf.keras.backend.transpose(w), w) - tf.keras.backend.eye(self.encoding_dim)

specifically the keras backend eye() function is causing the problem

Asked By: ElPapi42

||

Answers:

I checked the same with TensorFlow version 1.14.0 and it is working fine.

I am sharing my colab notebook link below. Please check!

Colab Notebook

Answered By: Rishab P

I manage to solve this problem:

the function causing the error was tf.keras.backed.eye() on line 14. I read out there that the implementation in the keras backend of this function use numpy array for the identity matrix, but tensorflow and other backends already have their impementation for this function using tensors. There is something with the lack of tensors causing the error on tf2.0, so just change tf.keras.backed.eye() to tf.eye() solve the problem.

Answered By: ElPapi42

@ElPapi42: Have you tried saving the trained model after applying your fix? I keep on getting this error:

    ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[29], line 1
----> 1 autoencoder.save(create_path(path, 'models', 'undercomplete_ae_v1'))

File d:Pythonenvsgm_dllibsite-packageskerasutilstraceback_utils.py:70, in filter_traceback.<locals>.error_handler(*args, **kwargs)
     67     filtered_tb = _process_traceback_frames(e.__traceback__)
     68     # To get the full stack trace, call:
     69     # `tf.debugging.disable_traceback_filtering()`
---> 70     raise e.with_traceback(filtered_tb) from None
     71 finally:
     72     del filtered_tb

File ~AppDataLocalTemp6__autograph_generated_filesofmf2dn.py:10, in outer_factory.<locals>.inner_factory.<locals>.tf____call__(self, activation)
      8 do_return = False
      9 retval_ = ag__.UndefinedReturnValue()
---> 10 ag__.ld(self).covariance = ag__.converted_call(ag__.ld(self).get_covariance, (ag__.ld(activation),), None, fscope)
     11 try:
     12     do_return = True

File ~AppDataLocalTemp6__autograph_generated_fileqy8eqiyf.py:24, in outer_factory.<locals>.inner_factory.<locals>.tf__get_covariance(self, activation)
     22 ag__.for_stmt(ag__.converted_call(ag__.ld(range), (32,), None, fscope), None, loop_body, get_state, set_state, (), {'iterate_names': 'i'})
     23 x_centered = ag__.converted_call(ag__.ld(tf).stack, (ag__.ld(x_centered_list),), None, fscope)
---> 24 covariance = ag__.converted_call(ag__.ld(K).dot, (ag__.ld(x_centered), ag__.converted_call(ag__.ld(K).transpose, (ag__.ld(x_centered),), None, fscope)), None, fscope) / ag__.converted_call(ag__.ld(tf).cast, (ag__.converted_call(ag__.ld(activation).get_shape, (), None, fscope)[1], ag__.ld(tf).float32), None, fscope)
     25 try:
     26     do_return = True

ValueError: in user code:

    File "C:UsersS_NathAppDataLocalTemp6ipykernel_305443534407764.py", line 130, in __call__  *
        self.covariance = self.get_covariance(activation)
    File "C:UsersS_NathAppDataLocalTemp6ipykernel_305443534407764.py", line 115, in get_covariance  *
        covariance = K.dot(x_centered, K.transpose(x_centered)) /             tf.cast(activation.get_shape()[1], tf.float32)

    ValueError: None values not supported.
Answered By: Souvik Nath