Reputation: 151
I was previously adding regularization of activations and/or kernels in Tensorflow.keras on a pretrained network, using a loop over layers:
if regul_what is 'kernel':
for layer in model.layers:
if isinstance(layer, DepthwiseConv2D):
layer.add_loss(regularizers.l1_l2(l1,l2)(layer.depthwise_kernel))
elif isinstance(layer, layers.Conv2D) or isinstance(layer, layers.Dense):
layer.add_loss(regularizers.l1_l2(l1,l2)(layer.kernel))
if regul_what is 'activity':
for layer in model.layers:
if isinstance(layer, Activation):
layer.add_loss(regularizers.l1_l2(l1,l2)(layer.output))
It used to work (as far as I tested) before upgrading to tensorflow 2.0.
Now that I need to update my whole framework to tensorflow 2.0. The previous code, when executed, returns the following error at the moment of applying the add_loss():
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-123-cc0c5783731e> in <module>
3 if ('_relu' in layer.name): #isinstance(layer, Activation):
4 #layer.activity_regularizer = regularizers.l1_l2(l1,l2)
----> 5 layer.add_loss(regularizers.l1_l2(l1,l2)(layer.output))
~/miniconda/envs/l1l2/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/base_layer.py in add_loss(self, losses, inputs)
1119 if eager_losses and not in_call_context:
1120 raise ValueError(
-> 1121 'Expected a symbolic Tensors or a callable for the loss value. '
1122 'Please wrap your loss computation in a zero argument `lambda`.')
1123
ValueError: Expected a symbolic Tensors or a callable for the loss value. Please wrap your loss computation in a zero argument `lambda`.
I thus tried to introduce zero argument lambda functions as follows:
if regul_what is 'kernel':
for layer in model.layers:
if isinstance(layer, DepthwiseConv2D):
layer.add_loss(lambda: regularizers.l1_l2(l1,l2)(layer.depthwise_kernel))
elif isinstance(layer, layers.Conv2D) or isinstance(layer, layers.Dense):
layer.add_loss(lambda: regularizers.l1_l2(l1,l2)(layer.kernel))
if regul_what is 'activity':
for layer in model.layers:
if isinstance(layer, Activation):
layer.add_loss(lambda: regularizers.l1_l2(l1,l2)(layer.output))
With the introduction of the lambda, the add_loss loop pass without error, but then when training starts I get the error:
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training.py", line 1297, in fit_generator
steps_name='steps_per_epoch')
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training_generator.py", line 295, in model_iteration
progbar.on_batch_end(step, batch_logs)
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/tensorflow_core/python/keras/callbacks.py", line 760, in on_batch_end
self.progbar.update(self.seen, self.log_values)
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/tensorflow_core/python/keras/utils/generic_utils.py", line 440, in update
avg = np.mean(self._values[k][0] / max(1, self._values[k][1]))
File "<__array_function__ internals>", line 6, in mean
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 3257, in mean
out=out, **kwargs)
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/numpy/core/_methods.py", line 135, in _mean
arr = asanyarray(a)
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/numpy/core/_asarray.py", line 138, in asanyarray
return array(a, dtype, copy=False, order=order, subok=True)
File "~/miniconda/envs/l1l2/lib/python3.6/site-packages/tensorflow_core/python/framework/ops.py", line 736, in __array__
" array.".format(self.name))
NotImplementedError: Cannot convert a symbolic Tensor (truediv:0) to a numpy array.
I have no idea how to solve this... Thanks in advance for your help!
Upvotes: 2
Views: 1652
Reputation: 151
It seems that the problem was actually because of the default eager execution in TF2.0.
By disabling eager execution at the beginning of the script with the line:
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
.. the original version (without lambda) works smoothly.
The incompatibility between eager execution and add_loss() is also mentioned here: https://github.com/tensorflow/compression/issues/9
Upvotes: 2