1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
   | """resnet in pytorch
 
 
  [1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun.
      Deep Residual Learning for Image Recognition     https://arxiv.org/abs/1512.03385v1 """
  import torch import torch.nn as nn
  class BasicBlock(nn.Module):     """Basic Block for resnet 18 and resnet 34
      """
                          expansion = 1
      def __init__(self, in_channels, out_channels, stride=1):         super().__init__()
                   self.residual_function = nn.Sequential(             nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False),             nn.BatchNorm2d(out_channels),             nn.ReLU(inplace=True),             nn.Conv2d(out_channels, out_channels * BasicBlock.expansion, kernel_size=3, padding=1, bias=False),             nn.BatchNorm2d(out_channels * BasicBlock.expansion)         )
                   self.shortcut = nn.Sequential()
                            if stride != 1 or in_channels != BasicBlock.expansion * out_channels:             self.shortcut = nn.Sequential(                 nn.Conv2d(in_channels, out_channels * BasicBlock.expansion, kernel_size=1, stride=stride, bias=False),                 nn.BatchNorm2d(out_channels * BasicBlock.expansion)             )
      def forward(self, x):         return nn.ReLU(inplace=True)(self.residual_function(x) + self.shortcut(x))
  class BottleNeck(nn.Module):     """Residual block for resnet over 50 layers
      """     expansion = 4     def __init__(self, in_channels, out_channels, stride=1):         super().__init__()         self.residual_function = nn.Sequential(             nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False),             nn.BatchNorm2d(out_channels),             nn.ReLU(inplace=True),             nn.Conv2d(out_channels, out_channels, stride=stride, kernel_size=3, padding=1, bias=False),             nn.BatchNorm2d(out_channels),             nn.ReLU(inplace=True),             nn.Conv2d(out_channels, out_channels * BottleNeck.expansion, kernel_size=1, bias=False),             nn.BatchNorm2d(out_channels * BottleNeck.expansion),         )
          self.shortcut = nn.Sequential()
          if stride != 1 or in_channels != out_channels * BottleNeck.expansion:             self.shortcut = nn.Sequential(                 nn.Conv2d(in_channels, out_channels * BottleNeck.expansion, stride=stride, kernel_size=1, bias=False),                 nn.BatchNorm2d(out_channels * BottleNeck.expansion)             )
      def forward(self, x):         return nn.ReLU(inplace=True)(self.residual_function(x) + self.shortcut(x))
  class ResNet(nn.Module):
      def __init__(self, block, num_block, num_classes=100):         super().__init__()
          self.in_channels = 64
          self.conv1 = nn.Sequential(             nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False),             nn.BatchNorm2d(64),             nn.ReLU(inplace=True))                           self.conv2_x = self._make_layer(block, 64, num_block[0], 1)         self.conv3_x = self._make_layer(block, 128, num_block[1], 2)         self.conv4_x = self._make_layer(block, 256, num_block[2], 2)         self.conv5_x = self._make_layer(block, 512, num_block[3], 2)         self.avg_pool = nn.AdaptiveAvgPool2d((1, 1))         self.fc = nn.Linear(512 * block.expansion, num_classes)
      def _make_layer(self, block, out_channels, num_blocks, stride):         """make resnet layers(by layer i didnt mean this 'layer' was the         same as a neuron netowork layer, ex. conv layer), one layer may         contain more than one residual block
          Args:             block: block type, basic block or bottle neck block             out_channels: output depth channel number of this layer             num_blocks: how many blocks per layer             stride: the stride of the first block of this layer
          Return:             return a resnet layer         """
                            strides = [stride] + [1] * (num_blocks - 1)         layers = []         for stride in strides:             layers.append(block(self.in_channels, out_channels, stride))             self.in_channels = out_channels * block.expansion
          return nn.Sequential(*layers)
      def forward(self, x):         output = self.conv1(x)         output = self.conv2_x(output)         output = self.conv3_x(output)         output = self.conv4_x(output)         output = self.conv5_x(output)         output = self.avg_pool(output)         output = output.view(output.size(0), -1)         output = self.fc(output)
          return output
  def resnet18():     """ return a ResNet 18 object     """     return ResNet(BasicBlock, [2, 2, 2, 2])
  def resnet34():     """ return a ResNet 34 object     """     return ResNet(BasicBlock, [3, 4, 6, 3])
  def resnet50():     """ return a ResNet 50 object     """     return ResNet(BottleNeck, [3, 4, 6, 3])
  def resnet101():     """ return a ResNet 101 object     """     return ResNet(BottleNeck, [3, 4, 23, 3])
  def resnet152():     """ return a ResNet 152 object     """     return ResNet(BottleNeck, [3, 8, 36, 3])
 
 
 
   |