# Buggy code
def build(self, input_shape):
    """Build `Layer`"""
    input_shape = tf.TensorShape(input_shape).as_list()
    self.input_spec = tf.keras.layers.InputSpec(shape=[None] + input_shape[1:])

    if not self.layer.built:
        self.layer.build(input_shape)

    if not hasattr(self.layer, "kernel"):
        raise ValueError(
            "`WeightNormalization` must wrap a layer that"
            " contains a `kernel` for weights"
        )

    # The kernel's filter or unit dimension is -1
    self.layer_depth = int(self.layer.kernel.shape[-1])
    self.kernel_norm_axes = list(range(self.layer.kernel.shape.rank - 1))

    self.g = self.add_weight(
        name="g",
        shape=(self.layer_depth,),
        initializer="ones",
        dtype=self.layer.kernel.dtype,
        trainable=True,
    )
    self.v = self.layer.kernel

    self._initialized = self.add_weight(
        name="initialized",
        shape=None,
        initializer="zeros",
        dtype=tf.dtypes.bool,
        trainable=False,
    )

    if self.data_init:
        # Used for data initialization in self._data_dep_init.
        layer_config = tf.keras.layers.serialize(self.layer)
        layer_config["config"]["trainable"] = False
        self._naked_clone_layer = tf.keras.layers.deserialize(layer_config)
        self._naked_clone_layer.build(input_shape)
        self._naked_clone_layer.set_weights(self.layer.get_weights())
        self._naked_clone_layer.activation = None

    self.built = True


# Traceback (RuntimeError)
['weight_normalization/g:0', 'weight_normalization/kernel:0', 'weight_normalization/bias:0', 'weight_normalization/initialized:0', 'weight_normalization/kernel:0', 'weight_normalization/bias:0']
Traceback (most recent call last):
File "/home/ubuntu/hankcs/laser/tests/playground/wn_bug.py", line 14, in <module>
model.save_weights('model.h5')
File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/network.py", line 1074, in save_weights
saving.save_weights_to_hdf5_group(f, self.layers)
File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/saving/hdf5_format.py", line 631, in save_weights_to_hdf5_group
param_dset = g.create_dataset(name, val.shape, dtype=val.dtype)
File "/home/ubuntu/.local/lib/python3.6/site-packages/h5py/_hl/group.py", line 139, in create_dataset
self[name] = dset
File "/home/ubuntu/.local/lib/python3.6/site-packages/h5py/_hl/group.py", line 371, in __setitem__
h5o.link(obj.id, self.id, name, lcpl=lcpl, lapl=self._lapl)
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "h5py/h5o.pyx", line 202, in h5py.h5o.link
RuntimeError: Unable to create link (name already exists)

# Fixed code
def build(self, input_shape):
    """Build `Layer`"""
    input_shape = tf.TensorShape(input_shape).as_list()
    self.input_spec = tf.keras.layers.InputSpec(shape=[None] + input_shape[1:])

    if not self.layer.built:
        self.layer.build(input_shape)

    if not hasattr(self.layer, "kernel"):
        raise ValueError(
            "`WeightNormalization` must wrap a layer that"
            " contains a `kernel` for weights"
        )

    # The kernel's filter or unit dimension is -1
    self.layer_depth = int(self.layer.kernel.shape[-1])
    self.kernel_norm_axes = list(range(self.layer.kernel.shape.rank - 1))

    self.g = self.add_weight(
        name="g",
        shape=(self.layer_depth,),
        initializer="ones",
        dtype=self.layer.kernel.dtype,
        trainable=True,
    )
    self.v = self.layer.kernel

    self._initialized = self.add_weight(
        name="initialized",
        shape=None,
        initializer="zeros",
        dtype=tf.dtypes.bool,
        trainable=False,
    )

    if self.data_init:
        # Used for data initialization in self._data_dep_init.
        with tf.name_scope("data_dep_init"):
            layer_config = tf.keras.layers.serialize(self.layer)
            layer_config["config"]["trainable"] = False
            self._naked_clone_layer = tf.keras.layers.deserialize(layer_config)
            self._naked_clone_layer.build(input_shape)
            self._naked_clone_layer.set_weights(self.layer.get_weights())
            self._naked_clone_layer.activation = None

    self.built = True