@@ -22,32 +22,32 @@ Creates a bottleneck block as described in the Res2Net paper.
2222"""
2323function bottle2neck (inplanes:: Integer , planes:: Integer ; stride:: Integer = 1 ,
2424 cardinality:: Integer = 1 , base_width:: Integer = 26 ,
25- scale:: Integer = 4 , activation = relu, norm_layer = BatchNorm,
26- revnorm:: Bool = false , attn_fn = planes -> identity)
25+ scale:: Integer = 4 , activation = relu, is_first:: Bool = false ,
26+ norm_layer = BatchNorm, revnorm:: Bool = false ,
27+ attn_fn = planes -> identity)
2728 width = fld (planes * base_width, 64 ) * cardinality
2829 outplanes = planes * 4
29- is_first = stride > 1
3030 pool = is_first && scale > 1 ? MeanPool ((3 , 3 ); stride, pad = 1 ) : identity
3131 conv_bns = [Chain (conv_norm ((3 , 3 ), width => width, activation; norm_layer, stride,
3232 pad = 1 , groups = cardinality, bias = false )... )
33- for _ in 1 : ( max (1 , scale - 1 ) )]
33+ for _ in 1 : max (1 , scale - 1 )]
3434 reslayer = is_first ? Parallel (cat_channels, pool, conv_bns... ) :
35- Parallel (cat_channels, identity, PairwiseFusion (+ , conv_bns... ))
35+ Parallel (cat_channels, identity, Chain ( PairwiseFusion (+ , conv_bns... ) ))
3636 tuplify (x) = is_first ? tuple (x... ) : tuple (x[1 ], tuple (x[2 : end ]. .. ))
37- return Chain ( conv_norm ((1 , 1 ), inplanes => width * scale, activation;
38- norm_layer, revnorm, bias = false )... ,
39- chunk$ (; size = width, dims = 3 ),
40- tuplify, reslayer,
41- conv_norm (( 1 , 1 ), width * scale => outplanes, activation;
42- norm_layer, revnorm, bias = false ) ... ,
43- attn_fn (outplanes) )
37+ layers = [ conv_norm ((1 , 1 ), inplanes => width * scale, activation;
38+ norm_layer, revnorm, bias = false )... ,
39+ chunk$ (; size = width, dims = 3 ), tuplify, reslayer ,
40+ conv_norm (( 1 , 1 ), width * scale => outplanes, activation;
41+ norm_layer, revnorm, bias = false ) ... ,
42+ attn_fn (outplanes)]
43+ return Chain ( filter ( != (identity), layers) ... )
4444end
4545
4646function bottle2neck_builder (block_repeats:: AbstractVector{<:Integer} ;
4747 inplanes:: Integer = 64 , cardinality:: Integer = 1 ,
4848 base_width:: Integer = 26 , scale:: Integer = 4 ,
4949 expansion:: Integer = 4 , norm_layer = BatchNorm,
50- revnorm:: Bool = false , activation = relu,
50+ revnorm:: Bool = false , activation = relu,
5151 attn_fn = planes -> identity,
5252 stride_fn = resnet_stride, planes_fn = resnet_planes,
5353 downsample_tuple = (downsample_conv, downsample_identity))
@@ -63,8 +63,9 @@ function bottle2neck_builder(block_repeats::AbstractVector{<:Integer};
6363 stride = stride_fn (stage_idx, block_idx)
6464 downsample_fn = (stride != 1 || inplanes != planes * expansion) ?
6565 downsample_tuple[1 ] : downsample_tuple[2 ]
66+ is_first = (stride > 1 || downsample_fn != downsample_tuple[2 ]) ? true : false
6667 block = bottle2neck (inplanes, planes; stride, cardinality, base_width, scale,
67- activation, norm_layer, revnorm, attn_fn)
68+ activation, is_first, norm_layer, revnorm, attn_fn)
6869 downsample = downsample_fn (inplanes, planes * expansion; stride, norm_layer,
6970 revnorm)
7071 return block, downsample
@@ -92,19 +93,25 @@ Creates a Res2Net model with the specified depth, scale, and base width.
9293struct Res2Net
9394 layers:: Any
9495end
96+ @functor Res2Net
9597
9698function Res2Net (depth:: Integer ; pretrain:: Bool = false , scale:: Integer = 4 ,
9799 base_width:: Integer = 26 , inchannels:: Integer = 3 ,
98100 nclasses:: Integer = 1000 )
99101 _checkconfig (depth, sort (collect (keys (RESNET_CONFIGS)))[3 : end ])
100- layers = resnet (:bottle2neck , RESNET_CONFIGS[depth][2 ], :C ; base_width, scale,
102+ layers = resnet (:bottle2neck , RESNET_CONFIGS[depth][2 ]; base_width, scale,
101103 inchannels, nclasses)
102104 if pretrain
103105 loadpretrain! (layers, string (" Res2Net" , depth, " _" , base_width, " x" , scale))
104106 end
105- return ResNet (layers)
107+ return Res2Net (layers)
106108end
107109
110+ (m:: Res2Net )(x) = m. layers (x)
111+
112+ backbone (m:: Res2Net ) = m. layers[1 ]
113+ classifier (m:: Res2Net ) = m. layers[2 ]
114+
108115"""
109116 Res2NeXt(depth::Integer; pretrain::Bool = false, scale::Integer = 4,
110117 base_width::Integer = 4, cardinality::Integer = 8,
@@ -126,17 +133,23 @@ Creates a Res2NeXt model with the specified depth, scale, base width and cardina
126133struct Res2NeXt
127134 layers:: Any
128135end
136+ @functor Res2NeXt
129137
130138function Res2NeXt (depth:: Integer ; pretrain:: Bool = false , scale:: Integer = 4 ,
131139 base_width:: Integer = 4 , cardinality:: Integer = 8 ,
132140 inchannels:: Integer = 3 , nclasses:: Integer = 1000 )
133141 _checkconfig (depth, sort (collect (keys (RESNET_CONFIGS)))[3 : end ])
134- layers = resnet (:bottle2neck , RESNET_CONFIGS[depth][2 ], :C ; base_width, scale,
142+ layers = resnet (:bottle2neck , RESNET_CONFIGS[depth][2 ]; base_width, scale,
135143 cardinality, inchannels, nclasses)
136144 if pretrain
137145 loadpretrain! (layers,
138146 string (" Res2NeXt" , depth, " _" , base_width, " x" , cardinality,
139147 " x" , scale))
140148 end
141- return ResNet (layers)
149+ return Res2NeXt (layers)
142150end
151+
152+ (m:: Res2NeXt )(x) = m. layers (x)
153+
154+ backbone (m:: Res2NeXt ) = m. layers[1 ]
155+ classifier (m:: Res2NeXt ) = m. layers[2 ]
0 commit comments