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) """ x = layers.conv(img_input, filters_out=64, kernel_size=7, stride=2, add_bias=False, name='conv1_conv') x = layers.norm(x, axis=-1, epsilon=1.001e-5, name='conv1_bn') x = layers.relu(x, name='conv1_relu') x = layers.zero_padding(x, padding=((1, 1), (1, 1)), name='pool1_pad') x = layers.max_pool(x, kernel_size=3, name='pool1') x = self.conv_block(x, 3, [64, 64, 256], stage=2, block='1', strides=1) x = self.identity_block(x, 3, [64, 64, 256], stage=2, block='2') x = self.identity_block(x, 3, [64, 64, 256], stage=2, block='3') x = self.conv_block(x, 3, [128, 128, 512], stage=3, block='1') x = self.identity_block(x, 3, [128, 128, 512], stage=3, block='2') x = self.identity_block(x, 3, [128, 128, 512], stage=3, block='3') x = self.identity_block(x, 3, [128, 128, 512], stage=3, block='4') x = self.conv_block(x, 3, [256, 256, 1024], stage=4, block='1') x = self.identity_block(x, 3, [256, 256, 1024], stage=4, block='2') x = self.identity_block(x, 3, [256, 256, 1024], stage=4, block='3') x = self.identity_block(x, 3, [256, 256, 1024], stage=4, block='4') x = self.identity_block(x, 3, [256, 256, 1024], stage=4, block='5') x = self.identity_block(x, 3, [256, 256, 1024], stage=4, block='6') x = self.conv_block(x, 3, [512, 512, 2048], stage=5, block='1') x = self.identity_block(x, 3, [512, 512, 2048], stage=5, block='2') x = self.identity_block(x, 3, [512, 512, 2048], stage=5, block='3') x = layers.avg_pool(x, kernel_size=7, strides=1, name='avg_pool') x = layers.squeeze(x, axis=[1, 2], name='squeeze') x = layers.fully_connected(x, self.num_classes, name='probs') x = layers.softmax(x, name='output-prob') 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 = _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) """ x = layers.conv(img_input, filters_out=32, kernel_size=3, stride=2, add_bias=False, name='block1_conv1') x = layers.norm(x, name='block1_conv1_bn') x = layers.relu(x, name='block1_conv1_act') x = layers.conv(x, filters_out=64, kernel_size=3, add_bias=False, name='block1_conv2') x = layers.norm(x, name='block1_conv2_bn') x = layers.relu(x, name='block1_conv2_act') residual = layers.conv(x, filters_out=128, kernel_size=1, stride=2, padding='same', add_bias=False) residual = layers.norm(residual, name="batch_normalization") x = layers.separable_conv(x, filters_out=128, kernel_size=3, padding='same', add_bias=False, name='block2_sepconv1') x = layers.norm(x, name='block2_sepconv1_bn') x = layers.relu(x, name='block2_sepconv2_act') x = layers.separable_conv(x, filters_out=128, kernel_size=3, padding='same', add_bias=False, name='block2_sepconv2') x = layers.norm(x, name='block2_sepconv2_bn') x = layers.max_pool(x, 3, strides=2, padding='same', name='block2_pool') x += residual residual = layers.conv(x, filters_out=256, kernel_size=1, stride=2, padding='same', add_bias=False) residual = layers.norm(residual, name="batch_normalization") x = layers.relu(x, name='block3_sepconv1_act') x = layers.separable_conv(x, filters_out=256, kernel_size=3, padding='same', add_bias=False, name='block3_sepconv1') x = layers.norm(x, name='block3_sepconv1_bn') x = layers.relu(x, name='block3_sepconv2_act') x = layers.separable_conv(x, filters_out=256, kernel_size=3, padding='same', add_bias=False, name='block3_sepconv2') x = layers.norm(x, name='block3_sepconv2_bn') x = layers.max_pool(x, 3, strides=2, padding='same', name='block3_pool') x += residual residual = layers.conv(x, filters_out=728, kernel_size=1, stride=2, padding='same', add_bias=False) residual = layers.norm(residual, name="batch_normalization") x = layers.relu(x, name='block4_sepconv1_act') x = layers.separable_conv(x, filters_out=728, kernel_size=3, padding='same', add_bias=False, name='block4_sepconv1') x = layers.norm(x, name='block4_sepconv1_bn') x = layers.relu(x, name='block4_sepconv2_act') x = layers.separable_conv(x, filters_out=728, kernel_size=3, padding='same', add_bias=False, name='block4_sepconv2') x = layers.norm(x, name='block4_sepconv2_bn') x = layers.max_pool(x, 3, strides=2, padding='same', name='block4_pool') x += residual for i in range(8): residual = x prefix = 'block' + str(i + 5) x = layers.relu(x, name=prefix + '_sepconv1_act') x = layers.separable_conv(x, filters_out=728, kernel_size=3, padding='same', add_bias=False, name=prefix + '_sepconv1') x = layers.norm(x, name=prefix + '_sepconv1_bn') x = layers.relu(x, name=prefix + '_sepconv2_act') x = layers.separable_conv(x, filters_out=728, kernel_size=3, padding='same', add_bias=False, name=prefix + '_sepconv2') x = layers.norm(x, name=prefix + '_sepconv2_bn') x = layers.relu(x, name=prefix + '_sepconv3_act') x = layers.separable_conv(x, filters_out=728, kernel_size=3, padding='same', add_bias=False, name=prefix + '_sepconv3') x = layers.norm(x, name=prefix + '_sepconv3_bn') x += residual residual = layers.conv(x, filters_out=1024, kernel_size=1, stride=2, padding='same', add_bias=False) residual = layers.norm(residual, name="batch_normalization") x = layers.relu(x, name='block13_sepconv1_act') x = layers.separable_conv(x, filters_out=728, kernel_size=3, padding='same', add_bias=False, name='block13_sepconv1') x = layers.norm(x, name='block13_sepconv1_bn') x = layers.relu(x, name='block13_sepconv2_act') x = layers.separable_conv(x, filters_out=1024, kernel_size=3, padding='same', add_bias=False, name='block13_sepconv2') x = layers.norm(x, name='block13_sepconv2_bn') x = layers.max_pool(x, 3, strides=2, padding='same', name='block13_pool') x += residual x = layers.separable_conv(x, filters_out=1536, kernel_size=3, padding='same', add_bias=False, name='block14_sepconv1') x = layers.norm(x, name='block14_sepconv1_bn') x = layers.relu(x, name='block14_sepconv1_act') x = layers.separable_conv(x, filters_out=2048, kernel_size=3, padding='same', add_bias=False, name='block14_sepconv2') x = layers.norm(x, name='block14_sepconv2_bn') x = layers.relu(x, name='block14_sepconv2_act') # Classification block x = layers.avg_pool(x, kernel_size=10, strides=1, name='avg_pool') x = layers.squeeze(x, axis=[1, 2], name='squeeze') x = layers.fully_connected(x, self.num_classes, name='predictions') x = layers.softmax(x, name='output-prob') 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) """ x = conv_norm_relu(img_input, 32, 3, strides=2, padding='VALID') x = conv_norm_relu(x, 32, 3, padding='VALID') x = conv_norm_relu( x, 64, 3, ) x = max_pool(x, 3, strides=2) x = conv_norm_relu(x, 80, 1, padding='VALID') x = conv_norm_relu(x, 192, 3, padding='VALID') x = max_pool(x, 3, strides=2) # mixed 0: 35 x 35 x 256 branch1x1 = conv_norm_relu(x, 64, 1) branch5x5 = conv_norm_relu(x, 48, 1) branch5x5 = conv_norm_relu(branch5x5, 64, 5) branch3x3dbl = conv_norm_relu(x, 64, 1) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 32, 1) x = concat([branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=-1, name='mixed0') # mixed 1: 35 x 35 x 288 branch1x1 = conv_norm_relu(x, 64, 1) branch5x5 = conv_norm_relu(x, 48, 1) branch5x5 = conv_norm_relu(branch5x5, 64, 5) branch3x3dbl = conv_norm_relu(x, 64, 1) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 64, 1) x = concat([branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=-1, name='mixed1') # mixed 2: 35 x 35 x 288 branch1x1 = conv_norm_relu(x, 64, 1) branch5x5 = conv_norm_relu(x, 48, 1) branch5x5 = conv_norm_relu(branch5x5, 64, 5) branch3x3dbl = conv_norm_relu(x, 64, 1) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 64, 1) x = concat([branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=-1, name='mixed2') # mixed 3: 17 x 17 x 768 branch3x3 = conv_norm_relu(x, 384, 3, strides=2, padding='VALID') branch3x3dbl = conv_norm_relu(x, 64, 1) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3) branch3x3dbl = conv_norm_relu(branch3x3dbl, 96, 3, strides=2, padding='VALID') branch_pool = max_pool(x, 3, 2) x = concat([branch3x3, branch3x3dbl, branch_pool], axis=-1, name='mixed3') # mixed 4: 17 x 17 x 768 branch1x1 = conv_norm_relu(x, 192, 1) branch7x7 = conv_norm_relu(x, 128, 1) branch7x7 = conv_norm_relu(branch7x7, 128, 1, 7) branch7x7 = conv_norm_relu(branch7x7, 192, 7, 1) branch7x7dbl = conv_norm_relu(x, 128, 1, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 128, 7, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 128, 1, 7) branch7x7dbl = conv_norm_relu(branch7x7dbl, 128, 7, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 192, 1, 7) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 192, 1, 1) x = concat([branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=-1, name='mixed4') # mixed 5, 6: 17 x 17 x 768 for i in range(2): branch1x1 = conv_norm_relu(x, 192, 1, 1) branch7x7 = conv_norm_relu(x, 160, 1, 1) branch7x7 = conv_norm_relu(branch7x7, 160, 1, 7) branch7x7 = conv_norm_relu(branch7x7, 192, 7, 1) branch7x7dbl = conv_norm_relu(x, 160, 1, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 160, 7, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 160, 1, 7) branch7x7dbl = conv_norm_relu(branch7x7dbl, 160, 7, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 192, 1, 7) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 192, 1, 1) x = concat([branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=-1, name='mixed' + str(5 + i)) # mixed 7: 17 x 17 x 768 branch1x1 = conv_norm_relu(x, 192, 1, 1) branch7x7 = conv_norm_relu(x, 192, 1, 1) branch7x7 = conv_norm_relu(branch7x7, 192, 1, 7) branch7x7 = conv_norm_relu(branch7x7, 192, 7, 1) branch7x7dbl = conv_norm_relu(x, 192, 1, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 192, 7, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 192, 1, 7) branch7x7dbl = conv_norm_relu(branch7x7dbl, 192, 7, 1) branch7x7dbl = conv_norm_relu(branch7x7dbl, 192, 1, 7) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 192, 1, 1) x = concat([branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=-1, name='mixed7') # mixed 8: 8 x 8 x 1280 branch3x3 = conv_norm_relu(x, 192, 1) branch3x3 = conv_norm_relu(branch3x3, 320, 3, strides=2, padding='VALID') branch7x7x3 = conv_norm_relu(x, 192, 1, 1) branch7x7x3 = conv_norm_relu(branch7x7x3, 192, 1, 7) branch7x7x3 = conv_norm_relu(branch7x7x3, 192, 7, 1) branch7x7x3 = conv_norm_relu(branch7x7x3, 192, 3, 3, strides=2, padding='VALID') branch_pool = max_pool(x, 3, strides=2) x = concat([branch3x3, branch7x7x3, branch_pool], axis=-1, name='mixed8') # mixed 9: 8 x 8 x 2048 for i in range(2): branch1x1 = conv_norm_relu(x, 320, 1, 1) branch3x3 = conv_norm_relu(x, 384, 1, 1) branch3x3_1 = conv_norm_relu(branch3x3, 384, 1, 3) branch3x3_2 = conv_norm_relu(branch3x3, 384, 3, 1) branch3x3 = concat([branch3x3_1, branch3x3_2], axis=-1, name='mixed9_' + str(i)) branch3x3dbl = conv_norm_relu(x, 448, 1, 1) branch3x3dbl = conv_norm_relu(branch3x3dbl, 384, 3, 3) branch3x3dbl_1 = conv_norm_relu(branch3x3dbl, 384, 1, 3) branch3x3dbl_2 = conv_norm_relu(branch3x3dbl, 384, 3, 1) branch3x3dbl = concat([branch3x3dbl_1, branch3x3dbl_2], axis=-1) branch_pool = avg_pool(x, 3, strides=1, padding='SAME') branch_pool = conv_norm_relu(branch_pool, 192, 1, 1) x = concat([branch1x1, branch3x3, branch3x3dbl, branch_pool], axis=-1, name='mixed' + str(9 + i)) # Classification block x = avg_pool(x, kernel_size=8, strides=1, name='avg_pool') x = squeeze(x, axis=[1, 2], name='squeeze') x = fully_connected(x, self.num_classes, name='predictions') x = softmax(x, name='output-prob') 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 = self.penultimate_filters // 24 x = layers.conv(img_input, filters_out=self.stem_block_filters, kernel_size=3, stride=2, padding='valid', add_bias=False, name='stem_conv1') x = layers.norm(x, axis=-1, momentum=0.9997, epsilon=1e-3, name='stem_bn1') p = None x, p = self.reduction_a_cell(x, p, filters // (self.filter_multiplier**2), block_id='stem_1') x, p = self.reduction_a_cell(x, p, filters // self.filter_multiplier, block_id='stem_2') for i in range(self.num_blocks): x, p = self.normal_a_cell(x, p, filters, block_id='%d' % i) x, p0 = self.reduction_a_cell(x, p, filters * self.filter_multiplier, block_id='reduce_%d' % self.num_blocks) p = p0 if not self.skip_reduction else p for i in range(self.num_blocks): x, p = self.normal_a_cell(x, p, filters * self.filter_multiplier, block_id='%d' % (self.num_blocks + i + 1)) x, p0 = self.reduction_a_cell(x, p, filters * self.filter_multiplier**2, block_id='reduce_%d' % (2 * self.num_blocks)) p = p0 if not self.skip_reduction else p for i in range(self.num_blocks): x, p = self.normal_a_cell(x, p, filters * self.filter_multiplier**2, block_id='%d' % (2 * self.num_blocks + i + 1)) x = layers.relu(x, 'relu') # Classification block x = layers.avg_pool(x, kernel_size=7, strides=1, name='avg_pool') x = layers.squeeze(x, axis=[1, 2], name='squeeze') x = layers.fully_connected(x, self.num_classes, name='predictions') x = layers.softmax(x, name='output-prob') return x