@@ -22,32 +22,32 @@ Creates a bottleneck block as described in the Res2Net paper.
22
22
"""
23
23
function bottle2neck (inplanes:: Integer , planes:: Integer ; stride:: Integer = 1 ,
24
24
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)
27
28
width = fld (planes * base_width, 64 ) * cardinality
28
29
outplanes = planes * 4
29
- is_first = stride > 1
30
30
pool = is_first && scale > 1 ? MeanPool ((3 , 3 ); stride, pad = 1 ) : identity
31
31
conv_bns = [Chain (conv_norm ((3 , 3 ), width => width, activation; norm_layer, stride,
32
32
pad = 1 , groups = cardinality, bias = false )... )
33
- for _ in 1 : ( max (1 , scale - 1 ) )]
33
+ for _ in 1 : max (1 , scale - 1 )]
34
34
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... ) ))
36
36
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) ... )
44
44
end
45
45
46
46
function bottle2neck_builder (block_repeats:: AbstractVector{<:Integer} ;
47
47
inplanes:: Integer = 64 , cardinality:: Integer = 1 ,
48
48
base_width:: Integer = 26 , scale:: Integer = 4 ,
49
49
expansion:: Integer = 4 , norm_layer = BatchNorm,
50
- revnorm:: Bool = false , activation = relu,
50
+ revnorm:: Bool = false , activation = relu,
51
51
attn_fn = planes -> identity,
52
52
stride_fn = resnet_stride, planes_fn = resnet_planes,
53
53
downsample_tuple = (downsample_conv, downsample_identity))
@@ -63,8 +63,9 @@ function bottle2neck_builder(block_repeats::AbstractVector{<:Integer};
63
63
stride = stride_fn (stage_idx, block_idx)
64
64
downsample_fn = (stride != 1 || inplanes != planes * expansion) ?
65
65
downsample_tuple[1 ] : downsample_tuple[2 ]
66
+ is_first = (stride > 1 || downsample_fn != downsample_tuple[2 ]) ? true : false
66
67
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)
68
69
downsample = downsample_fn (inplanes, planes * expansion; stride, norm_layer,
69
70
revnorm)
70
71
return block, downsample
@@ -92,19 +93,25 @@ Creates a Res2Net model with the specified depth, scale, and base width.
92
93
struct Res2Net
93
94
layers:: Any
94
95
end
96
+ @functor Res2Net
95
97
96
98
function Res2Net (depth:: Integer ; pretrain:: Bool = false , scale:: Integer = 4 ,
97
99
base_width:: Integer = 26 , inchannels:: Integer = 3 ,
98
100
nclasses:: Integer = 1000 )
99
101
_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,
101
103
inchannels, nclasses)
102
104
if pretrain
103
105
loadpretrain! (layers, string (" Res2Net" , depth, " _" , base_width, " x" , scale))
104
106
end
105
- return ResNet (layers)
107
+ return Res2Net (layers)
106
108
end
107
109
110
+ (m:: Res2Net )(x) = m. layers (x)
111
+
112
+ backbone (m:: Res2Net ) = m. layers[1 ]
113
+ classifier (m:: Res2Net ) = m. layers[2 ]
114
+
108
115
"""
109
116
Res2NeXt(depth::Integer; pretrain::Bool = false, scale::Integer = 4,
110
117
base_width::Integer = 4, cardinality::Integer = 8,
@@ -126,17 +133,23 @@ Creates a Res2NeXt model with the specified depth, scale, base width and cardina
126
133
struct Res2NeXt
127
134
layers:: Any
128
135
end
136
+ @functor Res2NeXt
129
137
130
138
function Res2NeXt (depth:: Integer ; pretrain:: Bool = false , scale:: Integer = 4 ,
131
139
base_width:: Integer = 4 , cardinality:: Integer = 8 ,
132
140
inchannels:: Integer = 3 , nclasses:: Integer = 1000 )
133
141
_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,
135
143
cardinality, inchannels, nclasses)
136
144
if pretrain
137
145
loadpretrain! (layers,
138
146
string (" Res2NeXt" , depth, " _" , base_width, " x" , cardinality,
139
147
" x" , scale))
140
148
end
141
- return ResNet (layers)
149
+ return Res2NeXt (layers)
142
150
end
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