def __call__(self, x,scope=None): with tf.variable_scope(scope,default_name="Bottleneck"): residual = x out = slim.conv2d(x,self.num_outputs,1,1,activation_fn=self.activation_fn, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params) out = slim.conv2d(out,self.num_outputs,3,self.stride,activation_fn=self.activation_fn, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params) out = slim.conv2d(out,self.num_outputs*self.expansion,1,1, activation_fn=None, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params) if self.downsample is not None: residual = self.downsample(x) if get_channel(residual) != get_channel(out): residual = slim.conv2d(residual,self.num_outputs*self.expansion,1,1, activation_fn=None, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params) out += residual if self.activation_fn is not None: out = self.activation_fn(out) return out
def downsample(self,x,expansion,stride,scope=None): with tf.variable_scope(scope,default_name="downsample"): num_outputs = get_channel(x)*expansion out = slim.conv2d(x, num_outputs, 3, stride, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params) return out
def fuse_layer(self, xs): with tf.variable_scope("Fuse"): ys = [] for i,v0 in enumerate(xs): chl = get_channel(xs[i]) shape0 = wmlt.combined_static_and_dynamic_shape(v0)[1:3] datas = [] for j, v1 in enumerate(xs): if i != j: if i<j: #upsample v1 = tf.image.resize_nearest_neighbor(v1, shape0,name="upsample") v1 = slim.conv2d(v1, chl, [1, 1], activation_fn=None, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params, scope=f"smooth{i}_{j}") elif i>j: v1 = self.downsamplev2(v1,chl,i-j) datas.append(v1) if len(datas)>1: v = tf.add_n(datas) / len(datas) if self.activation_fn is not None: v = self.activation_fn(v) else: v = datas[0] ys.append(v) return ys
def forward(self, x): cfg = self.cfg # fmt: off num_classes = cfg.MODEL.ROI_HEADS.NUM_CLASSES conv_dims = cfg.MODEL.ROI_MASK_HEAD.CONV_DIM num_conv = cfg.MODEL.ROI_MASK_HEAD.NUM_CONV cls_agnostic_mask = cfg.MODEL.ROI_MASK_HEAD.CLS_AGNOSTIC_MASK # fmt: on num_mask_classes = 1 if cls_agnostic_mask else num_classes x_channel = get_channel(x) assert x_channel > conv_dims, "error conv dims for mask." with tf.variable_scope("MaskHead"): x_identity, x = tf.split( x, num_or_size_splits=[x_channel - conv_dims, conv_dims], axis=-1) x_iden_channel = get_channel(x_identity) if 'G' in self.norm_params and self.norm_params['G'] > get_channel( x): self.norm_params['G'] = get_channel(x) for k in range(num_conv): x = slim.conv2d(x, conv_dims, [3, 3], padding="SAME", activation_fn=self.activation_fn, normalizer_fn=self.normalizer_fn, normalizer_params=self.norm_params, scope=f"Conv{k}") x = slim.conv2d_transpose(x, x_iden_channel, kernel_size=2, stride=2, activation_fn=self.activation_fn, normalizer_fn=self.normalizer_fn, normalizer_params=self.norm_params, scope="Upsample") B, H, W, C = btf.combined_static_and_dynamic_shape(x) x_identity = tf.image.resize_bilinear(x_identity, size=(H, W)) x = x_identity + x x = slim.conv2d(x, num_mask_classes, kernel_size=1, activation_fn=None, normalizer_fn=None, scope="predictor") return x
def downsamplev2(self,x,outchannel,order,scope=None): with tf.variable_scope(scope,default_name="downsample"): out = x for i in range(order): num_outputs = get_channel(x) if i != order-1 else outchannel activation_fn = self.activation_fn if i !=order-1 else None out = slim.conv2d(out, num_outputs, 3, 2, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params, activation_fn=activation_fn, scope=f"downsample_conv_{i}") return out
def _make_transition_layer(self,xs, num_channels_pre_layer, num_channels_cur_layer,scope=None): num_branches_cur = len(num_channels_cur_layer) num_branches_pre = len(num_channels_pre_layer) ys = [] with tf.variable_scope(scope,default_name="transition_layer"): out_shapes = [] for i in range(num_branches_cur): if i < num_branches_pre: out_shapes.append(wmlt.combined_static_and_dynamic_shape(xs[i])[1:3]) else: last_shape = out_shapes[-1] h = last_shape[0]//2 w = last_shape[1]//2 out_shapes.append([h,w]) with tf.variable_scope("Fuse"): for i in range(num_branches_cur): chl = num_channels_cur_layer[i] shape0 = out_shapes[i] datas = [] for j, v1 in enumerate(xs): if i != j: if i<j: #upsample v1 = tf.image.resize_nearest_neighbor(v1, shape0,name="upsample") v1 = slim.conv2d(v1, chl, [1, 1], activation_fn=None, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params, scope=f"smooth{i}_{j}") elif i>j: v1 = self.downsamplev2(v1,chl,i-j) elif chl != get_channel(v1): v1 = slim.conv2d(v1, chl, [3, 3], activation_fn=None, normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params, scope=f"project_{i}_{j}") datas.append(v1) if len(datas)>1: v = tf.add_n(datas) / len(datas) if self.activation_fn is not None: v = self.activation_fn(v) else: v = datas[0] ys.append(v) return ys
def _make_layer(self, x,block, planes, blocks, stride=1,scope=None): with tf.variable_scope(scope,default_name="layer"): downsample = None inplanes = get_channel(x) if stride != 1: downsample = partial(self.downsample,expansion=block.expansion,stride=stride) x = block(planes, stride, downsample,normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params, activation_fn=self.activation_fn)(x,scope="block0") for i in range(1, blocks): x = block(planes,normalizer_fn=self.normalizer_fn, normalizer_params=self.normalizer_params, activation_fn=self.activation_fn)(x,scope=f"block{i}") return x