![]() Sequential ( * layers ) def forward ( self, x ): x = self. expansion for i in range ( 1, blocks ): layers. inplanes, planes, stride, downsample )) self. expansion, kernel_size = 1, stride = stride, bias = False ), nn. ![]() zero_ () def _make_layer ( self, block, planes, blocks, stride = 1 ): downsample = None if stride != 1 or self. _make_layer ( block, 512, layers, stride = 2 ) self. _make_layer ( block, 256, layers, stride = 2 ) self. _make_layer ( block, 128, layers, stride = 2 ) self. _make_layer ( block, 64, layers ) self. MaxPool2d ( kernel_size = 3, stride = 2, padding = 1 ) self. Conv2d ( 3, 64, kernel_size = 7, stride = 2, padding = 3, bias = False ) self. inplanes = 64 super ( ResNetOld, self ). Module ): def _init_ ( self, block, layers, num_classes = 1000 ): self. relu ( combined, inplace = True )Ĭlass ResNetOld ( nn. BatchNorm2d ( out_channels ), ) def forward ( self, x ): if self. BatchNorm2d ( bottleneck_channels ), # Use 1x1 grouped convolution to expand from # bottleneck_channels to out_channels conv1x1 ( bottleneck_channels, out_channels, groups = groups ), nn. ReLU ( inplace = True ), # channel shuffle Rearrange ( 'b (c1 c2) h w -> b (c2 c1) h w', c1 = groups ), # 3x3 depthwise convolution followed by batch conv3x3 ( bottleneck_channels, bottleneck_channels, stride = depthwise_stride, groups = bottleneck_channels ), nn. conv1x1 ( in_channels, bottleneck_channels, groups = first_1x1_groups ), nn. Sequential ( # Use a 1x1 grouped or non-grouped convolution to reduce input channels # to bottleneck channels, as in a ResNet bottleneck module. out_channels -= in_channels assert out_channels > 0 self. AvgPool2d ( kernel_size = 3, stride = 2, padding = 1 ) depthwise_stride = 2 # ensure output of concat has the same channels as original output channels. left = Rearrange ( '.->.' ) # identity depthwise_stride = 1 else : # ShuffleUnit Figure 2c self. combine = combine if combine = 'add' : # ShuffleUnit Figure 2b self. _init_ () first_1x1_groups = groups if grouped_conv else 1 bottleneck_channels = out_channels // 4 self. Module ): def _init_ ( self, in_channels, out_channels, groups = 3, grouped_conv = True, combine = 'add' ): super (). _combine_func ( residual, out ) return F. g_conv_1x1_compress ( x ) out = channel_shuffle ( out, self. avg_pool2d ( residual, kernel_size = 3, stride = 2, padding = 1 ) out = self. Sequential ( modules ) else : return conv def forward ( self, x ): # save for combining later with output residual = x if self. ![]() ReLU () if len ( modules ) > 1 : return nn. BatchNorm2d ( out_channels ) if relu : modules = nn. cat (( x, out ), 1 ) def _make_grouped_conv1x1 ( self, in_channels, out_channels, groups, batch_norm = True, relu = False ): modules = OrderedDict () conv = conv1x1 ( in_channels, out_channels, groups = groups ) modules = conv if batch_norm : modules = nn. ![]() groups, batch_norm = True, relu = False ) def _add ( x, out ): # residual connection return x + out def _concat ( x, out ): # concatenate along channel axis return torch. bottleneck_channels ) # Use 1x1 grouped convolution to expand from # bottleneck_channels to out_channels self. first_1x1_groups, batch_norm = True, relu = True ) # 3x3 depthwise convolution followed by batch normalization self. ![]() # NOTE: Do not use group convolution for the first conv1x1 in Stage 2. combine )) # Use a 1x1 grouped or non-grouped convolution to reduce input channels # to bottleneck channels, as in a ResNet bottleneck module. in_channels else : raise ValueError ( "Cannot combine tensors with \" \" " \ _concat # ensure output of concat has the same channels as # original output channels. combine = 'concat' : # ShuffleUnit Figure 2c self. combine = 'add' : # ShuffleUnit Figure 2b self. out_channels // 4 # define the type of ShuffleUnit if self. Module ): def _init_ ( self, in_channels, out_channels, groups = 3, grouped_conv = True, combine = 'add' ): super ( ShuffleUnitOld, self ). view ( batchsize, - 1, height, width ) return x class ShuffleUnitOld ( nn. view ( batchsize, groups, channels_per_group, height, width ) # transpose # - contiguous() required if transpose() is used before view(). size () channels_per_group = num_channels // groups # reshape x = x. To visualize the layout, given a contiguous array x = torch.arange(12).From collections import OrderedDict def channel_shuffle ( x, groups ): batchsize, num_channels, height, width = x. With the k-th stride being the product of all dimensions that come after the k-th axis, e.g., y.stride(0) = y.size(1) * y.size(2), y.stride(1) = y.size(0), y.stride(2) = 1. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |