Validates a network's topology and gather its layers and nodes. Arguments: inputs: List of input tensors. outputs: List of outputs tensors. Returns: A tuple `(nodes, nodes_by_depth, layers, layers_by_depth)`. - nodes: list of Node instances. - nodes_by_depth: dict mapping i
(inputs, outputs)
| 1651 | |
| 1652 | |
| 1653 | def _map_graph_network(inputs, outputs): |
| 1654 | """Validates a network's topology and gather its layers and nodes. |
| 1655 | |
| 1656 | Arguments: |
| 1657 | inputs: List of input tensors. |
| 1658 | outputs: List of outputs tensors. |
| 1659 | |
| 1660 | Returns: |
| 1661 | A tuple `(nodes, nodes_by_depth, layers, layers_by_depth)`. |
| 1662 | - nodes: list of Node instances. |
| 1663 | - nodes_by_depth: dict mapping ints (depth) to lists of node instances. |
| 1664 | - layers: list of Layer instances. |
| 1665 | - layers_by_depth: dict mapping ints (depth) to lists of layer instances. |
| 1666 | |
| 1667 | Raises: |
| 1668 | ValueError: In case the network is not valid (e.g. disconnected graph). |
| 1669 | """ |
| 1670 | # Network_nodes: set of nodes included in the graph of layers |
| 1671 | # (not all nodes included in the layers are relevant to the current graph). |
| 1672 | network_nodes = set() # ids of all nodes relevant to the Network |
| 1673 | nodes_depths = {} # dict {node: depth value} |
| 1674 | layers_depths = {} # dict {layer: depth value} |
| 1675 | layer_indices = {} # dict {layer: index in traversal} |
| 1676 | nodes_in_decreasing_depth = [] |
| 1677 | |
| 1678 | def build_map(tensor, |
| 1679 | finished_nodes, |
| 1680 | nodes_in_progress, |
| 1681 | layer, |
| 1682 | node_index, |
| 1683 | tensor_index): |
| 1684 | """Builds a map of the graph of layers. |
| 1685 | |
| 1686 | This recursively updates the map `layer_indices`, |
| 1687 | the list `nodes_in_decreasing_depth` and the set `network_nodes`. |
| 1688 | |
| 1689 | Arguments: |
| 1690 | tensor: Some tensor in a graph. |
| 1691 | finished_nodes: Set of nodes whose subgraphs have been traversed |
| 1692 | completely. Useful to prevent duplicated work. |
| 1693 | nodes_in_progress: Set of nodes that are currently active on the |
| 1694 | recursion stack. Useful to detect cycles. |
| 1695 | layer: Layer from which `tensor` comes from. If not provided, |
| 1696 | will be obtained from `tensor._keras_history`. |
| 1697 | node_index: Node index from which `tensor` comes from. |
| 1698 | tensor_index: Tensor_index from which `tensor` comes from. |
| 1699 | |
| 1700 | Raises: |
| 1701 | ValueError: if a cycle is detected. |
| 1702 | """ |
| 1703 | node = layer._inbound_nodes[node_index] # pylint: disable=protected-access |
| 1704 | |
| 1705 | # Prevent cycles. |
| 1706 | if node in nodes_in_progress: |
| 1707 | raise ValueError('The tensor ' + str(tensor) + ' at layer "' + |
| 1708 | layer.name + '" is part of a cycle.') |
| 1709 | |
| 1710 | # Don't repeat work for shared subgraphs |
no test coverage detected