Uses the layers in `layer_map` to make new nodes based on `nodes_by_depth`. Args: nodes_by_depth: Provides structure information to create new nodes. layer_fn: Function to clone layers. layer_map: Map from layers in `model` to new layers. tensor_map: Map from tensors in `model` to
(nodes_by_depth, layer_fn, layer_map, tensor_map)
| 71 | |
| 72 | |
| 73 | def _make_new_nodes(nodes_by_depth, layer_fn, layer_map, tensor_map): |
| 74 | """Uses the layers in `layer_map` to make new nodes based on `nodes_by_depth`. |
| 75 | |
| 76 | Args: |
| 77 | nodes_by_depth: Provides structure information to create new nodes. |
| 78 | layer_fn: Function to clone layers. |
| 79 | layer_map: Map from layers in `model` to new layers. |
| 80 | tensor_map: Map from tensors in `model` to newly compute tensors. |
| 81 | |
| 82 | Returns: |
| 83 | A set of new nodes. `layer_map` and `tensor_map` are updated. |
| 84 | """ |
| 85 | # Iterated over every node in the reference model, in depth order. |
| 86 | new_nodes = set() |
| 87 | depth_keys = list(nodes_by_depth.keys()) |
| 88 | depth_keys.sort(reverse=True) |
| 89 | for depth in depth_keys: |
| 90 | nodes = nodes_by_depth[depth] |
| 91 | for node in nodes: |
| 92 | # Recover the corresponding layer. |
| 93 | layer = node.outbound_layer |
| 94 | |
| 95 | # Get or create layer. |
| 96 | if layer not in layer_map: |
| 97 | new_layer = layer_fn(layer) |
| 98 | layer_map[layer] = new_layer |
| 99 | layer = new_layer |
| 100 | else: |
| 101 | # Reuse previously cloned layer. |
| 102 | layer = layer_map[layer] |
| 103 | # Don't call InputLayer multiple times. |
| 104 | if isinstance(layer, InputLayer): |
| 105 | continue |
| 106 | |
| 107 | # If all previous input tensors are available in tensor_map, |
| 108 | # then call node.inbound_layer on them. |
| 109 | if all( |
| 110 | tensor in tensor_map for tensor in nest.flatten(node.input_tensors)): |
| 111 | computed_tensors = nest.map_structure(lambda t: tensor_map[t], |
| 112 | node.input_tensors) |
| 113 | # Call layer. |
| 114 | kwargs = node.arguments or {} |
| 115 | output_tensors = layer(computed_tensors, **kwargs) |
| 116 | |
| 117 | # Thread-safe way to keep track of what node was created. |
| 118 | first_output_tensor = nest.flatten(output_tensors)[0] |
| 119 | new_nodes.add( |
| 120 | layer._inbound_nodes[first_output_tensor._keras_history.node_index]) |
| 121 | |
| 122 | for x, y in zip( |
| 123 | nest.flatten(node.output_tensors), nest.flatten(output_tensors)): |
| 124 | tensor_map[x] = y |
| 125 | return new_nodes |
| 126 | |
| 127 | |
| 128 | def _clone_functional_model(model, input_tensors=None, layer_fn=_clone_layer): |
no test coverage detected