[FEA] Organize Blocks' variables and ops names using tf.name_scope()
🚀 Feature request
Currently it is hard to map the variables and ops in the TF graph generated by Merlin Models to the corresponding Blocks.
We should organize Blocks' variables and ops with tf.name_scope(), to make it easier to inspect the generated TF graph and logged gradients in Tensorboard when needed.
For example, when you a TwoTowerModel and list the weights/variables with model.weights, it shows an MLP layer being named like below.
<tf.Variable 'private__dense_6[/dense_6/kernel:0]()' shape=(256, 64) dtype=float32>
We should have the blocks names as scope for the contained variables and ops, and maybe allow for custom scopes related to the architecture (e.g. user_tower, item_tower), producing a variable name like item_tower/mlp_block/dense_1.
P.s. When providing for TwoTowerModel only the query_tower argument, the item_tower is automatically generated under-the-hood by doing query_tower.copy(). But that method returns a block with the same variable names, which makes it difficult to inspect the variables and gradients for the two towers MLP layers separately. Maybe the name scopes can be used to solve this issue. Otherwise, maybe Block.copy() should ensure that the new variables have different names (e.g. by using tf.Graph.unique_name() ?)