We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
WeightNormalization layer can't save in h5
**System information**
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04):
Ubuntu 16.04.6 LTS
- TensorFlow version and how it was installed (source or binary):
tensorflow-gpu                   2.0.0, binary
- TensorFlow-Addons version and how it was installed (source or binary):
tensorflow-addons                0.6.0, binary
- Python version:
Python 3.6.9
- Is GPU used? (yes/no):
yes
**Describe the bug**
WeightNormalization layer can't save to h5

A clear and concise description of what the bug is.
WeightNormalization causing duplicate names of variables.

**Code to reproduce the issue**

```python
import tensorflow as tf
import tensorflow_addons as tfa

conv = tf.keras.layers.Conv1D(1, 1, name='conv')
wn_conv = tfa.layers.WeightNormalization(conv)

model = tf.keras.Sequential(layers=[wn_conv])
model.build([1, 2, 3])
print([w.name for w in model.layers[0].weights])
model.save_weights('model.h5')
```

Provide a reproducible test case that is the bare minimum necessary to generate the problem.
See above.

**Other info / logs**

```
['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)
```

There are 2 `weight_normalization/kernel:0`.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tensorflow_addons/layers/wrappers.py`
Content:
```
1 # Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 # =============================================================================
15 from __future__ import absolute_import
16 from __future__ import division
17 from __future__ import print_function
18 
19 import tensorflow as tf
20 
21 
22 @tf.keras.utils.register_keras_serializable(package='Addons')
23 class WeightNormalization(tf.keras.layers.Wrapper):
24     """This wrapper reparameterizes a layer by decoupling the weight's
25     magnitude and direction.
26 
27     This speeds up convergence by improving the
28     conditioning of the optimization problem.
29     Weight Normalization: A Simple Reparameterization to Accelerate
30     Training of Deep Neural Networks: https://arxiv.org/abs/1602.07868
31     Tim Salimans, Diederik P. Kingma (2016)
32     WeightNormalization wrapper works for keras and tf layers.
33     ```python
34       net = WeightNormalization(
35           tf.keras.layers.Conv2D(2, 2, activation='relu'),
36           input_shape=(32, 32, 3),
37           data_init=True)(x)
38       net = WeightNormalization(
39           tf.keras.layers.Conv2D(16, 5, activation='relu'),
40           data_init=True)(net)
41       net = WeightNormalization(
42           tf.keras.layers.Dense(120, activation='relu'),
43           data_init=True)(net)
44       net = WeightNormalization(
45           tf.keras.layers.Dense(n_classes),
46           data_init=True)(net)
47     ```
48     Arguments:
49       layer: a layer instance.
50       data_init: If `True` use data dependent variable initialization
51     Raises:
52       ValueError: If not initialized with a `Layer` instance.
53       ValueError: If `Layer` does not contain a `kernel` of weights
54       NotImplementedError: If `data_init` is True and running graph execution
55     """
56 
57     def __init__(self, layer, data_init=True, **kwargs):
58         super(WeightNormalization, self).__init__(layer, **kwargs)
59         self.data_init = data_init
60         self._track_trackable(layer, name='layer')
61 
62     def build(self, input_shape):
63         """Build `Layer`"""
64         input_shape = tf.TensorShape(input_shape).as_list()
65         self.input_spec = tf.keras.layers.InputSpec(
66             shape=[None] + input_shape[1:])
67 
68         if not self.layer.built:
69             self.layer.build(input_shape)
70 
71         if not hasattr(self.layer, 'kernel'):
72             raise ValueError('`WeightNormalization` must wrap a layer that'
73                              ' contains a `kernel` for weights')
74 
75         # The kernel's filter or unit dimension is -1
76         self.layer_depth = int(self.layer.kernel.shape[-1])
77         self.kernel_norm_axes = list(range(self.layer.kernel.shape.rank - 1))
78 
79         self.g = self.add_weight(
80             name='g',
81             shape=(self.layer_depth,),
82             initializer='ones',
83             dtype=self.layer.kernel.dtype,
84             trainable=True)
85         self.v = self.layer.kernel
86 
87         self._initialized = self.add_weight(
88             name='initialized',
89             shape=None,
90             initializer='zeros',
91             dtype=tf.dtypes.bool,
92             trainable=False)
93 
94         if self.data_init:
95             # Used for data initialization in self._data_dep_init.
96             layer_config = tf.keras.layers.serialize(self.layer)
97             layer_config['config']['trainable'] = False
98             self._naked_clone_layer = tf.keras.layers.deserialize(layer_config)
99             self._naked_clone_layer.build(input_shape)
100             self._naked_clone_layer.set_weights(self.layer.get_weights())
101             self._naked_clone_layer.activation = None
102 
103         self.built = True
104 
105     def call(self, inputs):
106         """Call `Layer`"""
107 
108         def _do_nothing():
109             return tf.identity(self.g)
110 
111         def _update_weights():
112             # Ensure we read `self.g` after _update_weights.
113             with tf.control_dependencies(self._initialize_weights(inputs)):
114                 return tf.identity(self.g)
115 
116         g = tf.cond(self._initialized, _do_nothing, _update_weights)
117 
118         with tf.name_scope('compute_weights'):
119             # Replace kernel by normalized weight variable.
120             self.layer.kernel = tf.nn.l2_normalize(
121                 self.v, axis=self.kernel_norm_axes) * g
122 
123             # Ensure we calculate result after updating kernel.
124             update_kernel = tf.identity(self.layer.kernel)
125             with tf.control_dependencies([update_kernel]):
126                 outputs = self.layer(inputs)
127                 return outputs
128 
129     def compute_output_shape(self, input_shape):
130         return tf.TensorShape(
131             self.layer.compute_output_shape(input_shape).as_list())
132 
133     def _initialize_weights(self, inputs):
134         """Initialize weight g.
135 
136         The initial value of g could either from the initial value in v,
137         or by the input value if self.data_init is True.
138         """
139         with tf.control_dependencies([
140                 tf.debugging.assert_equal(  # pylint: disable=bad-continuation
141                     self._initialized,
142                     False,
143                     message='The layer has been initialized.')
144         ]):
145             if self.data_init:
146                 assign_tensors = self._data_dep_init(inputs)
147             else:
148                 assign_tensors = self._init_norm()
149             assign_tensors.append(self._initialized.assign(True))
150             return assign_tensors
151 
152     def _init_norm(self):
153         """Set the weight g with the norm of the weight vector."""
154         with tf.name_scope('init_norm'):
155             v_flat = tf.reshape(self.v, [-1, self.layer_depth])
156             v_norm = tf.linalg.norm(v_flat, axis=0)
157             g_tensor = self.g.assign(tf.reshape(v_norm, (self.layer_depth,)))
158             return [g_tensor]
159 
160     def _data_dep_init(self, inputs):
161         """Data dependent initialization."""
162         with tf.name_scope('data_dep_init'):
163             # Generate data dependent init values
164             x_init = self._naked_clone_layer(inputs)
165             data_norm_axes = list(range(x_init.shape.rank - 1))
166             m_init, v_init = tf.nn.moments(x_init, data_norm_axes)
167             scale_init = 1. / tf.math.sqrt(v_init + 1e-10)
168 
169             # Assign data dependent init values
170             g_tensor = self.g.assign(self.g * scale_init)
171             if hasattr(self.layer, 'bias'):
172                 bias_tensor = self.layer.bias.assign(-m_init * scale_init)
173                 return [g_tensor, bias_tensor]
174             else:
175                 return [g_tensor]
176 
177     def get_config(self):
178         config = {'data_init': self.data_init}
179         base_config = super(WeightNormalization, self).get_config()
180         return dict(list(base_config.items()) + list(config.items()))
181
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/tensorflow_addons/layers/wrappers.py b/tensorflow_addons/layers/wrappers.py
--- a/tensorflow_addons/layers/wrappers.py
+++ b/tensorflow_addons/layers/wrappers.py
@@ -93,12 +93,14 @@
 
         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
+            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

{"golden_diff": "diff --git a/tensorflow_addons/layers/wrappers.py b/tensorflow_addons/layers/wrappers.py\n--- a/tensorflow_addons/layers/wrappers.py\n+++ b/tensorflow_addons/layers/wrappers.py\n@@ -93,12 +93,14 @@\n \n         if self.data_init:\n             # Used for data initialization in self._data_dep_init.\n-            layer_config = tf.keras.layers.serialize(self.layer)\n-            layer_config['config']['trainable'] = False\n-            self._naked_clone_layer = tf.keras.layers.deserialize(layer_config)\n-            self._naked_clone_layer.build(input_shape)\n-            self._naked_clone_layer.set_weights(self.layer.get_weights())\n-            self._naked_clone_layer.activation = None\n+            with tf.name_scope('data_dep_init'):\n+                layer_config = tf.keras.layers.serialize(self.layer)\n+                layer_config['config']['trainable'] = False\n+                self._naked_clone_layer = tf.keras.layers.deserialize(\n+                    layer_config)\n+                self._naked_clone_layer.build(input_shape)\n+                self._naked_clone_layer.set_weights(self.layer.get_weights())\n+                self._naked_clone_layer.activation = None\n \n         self.built = True\n", "issue": "WeightNormalization layer can't save in h5\n**System information**\r\n- OS Platform and Distribution (e.g., Linux Ubuntu 16.04):\r\nUbuntu 16.04.6 LTS\r\n- TensorFlow version and how it was installed (source or binary):\r\ntensorflow-gpu                   2.0.0, binary\r\n- TensorFlow-Addons version and how it was installed (source or binary):\r\ntensorflow-addons                0.6.0, binary\r\n- Python version:\r\nPython 3.6.9\r\n- Is GPU used? (yes/no):\r\nyes\r\n**Describe the bug**\r\nWeightNormalization layer can't save to h5\r\n\r\nA clear and concise description of what the bug is.\r\nWeightNormalization causing duplicate names of variables.\r\n\r\n**Code to reproduce the issue**\r\n\r\n```python\r\nimport tensorflow as tf\r\nimport tensorflow_addons as tfa\r\n\r\nconv = tf.keras.layers.Conv1D(1, 1, name='conv')\r\nwn_conv = tfa.layers.WeightNormalization(conv)\r\n\r\nmodel = tf.keras.Sequential(layers=[wn_conv])\r\nmodel.build([1, 2, 3])\r\nprint([w.name for w in model.layers[0].weights])\r\nmodel.save_weights('model.h5')\r\n```\r\n\r\nProvide a reproducible test case that is the bare minimum necessary to generate the problem.\r\nSee above.\r\n\r\n**Other info / logs**\r\n\r\n```\r\n['weight_normalization/g:0', 'weight_normalization/kernel:0', 'weight_normalization/bias:0', 'weight_normalization/initialized:0', 'weight_normalization/kernel:0', 'weight_normalization/bias:0']\r\nTraceback (most recent call last):\r\n  File \"/home/ubuntu/hankcs/laser/tests/playground/wn_bug.py\", line 14, in <module>\r\n    model.save_weights('model.h5')\r\n  File \"/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/network.py\", line 1074, in save_weights\r\n    saving.save_weights_to_hdf5_group(f, self.layers)\r\n  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\r\n    param_dset = g.create_dataset(name, val.shape, dtype=val.dtype)\r\n  File \"/home/ubuntu/.local/lib/python3.6/site-packages/h5py/_hl/group.py\", line 139, in create_dataset\r\n    self[name] = dset\r\n  File \"/home/ubuntu/.local/lib/python3.6/site-packages/h5py/_hl/group.py\", line 371, in __setitem__\r\n    h5o.link(obj.id, self.id, name, lcpl=lcpl, lapl=self._lapl)\r\n  File \"h5py/_objects.pyx\", line 54, in h5py._objects.with_phil.wrapper\r\n  File \"h5py/_objects.pyx\", line 55, in h5py._objects.with_phil.wrapper\r\n  File \"h5py/h5o.pyx\", line 202, in h5py.h5o.link\r\nRuntimeError: Unable to create link (name already exists)\r\n```\r\n\r\nThere are 2 `weight_normalization/kernel:0`.\r\n\n", "before_files": [{"content": "# Copyright 2019 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# =============================================================================\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport tensorflow as tf\n\n\n@tf.keras.utils.register_keras_serializable(package='Addons')\nclass WeightNormalization(tf.keras.layers.Wrapper):\n    \"\"\"This wrapper reparameterizes a layer by decoupling the weight's\n    magnitude and direction.\n\n    This speeds up convergence by improving the\n    conditioning of the optimization problem.\n    Weight Normalization: A Simple Reparameterization to Accelerate\n    Training of Deep Neural Networks: https://arxiv.org/abs/1602.07868\n    Tim Salimans, Diederik P. Kingma (2016)\n    WeightNormalization wrapper works for keras and tf layers.\n    ```python\n      net = WeightNormalization(\n          tf.keras.layers.Conv2D(2, 2, activation='relu'),\n          input_shape=(32, 32, 3),\n          data_init=True)(x)\n      net = WeightNormalization(\n          tf.keras.layers.Conv2D(16, 5, activation='relu'),\n          data_init=True)(net)\n      net = WeightNormalization(\n          tf.keras.layers.Dense(120, activation='relu'),\n          data_init=True)(net)\n      net = WeightNormalization(\n          tf.keras.layers.Dense(n_classes),\n          data_init=True)(net)\n    ```\n    Arguments:\n      layer: a layer instance.\n      data_init: If `True` use data dependent variable initialization\n    Raises:\n      ValueError: If not initialized with a `Layer` instance.\n      ValueError: If `Layer` does not contain a `kernel` of weights\n      NotImplementedError: If `data_init` is True and running graph execution\n    \"\"\"\n\n    def __init__(self, layer, data_init=True, **kwargs):\n        super(WeightNormalization, self).__init__(layer, **kwargs)\n        self.data_init = data_init\n        self._track_trackable(layer, name='layer')\n\n    def build(self, input_shape):\n        \"\"\"Build `Layer`\"\"\"\n        input_shape = tf.TensorShape(input_shape).as_list()\n        self.input_spec = tf.keras.layers.InputSpec(\n            shape=[None] + input_shape[1:])\n\n        if not self.layer.built:\n            self.layer.build(input_shape)\n\n        if not hasattr(self.layer, 'kernel'):\n            raise ValueError('`WeightNormalization` must wrap a layer that'\n                             ' contains a `kernel` for weights')\n\n        # The kernel's filter or unit dimension is -1\n        self.layer_depth = int(self.layer.kernel.shape[-1])\n        self.kernel_norm_axes = list(range(self.layer.kernel.shape.rank - 1))\n\n        self.g = self.add_weight(\n            name='g',\n            shape=(self.layer_depth,),\n            initializer='ones',\n            dtype=self.layer.kernel.dtype,\n            trainable=True)\n        self.v = self.layer.kernel\n\n        self._initialized = self.add_weight(\n            name='initialized',\n            shape=None,\n            initializer='zeros',\n            dtype=tf.dtypes.bool,\n            trainable=False)\n\n        if self.data_init:\n            # Used for data initialization in self._data_dep_init.\n            layer_config = tf.keras.layers.serialize(self.layer)\n            layer_config['config']['trainable'] = False\n            self._naked_clone_layer = tf.keras.layers.deserialize(layer_config)\n            self._naked_clone_layer.build(input_shape)\n            self._naked_clone_layer.set_weights(self.layer.get_weights())\n            self._naked_clone_layer.activation = None\n\n        self.built = True\n\n    def call(self, inputs):\n        \"\"\"Call `Layer`\"\"\"\n\n        def _do_nothing():\n            return tf.identity(self.g)\n\n        def _update_weights():\n            # Ensure we read `self.g` after _update_weights.\n            with tf.control_dependencies(self._initialize_weights(inputs)):\n                return tf.identity(self.g)\n\n        g = tf.cond(self._initialized, _do_nothing, _update_weights)\n\n        with tf.name_scope('compute_weights'):\n            # Replace kernel by normalized weight variable.\n            self.layer.kernel = tf.nn.l2_normalize(\n                self.v, axis=self.kernel_norm_axes) * g\n\n            # Ensure we calculate result after updating kernel.\n            update_kernel = tf.identity(self.layer.kernel)\n            with tf.control_dependencies([update_kernel]):\n                outputs = self.layer(inputs)\n                return outputs\n\n    def compute_output_shape(self, input_shape):\n        return tf.TensorShape(\n            self.layer.compute_output_shape(input_shape).as_list())\n\n    def _initialize_weights(self, inputs):\n        \"\"\"Initialize weight g.\n\n        The initial value of g could either from the initial value in v,\n        or by the input value if self.data_init is True.\n        \"\"\"\n        with tf.control_dependencies([\n                tf.debugging.assert_equal(  # pylint: disable=bad-continuation\n                    self._initialized,\n                    False,\n                    message='The layer has been initialized.')\n        ]):\n            if self.data_init:\n                assign_tensors = self._data_dep_init(inputs)\n            else:\n                assign_tensors = self._init_norm()\n            assign_tensors.append(self._initialized.assign(True))\n            return assign_tensors\n\n    def _init_norm(self):\n        \"\"\"Set the weight g with the norm of the weight vector.\"\"\"\n        with tf.name_scope('init_norm'):\n            v_flat = tf.reshape(self.v, [-1, self.layer_depth])\n            v_norm = tf.linalg.norm(v_flat, axis=0)\n            g_tensor = self.g.assign(tf.reshape(v_norm, (self.layer_depth,)))\n            return [g_tensor]\n\n    def _data_dep_init(self, inputs):\n        \"\"\"Data dependent initialization.\"\"\"\n        with tf.name_scope('data_dep_init'):\n            # Generate data dependent init values\n            x_init = self._naked_clone_layer(inputs)\n            data_norm_axes = list(range(x_init.shape.rank - 1))\n            m_init, v_init = tf.nn.moments(x_init, data_norm_axes)\n            scale_init = 1. / tf.math.sqrt(v_init + 1e-10)\n\n            # Assign data dependent init values\n            g_tensor = self.g.assign(self.g * scale_init)\n            if hasattr(self.layer, 'bias'):\n                bias_tensor = self.layer.bias.assign(-m_init * scale_init)\n                return [g_tensor, bias_tensor]\n            else:\n                return [g_tensor]\n\n    def get_config(self):\n        config = {'data_init': self.data_init}\n        base_config = super(WeightNormalization, self).get_config()\n        return dict(list(base_config.items()) + list(config.items()))\n", "path": "tensorflow_addons/layers/wrappers.py"}], "after_files": [{"content": "# Copyright 2019 The TensorFlow Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# =============================================================================\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport tensorflow as tf\n\n\n@tf.keras.utils.register_keras_serializable(package='Addons')\nclass WeightNormalization(tf.keras.layers.Wrapper):\n    \"\"\"This wrapper reparameterizes a layer by decoupling the weight's\n    magnitude and direction.\n\n    This speeds up convergence by improving the\n    conditioning of the optimization problem.\n    Weight Normalization: A Simple Reparameterization to Accelerate\n    Training of Deep Neural Networks: https://arxiv.org/abs/1602.07868\n    Tim Salimans, Diederik P. Kingma (2016)\n    WeightNormalization wrapper works for keras and tf layers.\n    ```python\n      net = WeightNormalization(\n          tf.keras.layers.Conv2D(2, 2, activation='relu'),\n          input_shape=(32, 32, 3),\n          data_init=True)(x)\n      net = WeightNormalization(\n          tf.keras.layers.Conv2D(16, 5, activation='relu'),\n          data_init=True)(net)\n      net = WeightNormalization(\n          tf.keras.layers.Dense(120, activation='relu'),\n          data_init=True)(net)\n      net = WeightNormalization(\n          tf.keras.layers.Dense(n_classes),\n          data_init=True)(net)\n    ```\n    Arguments:\n      layer: a layer instance.\n      data_init: If `True` use data dependent variable initialization\n    Raises:\n      ValueError: If not initialized with a `Layer` instance.\n      ValueError: If `Layer` does not contain a `kernel` of weights\n      NotImplementedError: If `data_init` is True and running graph execution\n    \"\"\"\n\n    def __init__(self, layer, data_init=True, **kwargs):\n        super(WeightNormalization, self).__init__(layer, **kwargs)\n        self.data_init = data_init\n        self._track_trackable(layer, name='layer')\n\n    def build(self, input_shape):\n        \"\"\"Build `Layer`\"\"\"\n        input_shape = tf.TensorShape(input_shape).as_list()\n        self.input_spec = tf.keras.layers.InputSpec(\n            shape=[None] + input_shape[1:])\n\n        if not self.layer.built:\n            self.layer.build(input_shape)\n\n        if not hasattr(self.layer, 'kernel'):\n            raise ValueError('`WeightNormalization` must wrap a layer that'\n                             ' contains a `kernel` for weights')\n\n        # The kernel's filter or unit dimension is -1\n        self.layer_depth = int(self.layer.kernel.shape[-1])\n        self.kernel_norm_axes = list(range(self.layer.kernel.shape.rank - 1))\n\n        self.g = self.add_weight(\n            name='g',\n            shape=(self.layer_depth,),\n            initializer='ones',\n            dtype=self.layer.kernel.dtype,\n            trainable=True)\n        self.v = self.layer.kernel\n\n        self._initialized = self.add_weight(\n            name='initialized',\n            shape=None,\n            initializer='zeros',\n            dtype=tf.dtypes.bool,\n            trainable=False)\n\n        if self.data_init:\n            # Used for data initialization in self._data_dep_init.\n            with tf.name_scope('data_dep_init'):\n                layer_config = tf.keras.layers.serialize(self.layer)\n                layer_config['config']['trainable'] = False\n                self._naked_clone_layer = tf.keras.layers.deserialize(\n                    layer_config)\n                self._naked_clone_layer.build(input_shape)\n                self._naked_clone_layer.set_weights(self.layer.get_weights())\n                self._naked_clone_layer.activation = None\n\n        self.built = True\n\n    def call(self, inputs):\n        \"\"\"Call `Layer`\"\"\"\n\n        def _do_nothing():\n            return tf.identity(self.g)\n\n        def _update_weights():\n            # Ensure we read `self.g` after _update_weights.\n            with tf.control_dependencies(self._initialize_weights(inputs)):\n                return tf.identity(self.g)\n\n        g = tf.cond(self._initialized, _do_nothing, _update_weights)\n\n        with tf.name_scope('compute_weights'):\n            # Replace kernel by normalized weight variable.\n            self.layer.kernel = tf.nn.l2_normalize(\n                self.v, axis=self.kernel_norm_axes) * g\n\n            # Ensure we calculate result after updating kernel.\n            update_kernel = tf.identity(self.layer.kernel)\n            with tf.control_dependencies([update_kernel]):\n                outputs = self.layer(inputs)\n                return outputs\n\n    def compute_output_shape(self, input_shape):\n        return tf.TensorShape(\n            self.layer.compute_output_shape(input_shape).as_list())\n\n    def _initialize_weights(self, inputs):\n        \"\"\"Initialize weight g.\n\n        The initial value of g could either from the initial value in v,\n        or by the input value if self.data_init is True.\n        \"\"\"\n        with tf.control_dependencies([\n                tf.debugging.assert_equal(  # pylint: disable=bad-continuation\n                    self._initialized,\n                    False,\n                    message='The layer has been initialized.')\n        ]):\n            if self.data_init:\n                assign_tensors = self._data_dep_init(inputs)\n            else:\n                assign_tensors = self._init_norm()\n            assign_tensors.append(self._initialized.assign(True))\n            return assign_tensors\n\n    def _init_norm(self):\n        \"\"\"Set the weight g with the norm of the weight vector.\"\"\"\n        with tf.name_scope('init_norm'):\n            v_flat = tf.reshape(self.v, [-1, self.layer_depth])\n            v_norm = tf.linalg.norm(v_flat, axis=0)\n            g_tensor = self.g.assign(tf.reshape(v_norm, (self.layer_depth,)))\n            return [g_tensor]\n\n    def _data_dep_init(self, inputs):\n        \"\"\"Data dependent initialization.\"\"\"\n        with tf.name_scope('data_dep_init'):\n            # Generate data dependent init values\n            x_init = self._naked_clone_layer(inputs)\n            data_norm_axes = list(range(x_init.shape.rank - 1))\n            m_init, v_init = tf.nn.moments(x_init, data_norm_axes)\n            scale_init = 1. / tf.math.sqrt(v_init + 1e-10)\n\n            # Assign data dependent init values\n            g_tensor = self.g.assign(self.g * scale_init)\n            if hasattr(self.layer, 'bias'):\n                bias_tensor = self.layer.bias.assign(-m_init * scale_init)\n                return [g_tensor, bias_tensor]\n            else:\n                return [g_tensor]\n\n    def get_config(self):\n        config = {'data_init': self.data_init}\n        base_config = super(WeightNormalization, self).get_config()\n        return dict(list(base_config.items()) + list(config.items()))\n", "path": "tensorflow_addons/layers/wrappers.py"}]}