text: from keras import utils
  from keras import *
  
  def conv2d_bn(x,
                filters,
                kernel_size,
                strides=1,
                padding='same',
                activation='relu',
                use_bias=False,
                name=None):
      """Utility function to apply conv + BN.
      # Arguments
          x: input tensor.
          filters: filters in `Conv2D`.
          kernel_size: kernel size as in `Conv2D`.
          strides: strides in `Conv2D`.
          padding: padding mode in `Conv2D`.
          activation: activation in `Conv2D`.
          use_bias: whether to use a bias in `Conv2D`.
          name: name of the ops; will become `name + '_ac'` for the activation
              and `name + '_bn'` for the batch norm layer.
      # Returns
          Output tensor after applying `Conv2D` and `BatchNormalization`.
      """
      if name is None:
          print('None!!')
  
      x = layers.Conv2D(filters,
                        kernel_size,
                        strides=strides,
                        padding=padding,
                        use_bias=use_bias,
                        name=name)(x)
      if not use_bias:
          bn_axis = 1 if backend.image_data_format() == 'channels_first' else 3
          bn_name = None if name is None else name + '_bn'
          x = layers.BatchNormalization(axis=bn_axis,
                                        scale=False,
                                        name=bn_name)(x)
      if activation is not None:
          ac_name = None if name is None else name + '_ac'
          x = layers.Activation(activation, name=ac_name)(x)
      return x
  
  
  def inception_resnet_block(x, scale, block_type, block_idx, activation='relu'):
      """Adds a Inception-ResNet block.
      This function builds 3 types of Inception-ResNet blocks mentioned
      in the paper, controlled by the `block_type` argument (which is the
      block name used in the official TF-slim implementation):
          - Inception-ResNet-A: `block_type='block35'`
          - Inception-ResNet-B: `block_type='block17'`
          - Inception-ResNet-C: `block_type='block8'`
      # Arguments
          x: input tensor.
          scale: scaling factor to scale the residuals (i.e., the output of
              passing `x` through an inception module) before adding them
              to the shortcut branch.
              Let `r` be the output from the residual branch,
              the output of this block will be `x + scale * r`.
          block_type: `'block35'`, `'block17'` or `'block8'`, determines
              the network structure in the residual branch.
          block_idx: an `int` used for generating layer names.
              The Inception-ResNet blocks
              are repeated many times in this network.
              We use `block_idx` to identify
              each of the repetitions. For example,
              the first Inception-ResNet-A block
              will have `block_type='block35', block_idx=0`,
              and the layer names will have
              a common prefix `'block35_0'`.
          activation: activation function to use at the end of the block
              (see [activations](../activations.md)).
              When `activation=None`, no activation is applied
              (i.e., "linear" activation: `a(x) = x`).
      # Returns
          Output tensor for the block.
      # Raises
          ValueError: if `block_type` is not one of `'block35'`,
              `'block17'` or `'block8'`.
      """
      block_name = block_type + '_' + str(block_idx)
  
      if block_type == 'block35':
          branch_0 = conv2d_bn(x, 32, 1, name=block_name + '_conv1')
          branch_1 = conv2d_bn(x, 32, 1, name=block_name + '_conv2')
          branch_1 = conv2d_bn(branch_1, 32, 3, name=block_name + '_conv3')
          branch_2 = conv2d_bn(x, 32, 1, name=block_name + '_conv4')
          branch_2 = conv2d_bn(branch_2, 48, 3, name=block_name + '_conv5')
          branch_2 = conv2d_bn(branch_2, 64, 3, name=block_name + '_conv6')
          branches = [branch_0, branch_1, branch_2]
      elif block_type == 'block17':
          branch_0 = conv2d_bn(x, 192, 1, name=block_name + '_conv1')
          branch_1 = conv2d_bn(x, 128, 1, name=block_name + '_conv2')
          branch_1 = conv2d_bn(branch_1, 160, [1, 7], name=block_name + '_conv3')
          branch_1 = conv2d_bn(branch_1, 192, [7, 1], name=block_name + '_conv4')
          branches = [branch_0, branch_1]
      elif block_type == 'block8':
          branch_0 = conv2d_bn(x, 192, 1, name=block_name + '_conv1')
          branch_1 = conv2d_bn(x, 192, 1, name=block_name + '_conv2')
          branch_1 = conv2d_bn(branch_1, 224, [1, 3], name=block_name + '_conv3')
          branch_1 = conv2d_bn(branch_1, 256, [3, 1], name=block_name + '_conv4')
          branches = [branch_0, branch_1]
      else:
          raise ValueError('Unknown Inception-ResNet block type. '
                           'Expects "block35", "block17" or "block8", '
                           'but got: ' + str(block_type))
  
      channel_axis = 1 if backend.image_data_format() == 'channels_first' else 3
      mixed = layers.Concatenate(
          axis=channel_axis, name=block_name + '_mixed')(branches)
      up = conv2d_bn(mixed,
                     backend.int_shape(x)[channel_axis],
                     1,
                     activation=None,
                     use_bias=True,
                     name=block_name + '_conv')
  
      x = layers.Lambda(lambda inputs, scale: inputs[0] + inputs[1] * scale,
                        output_shape=backend.int_shape(x)[1:],
                        arguments={'scale': scale},
                        name=block_name)([x, up])
      if activation is not None:
          x = layers.Activation(activation, name=block_name + '_ac')(x)
      return x
  
  
  def InceptionResnetV2_model(input_shape, include_top=False, input_tensor=None, weights='imagenet', pooling=None):
      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
  
      # Stem block: 35 x 35 x 192
      x = conv2d_bn(img_input, 32, 3, strides=2, padding='valid', name='Stem_block' + '_conv1')
      x = conv2d_bn(x, 32, 3, padding='valid', name='Stem_block' + '_conv2')
      x = conv2d_bn(x, 64, 3, name='Stem_block' + '_conv3')
      x = layers.MaxPooling2D(3, strides=2)(x)
      x = conv2d_bn(x, 80, 1, padding='valid', name='Stem_block' + '_conv4')
      x = conv2d_bn(x, 192, 3, padding='valid', name='Stem_block' + '_conv5')
      x = layers.MaxPooling2D(3, strides=2)(x)
  
      # Mixed 5b (Inception-A block): 35 x 35 x 320
      branch_0 = conv2d_bn(x, 96, 1, name='Inception_A_block' + '_conv1')
      branch_1 = conv2d_bn(x, 48, 1, name='Inception_A_block' + '_conv2')
      branch_1 = conv2d_bn(branch_1, 64, 5, name='Inception_A_block' + '_conv3')
      branch_2 = conv2d_bn(x, 64, 1, name='Inception_A_block' + '_conv4')
      branch_2 = conv2d_bn(branch_2, 96, 3, name='Inception_A_block' + '_conv5')
      branch_2 = conv2d_bn(branch_2, 96, 3, name='Inception_A_block' + '_conv6')
      branch_pool = layers.AveragePooling2D(3, strides=1, padding='same')(x)
      branch_pool = conv2d_bn(branch_pool, 64, 1, name='Inception_A_block' + '_conv7')
      branches = [branch_0, branch_1, branch_2, branch_pool]
      channel_axis = 1 if backend.image_data_format() == 'channels_first' else 3
      x = layers.Concatenate(axis=channel_axis, name='mixed_5b')(branches)
  
      # 10x block35 (Inception-ResNet-A block): 35 x 35 x 320
      for block_idx in range(1, 11):
          x = inception_resnet_block(x,
                                     scale=0.17,
                                     block_type='block35',
                                     block_idx=block_idx)
  
      # Mixed 6a (Reduction-A block): 17 x 17 x 1088
      branch_0 = conv2d_bn(x, 384, 3, strides=2, padding='valid', name='Reduction_A_block' + '_conv1')
      branch_1 = conv2d_bn(x, 256, 1, name='Reduction_A_block' + '_conv2')
      branch_1 = conv2d_bn(branch_1, 256, 3, name='Reduction_A_block' + '_conv3')
      branch_1 = conv2d_bn(branch_1, 384, 3, strides=2, padding='valid', name='Reduction_A_block' + '_conv4')
      branch_pool = layers.MaxPooling2D(3, strides=2, padding='valid')(x)
      branches = [branch_0, branch_1, branch_pool]
      x = layers.Concatenate(axis=channel_axis, name='mixed_6a')(branches)
  
      # 20x block17 (Inception-ResNet-B block): 17 x 17 x 1088
      for block_idx in range(1, 21):
          x = inception_resnet_block(x,
                                     scale=0.1,
                                     block_type='block17',
                                     block_idx=block_idx)
  
      # Mixed 7a (Reduction-B block): 8 x 8 x 2080
      branch_0 = conv2d_bn(x, 256, 1, name='Reduction_B_block' + '_conv1')
      branch_0 = conv2d_bn(branch_0, 384, 3, strides=2, padding='valid', name='Reduction_B_block' + '_conv2')
      branch_1 = conv2d_bn(x, 256, 1, name='Reduction_B_block' + '_conv3')
      branch_1 = conv2d_bn(branch_1, 288, 3, strides=2, padding='valid', name='Reduction_B_block' + '_conv4')
      branch_2 = conv2d_bn(x, 256, 1, name='Reduction_B_block' + '_conv5')
      branch_2 = conv2d_bn(branch_2, 288, 3, name='Reduction_B_block' + '_conv6')
      branch_2 = conv2d_bn(branch_2, 320, 3, strides=2, padding='valid', name='Reduction_B_block' + '_conv7')
      branch_pool = layers.MaxPooling2D(3, strides=2, padding='valid')(x)
      branches = [branch_0, branch_1, branch_2, branch_pool]
      x = layers.Concatenate(axis=channel_axis, name='mixed_7a')(branches)
  
      # 10x block8 (Inception-ResNet-C block): 8 x 8 x 2080
      for block_idx in range(1, 10):
          x = inception_resnet_block(x,
                                     scale=0.2,
                                     block_type='block8',
                                     block_idx=block_idx)
      x = inception_resnet_block(x,
                                 scale=1.,
                                 activation=None,
                                 block_type='block8',
                                 block_idx=10)
  
      # Final convolution block: 8 x 8 x 1536
      x = conv2d_bn(x, 1536, 1, name='conv_7b')
  
  
      if include_top:
          # Classification block
          x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
          x = layers.Dense(1000, activation='softmax', name='predictions')(x)
      else:
          if pooling == 'avg':
              x = layers.GlobalAveragePooling2D()(x)
          elif pooling == 'max':
              x = layers.GlobalMaxPooling2D()(x)
  
      inputs = img_input
  
      # Create model.
      model = models.Model(inputs, x, name='inception_resnet_v2')
  
      BASE_WEIGHT_URL = ('https://github.com/fchollet/deep-learning-models/'
                         'releases/download/v0.7/')
  
      # Load weights.
      if weights == 'imagenet':
          if include_top:
              fname = 'inception_resnet_v2_weights_tf_dim_ordering_tf_kernels.h5'
              weights_path = utils.get_file(
                  fname,
                  BASE_WEIGHT_URL + fname,
                  cache_subdir='models',
                  file_hash='e693bd0210a403b3192acc6073ad2e96')
          else:
              fname = ('inception_resnet_v2_weights_'
                       'tf_dim_ordering_tf_kernels_notop.h5')
              weights_path = utils.get_file(
                  fname,
                  BASE_WEIGHT_URL + fname,
                  cache_subdir='models',
                  file_hash='d19885ff4a710c122648d3b5c3b684e4')
          model.load_weights(weights_path)
      elif weights is not None:
          model.load_weights(weights)
  
      return model