Beispiel #1
0
def ModelForCustomLayerTest():
    input_shape = (None, None, 3)
    img_input = layers.Input(shape=input_shape)  # non-custom
    channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1
    x = img_input
    x = layers.Rescaling(scale=1. / 127.5,
                         offset=-1.)(x)  # non-custom, but experimental
    x = layers.Conv2D(16,
                      kernel_size=3,
                      strides=(2, 2),
                      padding='same',
                      use_bias=False,
                      name='Conv')(x)  # non-custom
    x = CustomLayerForTest()(x)  # custom!
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv/BatchNorm')(x)  # non-custom
    x = tf.multiply(x, x)  # TensorFlowOpLayer, should be treated as non-custom

    model = models.Model(img_input, x, name='ModelForCustomLayerTest')
    return model
Beispiel #2
0
def EfficientNet(width_coefficient,
                 depth_coefficient,
                 default_size,
                 dropout_rate=0.2,
                 drop_connect_rate=0.2,
                 depth_divisor=8,
                 activation='swish',
                 blocks_args='default',
                 model_name='efficientnet',
                 include_top=True,
                 weights='imagenet',
                 input_tensor=None,
                 input_shape=None,
                 pooling=None,
                 classes=1000):
  """Instantiates the EfficientNet architecture using given scaling coefficients.

  Optionally loads weights pre-trained on ImageNet.
  Note that the data format convention used by the model is
  the one specified in your Keras config at `~/.keras/keras.json`.

  Arguments:
    width_coefficient: float, scaling coefficient for network width.
    depth_coefficient: float, scaling coefficient for network depth.
    default_size: integer, default input image size.
    dropout_rate: float, dropout rate before final classifier layer.
    drop_connect_rate: float, dropout rate at skip connections.
    depth_divisor: integer, a unit of network width.
    activation: activation function.
    blocks_args: list of dicts, parameters to construct block modules.
    model_name: string, model name.
    include_top: whether to include the fully-connected
        layer at the top of the network.
    weights: one of `None` (random initialization),
          'imagenet' (pre-training on ImageNet),
          or the path to the weights file to be loaded.
    input_tensor: optional Keras tensor
        (i.e. output of `layers.Input()`)
        to use as image input for the model.
    input_shape: optional shape tuple, only to be specified
        if `include_top` is False.
        It should have exactly 3 inputs channels.
    pooling: optional pooling mode for feature extraction
        when `include_top` is `False`.
        - `None` means that the output of the model will be
            the 4D tensor output of the
            last convolutional layer.
        - `avg` means that global average pooling
            will be applied to the output of the
            last convolutional layer, and thus
            the output of the model will be a 2D tensor.
        - `max` means that global max pooling will
            be applied.
    classes: optional number of classes to classify images
        into, only to be specified if `include_top` is True, and
        if no `weights` argument is specified.

  Returns:
    A Keras model instance.

  Raises:
    ValueError: in case of invalid argument for `weights`,
      or invalid input shape.
  """
  if blocks_args == 'default':
    blocks_args = DEFAULT_BLOCKS_ARGS

  if not (weights in {'imagenet', None} or os.path.exists(weights)):
    raise ValueError('The `weights` argument should be either '
                     '`None` (random initialization), `imagenet` '
                     '(pre-training on ImageNet), '
                     'or the path to the weights file to be loaded.')

  if weights == 'imagenet' and include_top and classes != 1000:
    raise ValueError('If using `weights` as `"imagenet"` with `include_top`'
                     ' as true, `classes` should be 1000')

  # Determine proper input shape
  input_shape = imagenet_utils.obtain_input_shape(
      input_shape,
      default_size=default_size,
      min_size=32,
      data_format=backend.image_data_format(),
      require_flatten=include_top,
      weights=weights)

  if input_tensor is None:
    img_input = layers.Input(shape=input_shape)
  else:
    if not backend.is_keras_tensor(input_tensor):
      img_input = layers.Input(tensor=input_tensor, shape=input_shape)
    else:
      img_input = input_tensor

  bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1

  def round_filters(filters, divisor=depth_divisor):
    """Round number of filters based on depth multiplier."""
    filters *= width_coefficient
    new_filters = max(divisor, int(filters + divisor / 2) // divisor * divisor)
    # Make sure that round down does not go down by more than 10%.
    if new_filters < 0.9 * filters:
      new_filters += divisor
    return int(new_filters)

  def round_repeats(repeats):
    """Round number of repeats based on depth multiplier."""
    return int(math.ceil(depth_coefficient * repeats))

  # Build stem
  x = img_input
  x = layers.Rescaling(1. / 255.)(x)
  x = layers.Normalization(axis=bn_axis)(x)

  x = layers.ZeroPadding2D(
      padding=imagenet_utils.correct_pad(x, 3),
      name='stem_conv_pad')(x)
  x = layers.Conv2D(
      round_filters(32),
      3,
      strides=2,
      padding='valid',
      use_bias=False,
      kernel_initializer=CONV_KERNEL_INITIALIZER,
      name='stem_conv')(x)
  x = layers.BatchNormalization(axis=bn_axis, name='stem_bn')(x)
  x = layers.Activation(activation, name='stem_activation')(x)

  # Build blocks
  blocks_args = copy.deepcopy(blocks_args)

  b = 0
  blocks = float(sum(args['repeats'] for args in blocks_args))
  for (i, args) in enumerate(blocks_args):
    assert args['repeats'] > 0
    # Update block input and output filters based on depth multiplier.
    args['filters_in'] = round_filters(args['filters_in'])
    args['filters_out'] = round_filters(args['filters_out'])

    for j in range(round_repeats(args.pop('repeats'))):
      # The first block needs to take care of stride and filter size increase.
      if j > 0:
        args['strides'] = 1
        args['filters_in'] = args['filters_out']
      x = block(
          x,
          activation,
          drop_connect_rate * b / blocks,
          name='block{}{}_'.format(i + 1, chr(j + 97)),
          **args)
      b += 1

  # Build top
  x = layers.Conv2D(
      round_filters(1280),
      1,
      padding='same',
      use_bias=False,
      kernel_initializer=CONV_KERNEL_INITIALIZER,
      name='top_conv')(x)
  x = layers.BatchNormalization(axis=bn_axis, name='top_bn')(x)
  x = layers.Activation(activation, name='top_activation')(x)
  if include_top:
    x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
    if dropout_rate > 0:
      x = layers.Dropout(dropout_rate, name='top_dropout')(x)
    x = layers.Dense(
        classes,
        activation='softmax',
        kernel_initializer=DENSE_KERNEL_INITIALIZER,
        name='probs')(x)
  else:
    if pooling == 'avg':
      x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
    elif pooling == 'max':
      x = layers.GlobalMaxPooling2D(name='max_pool')(x)

  # Ensure that the model takes into account
  # any potential predecessors of `input_tensor`.
  if input_tensor is not None:
    inputs = layer_utils.get_source_inputs(input_tensor)
  else:
    inputs = img_input

  # Create model.
  model = training.Model(inputs, x, name=model_name)

  # Load weights.
  if weights == 'imagenet':
    if include_top:
      file_suffix = '.h5'
      file_hash = WEIGHTS_HASHES[model_name[-2:]][0]
    else:
      file_suffix = '_notop.h5'
      file_hash = WEIGHTS_HASHES[model_name[-2:]][1]
    file_name = model_name + file_suffix
    weights_path = data_utils.get_file(
        file_name,
        BASE_WEIGHTS_PATH + file_name,
        cache_subdir='models',
        file_hash=file_hash)
    model.load_weights(weights_path)
  elif weights is not None:
    model.load_weights(weights)
  return model
Beispiel #3
0
def MobileNetV3(stack_fn,
                last_point_ch,
                input_shape=None,
                model_type='large',
                **_):
    if input_shape is None:
        input_shape = (None, None, 3)

    if backend.image_data_format() == 'channels_last':
        row_axis, col_axis = (0, 1)
    else:
        row_axis, col_axis = (1, 2)
    rows = input_shape[row_axis]
    cols = input_shape[col_axis]
    if rows and cols and (rows < 32 or cols < 32):
        raise ValueError(
            'Input size must be at least 32x32; got `input_shape=' +
            str(input_shape) + '`')

    img_input = layers.Input(shape=input_shape)
    channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1

    kernel = 5
    activation = hard_swish
    se_ratio = 0.25

    x = img_input
    x = layers.Rescaling(scale=1. / 127.5, offset=-1.)(x)
    x = layers.Conv2D(16,
                      kernel_size=3,
                      strides=(2, 2),
                      padding='same',
                      use_bias=False,
                      name='Conv')(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv/BatchNorm')(x)
    x = activation(x)

    x = stack_fn(x, kernel, activation, se_ratio)

    last_conv_ch = _depth(backend.int_shape(x)[channel_axis] * 6)

    x = layers.Conv2D(last_conv_ch,
                      kernel_size=1,
                      padding='same',
                      use_bias=False,
                      name='Conv_1')(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv_1/BatchNorm')(x)
    x = activation(x)

    x = layers.GlobalAveragePooling2D()(x)
    if channel_axis == 1:
        x = layers.Reshape((last_conv_ch, 1, 1))(x)
    else:
        x = layers.Reshape((1, 1, last_conv_ch))(x)

    x = layers.Conv2D(last_point_ch,
                      kernel_size=1,
                      padding='same',
                      use_bias=True,
                      name='Conv_2')(x)
    x = activation(x)

    x = layers.Dropout(0.2)(x)
    x = layers.Conv2D(1000, kernel_size=1, padding='same', name='Logits')(x)
    x = layers.Flatten()(x)
    x = layers.Activation(activation='softmax', name='Predictions')(x)

    # Create model.
    model = models.Model(img_input, x, name='MobilenetV3{}'.format(model_type))

    BASE_WEIGHT_PATH = ('https://storage.googleapis.com/tensorflow/'
                        'keras-applications/mobilenet_v3/')
    WEIGHTS_HASHES = {
        'large': '59e551e166be033d707958cf9e29a6a7',
        'small': '8768d4c2e7dee89b9d02b2d03d65d862',
    }

    file_name = 'weights_mobilenet_v3_{}_224_1.0_float.h5'.format(model_type)
    file_hash = WEIGHTS_HASHES[model_type]

    weights_path = data_utils.get_file(file_name,
                                       BASE_WEIGHT_PATH + file_name,
                                       cache_subdir='models',
                                       file_hash=file_hash)
    model.load_weights(weights_path)

    return model
Beispiel #4
0
def MobileNetV3(stack_fn,
                last_point_ch,
                input_shape=None,
                alpha=1.0,
                model_type='large',
                minimalistic=False,
                include_top=True,
                weights='imagenet',
                input_tensor=None,
                classes=1000,
                pooling=None,
                dropout_rate=0.2,
                classifier_activation='softmax'):
    if not (weights in {'imagenet', None} or file_io.file_exists_v2(weights)):
        raise ValueError('The `weights` argument should be either '
                         '`None` (random initialization), `imagenet` '
                         '(pre-training on ImageNet), '
                         'or the path to the weights file to be loaded.')

    if weights == 'imagenet' and include_top and classes != 1000:
        raise ValueError(
            'If using `weights` as `"imagenet"` with `include_top` '
            'as true, `classes` should be 1000')

    # Determine proper input shape and default size.
    # If both input_shape and input_tensor are used, they should match
    if input_shape is not None and input_tensor is not None:
        try:
            is_input_t_tensor = backend.is_keras_tensor(input_tensor)
        except ValueError:
            try:
                is_input_t_tensor = backend.is_keras_tensor(
                    layer_utils.get_source_inputs(input_tensor))
            except ValueError:
                raise ValueError('input_tensor: ', input_tensor,
                                 'is not type input_tensor')
        if is_input_t_tensor:
            if backend.image_data_format == 'channels_first':
                if backend.int_shape(input_tensor)[1] != input_shape[1]:
                    raise ValueError(
                        'input_shape: ', input_shape, 'and input_tensor: ',
                        input_tensor,
                        'do not meet the same shape requirements')
            else:
                if backend.int_shape(input_tensor)[2] != input_shape[1]:
                    raise ValueError(
                        'input_shape: ', input_shape, 'and input_tensor: ',
                        input_tensor,
                        'do not meet the same shape requirements')
        else:
            raise ValueError('input_tensor specified: ', input_tensor,
                             'is not a keras tensor')

    # If input_shape is None, infer shape from input_tensor
    if input_shape is None and input_tensor is not None:

        try:
            backend.is_keras_tensor(input_tensor)
        except ValueError:
            raise ValueError('input_tensor: ', input_tensor, 'is type: ',
                             type(input_tensor), 'which is not a valid type')

        if backend.is_keras_tensor(input_tensor):
            if backend.image_data_format() == 'channels_first':
                rows = backend.int_shape(input_tensor)[2]
                cols = backend.int_shape(input_tensor)[3]
                input_shape = (3, cols, rows)
            else:
                rows = backend.int_shape(input_tensor)[1]
                cols = backend.int_shape(input_tensor)[2]
                input_shape = (cols, rows, 3)
    # If input_shape is None and input_tensor is None using standart shape
    if input_shape is None and input_tensor is None:
        input_shape = (None, None, 3)

    if backend.image_data_format() == 'channels_last':
        row_axis, col_axis = (0, 1)
    else:
        row_axis, col_axis = (1, 2)
    rows = input_shape[row_axis]
    cols = input_shape[col_axis]
    if rows and cols and (rows < 32 or cols < 32):
        raise ValueError(
            'Input size must be at least 32x32; got `input_shape=' +
            str(input_shape) + '`')
    if weights == 'imagenet':
        if (not minimalistic and alpha not in [0.75, 1.0]
                or minimalistic and alpha != 1.0):
            raise ValueError(
                'If imagenet weights are being loaded, '
                'alpha can be one of `0.75`, `1.0` for non minimalistic'
                ' or `1.0` for minimalistic only.')

        if rows != cols or rows != 224:
            logging.warning('`input_shape` is undefined or non-square, '
                            'or `rows` is not 224.'
                            ' Weights for input shape (224, 224) will be'
                            ' loaded as the default.')

    if input_tensor is None:
        img_input = layers.Input(shape=input_shape)
    else:
        if not backend.is_keras_tensor(input_tensor):
            img_input = layers.Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1

    if minimalistic:
        kernel = 3
        activation = relu
        se_ratio = None
    else:
        kernel = 5
        activation = hard_swish
        se_ratio = 0.25

    x = img_input
    x = layers.Rescaling(1. / 255.)(x)
    x = layers.Conv2D(16,
                      kernel_size=3,
                      strides=(2, 2),
                      padding='same',
                      use_bias=False,
                      name='Conv')(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv/BatchNorm')(x)
    x = activation(x)

    x = stack_fn(x, kernel, activation, se_ratio)

    last_conv_ch = _depth(backend.int_shape(x)[channel_axis] * 6)

    # if the width multiplier is greater than 1 we
    # increase the number of output channels
    if alpha > 1.0:
        last_point_ch = _depth(last_point_ch * alpha)
    x = layers.Conv2D(last_conv_ch,
                      kernel_size=1,
                      padding='same',
                      use_bias=False,
                      name='Conv_1')(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv_1/BatchNorm')(x)
    x = activation(x)
    x = layers.Conv2D(last_point_ch,
                      kernel_size=1,
                      padding='same',
                      use_bias=True,
                      name='Conv_2')(x)
    x = activation(x)

    if include_top:
        x = layers.GlobalAveragePooling2D()(x)
        if channel_axis == 1:
            x = layers.Reshape((last_point_ch, 1, 1))(x)
        else:
            x = layers.Reshape((1, 1, last_point_ch))(x)
        if dropout_rate > 0:
            x = layers.Dropout(dropout_rate)(x)
        x = layers.Conv2D(classes,
                          kernel_size=1,
                          padding='same',
                          name='Logits')(x)
        x = layers.Flatten()(x)
        imagenet_utils.validate_activation(classifier_activation, weights)
        x = layers.Activation(activation=classifier_activation,
                              name='Predictions')(x)
    else:
        if pooling == 'avg':
            x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
        elif pooling == 'max':
            x = layers.GlobalMaxPooling2D(name='max_pool')(x)
    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = layer_utils.get_source_inputs(input_tensor)
    else:
        inputs = img_input

    # Create model.
    model = models.Model(inputs, x, name='MobilenetV3' + model_type)

    # Load weights.
    if weights == 'imagenet':
        model_name = '{}{}_224_{}_float'.format(
            model_type, '_minimalistic' if minimalistic else '', str(alpha))
        if include_top:
            file_name = 'weights_mobilenet_v3_' + model_name + '.h5'
            file_hash = WEIGHTS_HASHES[model_name][0]
        else:
            file_name = 'weights_mobilenet_v3_' + model_name + '_no_top.h5'
            file_hash = WEIGHTS_HASHES[model_name][1]
        weights_path = data_utils.get_file(file_name,
                                           BASE_WEIGHT_PATH + file_name,
                                           cache_subdir='models',
                                           file_hash=file_hash)
        model.load_weights(weights_path)
    elif weights is not None:
        model.load_weights(weights)

    return model
    def build_model(self):
        # Build stem
        x = self.img_input
        x = layers.Rescaling(1. / 255.)(x)
        x = layers.Normalization(axis=self.bn_axis)(x)

        x = tf.keras.layers.ZeroPadding2D(padding=imagenet_utils.correct_pad(
            x, 3),
                                          name='stem_conv_pad')(x)
        x = tf.keras.layers.Conv2D(self.round_filters(32),
                                   3,
                                   strides=2,
                                   padding='valid',
                                   use_bias=False,
                                   kernel_initializer=CONV_KERNEL_INITIALIZER,
                                   name='stem_conv')(x)

        x = build_normalization(**self.normalization, name='stem_bn')(x)
        x = build_activation(**self.activation, name='stem_activation')(x)

        block_outputs = [x]
        # Build blocks
        blocks_args = copy.deepcopy(self.blocks_args)
        b = 0
        blocks = float(sum(args['repeats'] for args in blocks_args))
        output_stages = [1, 2, 4, 6]
        for (i, args) in enumerate(blocks_args):
            assert args['repeats'] > 0
            # Update block input and output filters based on depth multiplier.
            args['filters_in'] = self.round_filters(args['filters_in'])
            args['filters_out'] = self.round_filters(args['filters_out'])

            strides = args["strides"]

            for j in range(self.round_repeats(args.pop('repeats'))):
                # The first block needs to take care of stride and filter size increase.
                if j > 0:
                    args['strides'] = 1
                    args['filters_in'] = args['filters_out']
                x = self.block(x,
                               self.activation,
                               self.drop_connect_rate * b / blocks,
                               name='block{}{}_'.format(i + 1, chr(j + 97)),
                               **args)
                b += 1
            if i in output_stages:
                block_outputs.append(x)

        # Build top
        x = tf.keras.layers.Conv2D(self.round_filters(1280),
                                   1,
                                   padding='same',
                                   use_bias=False,
                                   kernel_initializer=CONV_KERNEL_INITIALIZER,
                                   name='top_conv')(x)
        x = build_normalization(**self.normalization, name='top_bn')(x)
        x = build_activation(**self.activation, name='top_activation')(x)
        if -1 in self.output_indices:
            x = tf.keras.layers.GlobalAveragePooling2D(name='avg_pool')(x)
            if self.dropout_rate > 0:
                x = tf.keras.layers.Dropout(self.dropout_rate,
                                            name='top_dropout')(x)
            x = tf.keras.layers.Dense(
                1000,
                activation=self.classifier_activation,
                kernel_initializer=DENSE_KERNEL_INITIALIZER,
                name='predictions')(x)
            # Ensure that the model takes into account
            # any potential predecessors of `input_tensor`.
            if self.input_tensor is not None:
                inputs = tf.keras.utils.get_source_inputs(self.input_tensor)
            else:
                inputs = self.img_input
            # Create model.
            return tf.keras.Model(inputs=self.img_input,
                                  outputs=x,
                                  name=model_name)

        return [block_outputs[i - 1] for i in self.output_indices]
Beispiel #6
0
def get_quantize_inputs_test_model(input_shapes):
    #    (1)     (2)      (3)    (4)   (5)
    #     |       |        |      |     |-----\
    #  (conv1)   (MP)     (MP)    (MP)  (MP)  |
    #     |       |       | |     |     |     |
    #     |       |       (+)     |     |     |
    #     |       |--\     |      |     |     |
    #     |       |   \    |      |     |     |
    #     |    (conv2) | (conv3)  |     |     |
    #     |       |    |   |       \   /      |
    #     |     (AvP)  \   |       (cat)      |
    #     |       |     \  |         |        |
    #  (conv4) (linear)  \ |      (conv6)     |
    #     |       |      (cat)       |        |
    #     |       |        |        (+)------/
    #     |       |      (conv5)     |
    #   (AvP)     |        |         |
    #     |       |      (AvP)       |
    #      \      |        /         |
    #       \---(cat)---------------/
    #             |
    #           (dense)

    inputs = []
    for i, input_shape in enumerate(input_shapes):
        inputs.append(
            tf.keras.Input(shape=input_shape[1:],
                           name='input_{}'.format(i + 1)))
    # pylint: disable=unbalanced-tuple-unpacking
    input_1, input_2, input_3, input_4, input_5 = inputs

    conv1 = layers.Conv2D(filters=8, kernel_size=3)
    conv2 = layers.Conv2D(filters=8, kernel_size=3)
    conv3 = layers.Conv2D(filters=8, kernel_size=3)
    conv4 = layers.Conv2D(filters=16, kernel_size=3)
    conv5 = layers.Conv2D(filters=3, kernel_size=1)
    conv6 = layers.Conv2D(filters=3, kernel_size=2)
    dense = layers.Dense(8)

    x_1 = layers.Rescaling(1. / 255.)(input_1)
    x_1 = conv1(x_1)
    x_1 = conv4(x_1)
    x_1 = layers.GlobalAveragePooling2D()(x_1)
    x_1 = layers.Flatten()(x_1)

    x_2_br = layers.MaxPool2D(pool_size=2)(input_2)
    x_2 = conv2(x_2_br)
    x_2 = layers.GlobalAveragePooling2D()(x_2)
    x_2 = layers.Flatten()(x_2)
    x_2 = dense(x_2)

    x_3 = layers.MaxPool2D(pool_size=2)(input_3)
    x_3 = x_3 + x_3
    x_3 = conv3(x_3)
    x_3 = layers.Flatten()(x_3)
    x_2_br = layers.Flatten()(x_2_br)
    x_3 = tf.concat([x_2_br, x_3], -1)
    x_3 = conv5(tf.expand_dims(tf.expand_dims(x_3, -1), -1))
    x_3 = layers.GlobalAveragePooling2D()(x_3)
    x_3 = layers.Flatten()(x_3)

    x_4 = layers.MaxPool2D(pool_size=2)(input_4)
    x_5 = layers.MaxPool2D(pool_size=2)(input_5)
    x_45 = tf.concat([x_4, x_5], -1)
    x_45 = conv6(x_45)
    x_45 = layers.Flatten()(x_45)
    in_5_flat = layers.Flatten()(input_5)
    # pylint: disable=E1120
    x_45 = tf.pad(x_45, [[0, 0], [0, in_5_flat.shape[1] - x_45.shape[1]]])
    x_45 += in_5_flat
    x = tf.concat([x_1, x_2, x_3, x_45], -1)
    outputs = layers.Dense(10)(x)

    return tf.keras.Model(inputs=inputs, outputs=outputs)
Beispiel #7
0
def MobileNetV3Small(input_shape=None):
    if input_shape is None:
        input_shape = (None, None, 3)

    if backend.image_data_format() == 'channels_last':
        row_axis, col_axis = (0, 1)
    else:
        row_axis, col_axis = (1, 2)
    rows = input_shape[row_axis]
    cols = input_shape[col_axis]
    if rows and cols and (rows < 32 or cols < 32):
        raise ValueError(
            'Input size must be at least 32x32; got `input_shape=' +
            str(input_shape) + '`')

    img_input = layers.Input(shape=input_shape)
    channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1

    kernel = 5
    activation = hard_swish
    se_ratio = 0.25
    last_point_ch = 1024

    x = img_input
    x = layers.Rescaling(1. / 255.)(x)
    x = layers.Conv2D(16,
                      kernel_size=3,
                      strides=(2, 2),
                      padding='same',
                      use_bias=False,
                      name='Conv')(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv/BatchNorm')(x)
    x = activation(x)

    x = stack_fn(x, kernel, activation, se_ratio)

    last_conv_ch = _depth(backend.int_shape(x)[channel_axis] * 6)

    x = layers.Conv2D(last_conv_ch,
                      kernel_size=1,
                      padding='same',
                      use_bias=False,
                      name='Conv_1')(x)
    x = layers.BatchNormalization(axis=channel_axis,
                                  epsilon=1e-3,
                                  momentum=0.999,
                                  name='Conv_1/BatchNorm')(x)
    x = activation(x)
    x = layers.Conv2D(last_point_ch,
                      kernel_size=1,
                      padding='same',
                      use_bias=True,
                      name='Conv_2')(x)
    x = activation(x)

    x = layers.GlobalAveragePooling2D()(x)
    if channel_axis == 1:
        x = layers.Reshape((last_point_ch, 1, 1))(x)
    else:
        x = layers.Reshape((1, 1, last_point_ch))(x)
    x = layers.Dropout(0.2)(x)
    x = layers.Conv2D(1000, kernel_size=1, padding='same', name='Logits')(x)
    x = layers.Flatten()(x)
    x = layers.Activation(activation='softmax', name='Predictions')(x)

    # Create model.
    return models.Model(img_input, x, name='MobilenetV3small')
def efficientnetB0(width_coeff=1,
                   depth_coeff=1,
                   default_img_size=224,
                   dropoutrate=0.2,
                   drop_connect_rate=0.2,
                   depth_divisor=8,
                   activations='swish',
                   block_args='default',
                   include_top=True,
                   weights='imagenet',
                   input_tensor=None,
                   input_shape=None,
                   pooling=None,
                   classes=1000,
                   classifier_activation='softmax'):

    if block_args == 'default':
        block_args = DEFAULT_BLOCKS_ARGS

    if not (weights in {'imagenet', None} or file_io.file_exists(weights)):
        raise ValueError('The `weights` argument should be either '
                         '`None` (random initialization), `imagenet` '
                         '(pre-training on ImageNet), '
                         'or the path to the weights file to be loaded.')

    if weights == 'imagenet' and include_top and classes != 1000:
        raise ValueError(
            'If using `weights` as `"imagenet"` with `include_top`'
            ' as true, `classes` should be 1000')

    # proper input shape check

    input_shape = imagenet_utils.obtain_input_shape(
        input_shape,
        default_size=default_img_size,
        min_size=32,
        data_format=backend.image_data_format(),
        require_flatten=include_top,
        weights=weights)

    if input_tensor is None:
        img_input = layers.Input(shape=input_shape)
    else:
        if not backend.is_keras_tensor(input_tensor):
            img_input = layers.Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1

    def round_filters(filters, divisor=depth_divisor):
        """ round number of filters based on depth multiplier"""
        filters *= width_coeff
        new_filters = max(divisor,
                          int(filters + divisor / 2) // divisor * divisor)
        #making sure round down does not go down by 10%
        if new_filters < 0.9 * filters:
            new_filters += divisor
        return int(new_filters)

    def round_repeats(repeats):
        """Round number of repeats based on depth multiplier."""
        return int(math.ceil(depth_coeff * repeats))

    #building stem

    x = img_input
    x = layers.Rescaling(1. / 255.)(x)
    x = layers.Normalization(axis=bn_axis)(x)

    x = layers.ZeroPadding2D(padding=imagenet_utils.correct_pad(x, 3))(x)
    x = layers.Conv2D(round_filters(32),
                      kernel_size=3,
                      strides=2,
                      padding='valid',
                      use_bias=False,
                      kernel_initializer=CONV_KERNEL_INITIALIZER)(x)

    x = layers.BatchNormalization(axis=bn_axis)(x)
    x = layers.Activation(activations)(x)

    #building blocks
    block_args = copy.deepcopy(block_args)

    b = 0
    blocks = float(sum(round_repeats(args['repeats']) for args in block_args))

    for (i, args) in enumerate(block_args):
        assert args['repeats'] > 0

        args['filters_in'] = round_filters(args['filters_in'])
        args['filters_out'] = round_filters(args['filters_out'])

        for j in range(round_repeats(args.pop('repeats'))):
            # The first block needs to take care of stride and filter size increase.
            if j > 0:
                args['strides'] = 1
                args['filters_in'] = args['filters_out']

            x = mbconvblock(inputs=x,
                            activations=activations,
                            droprate=drop_connect_rate * b / blocks,
                            name=str(i),
                            **args)
            b += 1

    #build top

    x = layers.Conv2D(round_filters(1280),
                      kernel_size=1,
                      padding='same',
                      use_bias=False,
                      kernel_initializer=CONV_KERNEL_INITIALIZER)(x)

    x = layers.BatchNormalization(axis=bn_axis)(x)
    x = layers.Activation(activations)(x)

    if include_top:
        x = layers.GlobalAveragePooling2D()(x)
        if dropoutrate > 0:
            x = layers.Dropout(dropoutrate)(x)
        imagenet_utils.validate_activation(classifier_activation, weights)

        x = layers.Dense(classes,
                         activation=classifier_activation,
                         kernel_initializer=DENSE_KERNEL_INITIALIZER)(x)

    else:
        if pooling == 'avg':
            x = layers.GlobalAveragePooling2D()(x)
        elif pooling == 'max':
            x = layers.GlobalMaxPooling2D()(x)

    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = layer_utils.get_source_inputs(input_tensor)
    else:
        inputs = img_input

    #creating model
    model = training.Model(inputs, x)

    return model