def build_model(self, img_input: TensorType) -> TensorType: """Build graph using img_input as input. Args: img_input: 4D Image input tensor of shape (batch, height, width, channels) Returns: `Tensor` holding output probabilities per class, shape (batch, num_classes) """ filters = _make_divisible(32 * self.alpha, 8) # Conv 1 block x = layers.zero_padding(img_input, padding=((0, 1), (0, 1)), name='Conv1_pad') x = layers.conv(x, filters_out=filters, kernel_size=3, padding='valid', add_bias=False, stride=2, name='Conv1') x = layers.norm(x, axis=-1, epsilon=1e-3, momentum=0.999, name='bn_Conv1') x = layers.relu(x, name='Conv1_relu', max_value=tf.constant(6, tf.float16)) # Depthwise separable convolutions x = self._inverted_res_block(x, filters=16, alpha=self.alpha, stride=1, expansion=1, block_id=0) x = self._inverted_res_block(x, filters=24, alpha=self.alpha, stride=2, expansion=6, block_id=1) x = self._inverted_res_block(x, filters=24, alpha=self.alpha, stride=1, expansion=6, block_id=2) x = self._inverted_res_block(x, filters=32, alpha=self.alpha, stride=2, expansion=6, block_id=3) x = self._inverted_res_block(x, filters=32, alpha=self.alpha, stride=1, expansion=6, block_id=4) x = self._inverted_res_block(x, filters=32, alpha=self.alpha, stride=1, expansion=6, block_id=5) x = self._inverted_res_block(x, filters=64, alpha=self.alpha, stride=2, expansion=6, block_id=6) x = self._inverted_res_block(x, filters=64, alpha=self.alpha, stride=1, expansion=6, block_id=7) x = self._inverted_res_block(x, filters=64, alpha=self.alpha, stride=1, expansion=6, block_id=8) x = self._inverted_res_block(x, filters=64, alpha=self.alpha, stride=1, expansion=6, block_id=9) x = self._inverted_res_block(x, filters=96, alpha=self.alpha, stride=1, expansion=6, block_id=10) x = self._inverted_res_block(x, filters=96, alpha=self.alpha, stride=1, expansion=6, block_id=11) x = self._inverted_res_block(x, filters=96, alpha=self.alpha, stride=1, expansion=6, block_id=12) x = self._inverted_res_block(x, filters=160, alpha=self.alpha, stride=2, expansion=6, block_id=13) x = self._inverted_res_block(x, filters=160, alpha=self.alpha, stride=1, expansion=6, block_id=14) x = self._inverted_res_block(x, filters=160, alpha=self.alpha, stride=1, expansion=6, block_id=15) x = self._inverted_res_block(x, filters=320, alpha=self.alpha, stride=1, expansion=6, block_id=16) # no alpha applied to last conv as stated in the paper: # if the width multiplier is greater than 1 we # increase the number of output channels if self.alpha > 1.0: last_block_filters = _make_divisible(1280 * self.alpha, 8) else: last_block_filters = 1280 x = layers.conv(x, filters_out=last_block_filters, kernel_size=1, add_bias=False, name='Conv_1') x = layers.norm(x, epsilon=1e-3, momentum=0.999, name='Conv_1_bn') x = layers.relu(x, max_value=tf.constant(6, tf.float16), name='out_relu') # Include top x = layers.global_avg_pool(x) x = layers.fully_connected(x, self.num_classes, name='Logits') x = layers.softmax(x, name='act_softmax') return x
def build_model(self, img_input: TensorType) -> TensorType: """Build graph using img_input as input. Args: img_input: 4D Image input tensor of shape (batch, height, width, channels) Returns: `Tensor` holding output probabilities per class, shape (batch, num_classes) """ filters = int(32 * self.alpha) shape = (-1, 1, 1, int(1024 * self.alpha)) # Conv 1 block x = layers.zero_padding(img_input, padding=((0, 1), (0, 1)), name='conv1_pad') x = layers.conv(x, filters_out=filters, kernel_size=3, padding='valid', add_bias=False, stride=2, name='conv1') x = layers.norm(x, axis=-1, name='conv1_bn') x = layers.relu(x, name='conv1_relu') # Depthwise convolutions x = self._depthwise_conv_block(x, 64, self.alpha, depth_multiplier=1, block_id=1) x = self._depthwise_conv_block(x, 128, self.alpha, depth_multiplier=1, strides=2, block_id=2) x = self._depthwise_conv_block(x, 128, self.alpha, depth_multiplier=1, block_id=3) x = self._depthwise_conv_block(x, 256, self.alpha, depth_multiplier=1, strides=2, block_id=4) x = self._depthwise_conv_block(x, 256, self.alpha, depth_multiplier=1, block_id=5) x = self._depthwise_conv_block(x, 512, self.alpha, depth_multiplier=1, strides=2, block_id=6) x = self._depthwise_conv_block(x, 512, self.alpha, depth_multiplier=1, block_id=7) x = self._depthwise_conv_block(x, 512, self.alpha, depth_multiplier=1, block_id=8) x = self._depthwise_conv_block(x, 512, self.alpha, depth_multiplier=1, block_id=9) x = self._depthwise_conv_block(x, 512, self.alpha, depth_multiplier=1, block_id=10) x = self._depthwise_conv_block(x, 512, self.alpha, depth_multiplier=1, block_id=11) x = self._depthwise_conv_block(x, 1024, self.alpha, depth_multiplier=1, strides=2, block_id=12) x = self._depthwise_conv_block(x, 1024, self.alpha, depth_multiplier=1, block_id=13) # Include top x = layers.global_avg_pool(x) x = layers.reshape(x, shape=shape, name='reshape_1') x = layers.conv(x, filters_out=self.num_classes, kernel_size=1, padding='same', name='conv_preds', add_bias=False) x = layers.reshape(x, shape=(-1, self.num_classes), name='reshape_2') x = layers.softmax(x, name='act_softmax') return x