# Module `models.resnet_cifarlike`

ResNet in PyTorch.

For Pre-activation ResNet, see 'preact_resnet.py'.

Reference: [1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun Deep Residual Learning for Image Recognition. arXiv:1512.03385

Expand source code

    #!/usr/bin/env python3

    # From: https://github.com/kuangliu/pytorch-cifar

    """ResNet in PyTorch.

    For Pre-activation ResNet, see 'preact_resnet.py'.

    Reference:
    [1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
        Deep Residual Learning for Image Recognition. arXiv:1512.03385
    """
    import torch.nn as nn

    # Import PyTorch layers, activations and more
    import torch.nn.functional as F

    class BasicBlock(nn.Module):
        expansion = 1

        def __init__(self, in_planes, planes, stride=1):
            super(BasicBlock, self).__init__()
            self.conv1 = nn.Conv2d(
                in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
            self.bn1 = nn.BatchNorm2d(planes)
            self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
                                   stride=1, padding=1, bias=False)
            self.bn2 = nn.BatchNorm2d(planes)

            self.shortcut = nn.Sequential()
            if stride != 1 or in_planes != self.expansion*planes:
                self.shortcut = nn.Sequential(
                    nn.Conv2d(in_planes, self.expansion*planes,
                              kernel_size=1, stride=stride, bias=False),
                    nn.BatchNorm2d(self.expansion*planes)
                )

            self.relu = nn.ReLU()

        def forward(self, x):
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.bn2(self.conv2(out))
            out += self.shortcut(x)
            out = self.relu(out)
            return out

    class Bottleneck(nn.Module):
        expansion = 4

        def __init__(self, in_planes, planes, stride=1):
            super(Bottleneck, self).__init__()
            self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
            self.bn1 = nn.BatchNorm2d(planes)
            self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
                                   stride=stride, padding=1, bias=False)
            self.bn2 = nn.BatchNorm2d(planes)
            self.conv3 = nn.Conv2d(planes, self.expansion *
                                   planes, kernel_size=1, bias=False)
            self.bn3 = nn.BatchNorm2d(self.expansion*planes)

            self.shortcut = nn.Sequential()
            if stride != 1 or in_planes != self.expansion*planes:
                self.shortcut = nn.Sequential(
                    nn.Conv2d(in_planes, self.expansion*planes,
                              kernel_size=1, stride=stride, bias=False),
                    nn.BatchNorm2d(self.expansion*planes)
                )
            self.relu = nn.ReLU()

        def forward(self, x):
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.relu(self.bn2(self.conv2(out)))
            out = self.bn3(self.conv3(out))
            out += self.shortcut(x)
            out = self.relu(out)
            return out

    class ResNet(nn.Module):
        def __init__(self, block, num_blocks, num_classes=10):
            super(ResNet, self).__init__()
            self.in_planes = 64

            self.conv1 = nn.Conv2d(3, 64, kernel_size=3,
                                   stride=1, padding=1, bias=False)
            self.bn1 = nn.BatchNorm2d(64)
            self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
            self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
            self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
            self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
            self.linear = nn.Linear(512*block.expansion, num_classes)
            self.relu = nn.ReLU()

        def _make_layer(self, block, planes, num_blocks, stride):
            strides = [stride] + [1]*(num_blocks-1)
            layers = []
            for stride in strides:
                layers.append(block(self.in_planes, planes, stride))
                self.in_planes = planes * block.expansion
            return nn.Sequential(*layers)

        def forward(self, x):
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.layer1(out)
            out = self.layer2(out)
            out = self.layer3(out)
            out = self.layer4(out)
            out = F.avg_pool2d(out, 4)
            out = out.view(out.size(0), -1)
            out = self.linear(out)
            return out

    # TODO: Any way we can actually have an useful pretrained argument here?
    def ResNet18(pretrained=False, num_classes=10):
        return ResNet(BasicBlock, [2, 2, 2, 2], num_classes=num_classes)

    def ResNet34(pretrained=False, num_classes=10):
        return ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes)

    def ResNet50(pretrained=False, num_classes=10):
        return ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes)

    def ResNet101(pretrained=False, num_classes=10):
        return ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes)

    def ResNet152(pretrained=False, num_classes=10):
        return ResNet(Bottleneck, [3, 8, 36, 3], num_classes=num_classes)

## Functions

`def ResNet101(pretrained=False, num_classes=10)`
  Expand source code

      def ResNet101(pretrained=False, num_classes=10):
          return ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes)

`def ResNet152(pretrained=False, num_classes=10)`
  Expand source code

      def ResNet152(pretrained=False, num_classes=10):
          return ResNet(Bottleneck, [3, 8, 36, 3], num_classes=num_classes)

`def ResNet18(pretrained=False, num_classes=10)`
  Expand source code

      def ResNet18(pretrained=False, num_classes=10):
          return ResNet(BasicBlock, [2, 2, 2, 2], num_classes=num_classes)

`def ResNet34(pretrained=False, num_classes=10)`
  Expand source code

      def ResNet34(pretrained=False, num_classes=10):
          return ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes)

`def ResNet50(pretrained=False, num_classes=10)`
  Expand source code

      def ResNet50(pretrained=False, num_classes=10):
          return ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes)

## Classes

`class BasicBlock (in_planes, planes, stride=1)`

  Base class for all neural network modules.

  Your models should also subclass this class.

  Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::

      import torch.nn as nn
      import torch.nn.functional as F

      class Model(nn.Module):
          def __init__(self):
              super(Model, self).__init__()
              self.conv1 = nn.Conv2d(1, 20, 5)
              self.conv2 = nn.Conv2d(20, 20, 5)

          def forward(self, x):
              x = F.relu(self.conv1(x))
              return F.relu(self.conv2(x))

  Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:`to`, etc.

  :ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool

  Initializes internal Module state, shared by both nn.Module and ScriptModule.

  Expand source code

      class BasicBlock(nn.Module):
          expansion = 1

          def __init__(self, in_planes, planes, stride=1):
              super(BasicBlock, self).__init__()
              self.conv1 = nn.Conv2d(
                  in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
              self.bn1 = nn.BatchNorm2d(planes)
              self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
                                     stride=1, padding=1, bias=False)
              self.bn2 = nn.BatchNorm2d(planes)

              self.shortcut = nn.Sequential()
              if stride != 1 or in_planes != self.expansion*planes:
                  self.shortcut = nn.Sequential(
                      nn.Conv2d(in_planes, self.expansion*planes,
                                kernel_size=1, stride=stride, bias=False),
                      nn.BatchNorm2d(self.expansion*planes)
                  )

              self.relu = nn.ReLU()

          def forward(self, x):
              out = self.relu(self.bn1(self.conv1(x)))
              out = self.bn2(self.conv2(out))
              out += self.shortcut(x)
              out = self.relu(out)
              return out

  ### Ancestors

  - torch.nn.modules.module.Module

  ### Class variables

  `var dump_patches : bool`
  `var expansion`
  `var training : bool`

  ### Methods

  `def forward(self, x) ‑> Callable[..., Any]`

    Defines the computation performed at every call.

    Should be overridden by all subclasses.

    Note

    Although the recipe for forward pass needs to be defined within this function, one should call the :class:`Module` instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.

    Expand source code

        def forward(self, x):
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.bn2(self.conv2(out))
            out += self.shortcut(x)
            out = self.relu(out)
            return out

`class Bottleneck (in_planes, planes, stride=1)`

  Base class for all neural network modules.

  Your models should also subclass this class.

  Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::

      import torch.nn as nn
      import torch.nn.functional as F

      class Model(nn.Module):
          def __init__(self):
              super(Model, self).__init__()
              self.conv1 = nn.Conv2d(1, 20, 5)
              self.conv2 = nn.Conv2d(20, 20, 5)

          def forward(self, x):
              x = F.relu(self.conv1(x))
              return F.relu(self.conv2(x))

  Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:`to`, etc.

  :ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool

  Initializes internal Module state, shared by both nn.Module and ScriptModule.

  Expand source code

      class Bottleneck(nn.Module):
          expansion = 4

          def __init__(self, in_planes, planes, stride=1):
              super(Bottleneck, self).__init__()
              self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
              self.bn1 = nn.BatchNorm2d(planes)
              self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
                                     stride=stride, padding=1, bias=False)
              self.bn2 = nn.BatchNorm2d(planes)
              self.conv3 = nn.Conv2d(planes, self.expansion *
                                     planes, kernel_size=1, bias=False)
              self.bn3 = nn.BatchNorm2d(self.expansion*planes)

              self.shortcut = nn.Sequential()
              if stride != 1 or in_planes != self.expansion*planes:
                  self.shortcut = nn.Sequential(
                      nn.Conv2d(in_planes, self.expansion*planes,
                                kernel_size=1, stride=stride, bias=False),
                      nn.BatchNorm2d(self.expansion*planes)
                  )
              self.relu = nn.ReLU()

          def forward(self, x):
              out = self.relu(self.bn1(self.conv1(x)))
              out = self.relu(self.bn2(self.conv2(out)))
              out = self.bn3(self.conv3(out))
              out += self.shortcut(x)
              out = self.relu(out)
              return out

  ### Ancestors

  - torch.nn.modules.module.Module

  ### Class variables

  `var dump_patches : bool`
  `var expansion`
  `var training : bool`

  ### Methods

  `def forward(self, x) ‑> Callable[..., Any]`

    Defines the computation performed at every call.

    Should be overridden by all subclasses.

    Note

    Although the recipe for forward pass needs to be defined within this function, one should call the :class:`Module` instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.

    Expand source code

        def forward(self, x):
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.relu(self.bn2(self.conv2(out)))
            out = self.bn3(self.conv3(out))
            out += self.shortcut(x)
            out = self.relu(out)
            return out

`class ResNet (block, num_blocks, num_classes=10)`

  Base class for all neural network modules.

  Your models should also subclass this class.

  Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::

      import torch.nn as nn
      import torch.nn.functional as F

      class Model(nn.Module):
          def __init__(self):
              super(Model, self).__init__()
              self.conv1 = nn.Conv2d(1, 20, 5)
              self.conv2 = nn.Conv2d(20, 20, 5)

          def forward(self, x):
              x = F.relu(self.conv1(x))
              return F.relu(self.conv2(x))

  Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:`to`, etc.

  :ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool

  Initializes internal Module state, shared by both nn.Module and ScriptModule.

  Expand source code

      class ResNet(nn.Module):
          def __init__(self, block, num_blocks, num_classes=10):
              super(ResNet, self).__init__()
              self.in_planes = 64

              self.conv1 = nn.Conv2d(3, 64, kernel_size=3,
                                     stride=1, padding=1, bias=False)
              self.bn1 = nn.BatchNorm2d(64)
              self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
              self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
              self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
              self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
              self.linear = nn.Linear(512*block.expansion, num_classes)
              self.relu = nn.ReLU()

          def _make_layer(self, block, planes, num_blocks, stride):
              strides = [stride] + [1]*(num_blocks-1)
              layers = []
              for stride in strides:
                  layers.append(block(self.in_planes, planes, stride))
                  self.in_planes = planes * block.expansion
              return nn.Sequential(*layers)

          def forward(self, x):
              out = self.relu(self.bn1(self.conv1(x)))
              out = self.layer1(out)
              out = self.layer2(out)
              out = self.layer3(out)
              out = self.layer4(out)
              out = F.avg_pool2d(out, 4)
              out = out.view(out.size(0), -1)
              out = self.linear(out)
              return out

  ### Ancestors

  - torch.nn.modules.module.Module

  ### Class variables

  `var dump_patches : bool`
  `var training : bool`

  ### Methods

  `def forward(self, x) ‑> Callable[..., Any]`

    Defines the computation performed at every call.

    Should be overridden by all subclasses.

    Note

    Although the recipe for forward pass needs to be defined within this function, one should call the :class:`Module` instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.

    Expand source code

        def forward(self, x):
            out = self.relu(self.bn1(self.conv1(x)))
            out = self.layer1(out)
            out = self.layer2(out)
            out = self.layer3(out)
            out = self.layer4(out)
            out = F.avg_pool2d(out, 4)
            out = out.view(out.size(0), -1)
            out = self.linear(out)
            return out