Return the submodule given by ``target`` if it exists, otherwise throw an error. For example, let's say you have an ``nn.Module`` ``A`` that looks like this: .. code-block:: text A( (net_b): Module( (net_c): Module(
(self, target: str)
| 624 | self.add_module(name, module) |
| 625 | |
| 626 | def get_submodule(self, target: str) -> "Module": |
| 627 | """Return the submodule given by ``target`` if it exists, otherwise throw an error. |
| 628 | |
| 629 | For example, let's say you have an ``nn.Module`` ``A`` that |
| 630 | looks like this: |
| 631 | |
| 632 | .. code-block:: text |
| 633 | |
| 634 | A( |
| 635 | (net_b): Module( |
| 636 | (net_c): Module( |
| 637 | (conv): Conv2d(16, 33, kernel_size=(3, 3), stride=(2, 2)) |
| 638 | ) |
| 639 | (linear): Linear(in_features=100, out_features=200, bias=True) |
| 640 | ) |
| 641 | ) |
| 642 | |
| 643 | (The diagram shows an ``nn.Module`` ``A``. ``A`` has a nested |
| 644 | submodule ``net_b``, which itself has two submodules ``net_c`` |
| 645 | and ``linear``. ``net_c`` then has a submodule ``conv``.) |
| 646 | |
| 647 | To check whether or not we have the ``linear`` submodule, we |
| 648 | would call ``get_submodule("net_b.linear")``. To check whether |
| 649 | we have the ``conv`` submodule, we would call |
| 650 | ``get_submodule("net_b.net_c.conv")``. |
| 651 | |
| 652 | The runtime of ``get_submodule`` is bounded by the degree |
| 653 | of module nesting in ``target``. A query against |
| 654 | ``named_modules`` achieves the same result, but it is O(N) in |
| 655 | the number of transitive modules. So, for a simple check to see |
| 656 | if some submodule exists, ``get_submodule`` should always be |
| 657 | used. |
| 658 | |
| 659 | Args: |
| 660 | target: The fully-qualified string name of the submodule |
| 661 | to look for. (See above example for how to specify a |
| 662 | fully-qualified string.) |
| 663 | |
| 664 | Returns: |
| 665 | torch.nn.Module: The submodule referenced by ``target`` |
| 666 | |
| 667 | Raises: |
| 668 | AttributeError: If the target string references an invalid |
| 669 | path or resolves to something that is not an |
| 670 | ``nn.Module`` |
| 671 | """ |
| 672 | if target == "": |
| 673 | return self |
| 674 | |
| 675 | atoms: List[str] = target.split(".") |
| 676 | mod: torch.nn.Module = self |
| 677 | |
| 678 | for item in atoms: |
| 679 | |
| 680 | if not hasattr(mod, item): |
| 681 | raise AttributeError(mod._get_name() + " has no " |
| 682 | "attribute `" + item + "`") |
| 683 |