def _make_image_to_vec_tito(feature_name, tmp_dir=None, checkpoint=None):
  """Creates a tensor-in-tensor-out function that produces embeddings from image bytes.

  Image to embedding is implemented with Tensorflow's inception v3 model and a pretrained
  checkpoint. It returns 1x2048 'PreLogits' embeddings for each image.

  Args:
    feature_name: The name of the feature. Used only to identify the image tensors so
      we can get gradients for probe in image prediction explaining.
    tmp_dir: a local directory that is used for downloading the checkpoint. If
      non, a temp folder will be made and deleted.
    checkpoint: the inception v3 checkpoint gs or local path. If None, default checkpoint
      is used.

  Returns: a tensor-in-tensor-out function that takes image string tensor and returns embeddings.
  """

  def _image_to_vec(image_str_tensor):

    def _decode_and_resize(image_tensor):
      """Decodes jpeg string, resizes it and returns a uint8 tensor."""

      # These constants are set by Inception v3's expectations.
      height = 299
      width = 299
      channels = 3

      image_tensor = tf.where(tf.equal(image_tensor, ''), IMAGE_DEFAULT_STRING, image_tensor)

      # Fork by whether image_tensor value is a file path, or a base64 encoded string.
      slash_positions = tf.equal(tf.string_split([image_tensor], delimiter="").values, '/')
      is_file_path = tf.cast(tf.count_nonzero(slash_positions), tf.bool)

      # The following two functions are required for tf.cond. Note that we can not replace them
      # with lambda. According to TF docs, if using inline lambda, both branches of condition
      # will be executed. The workaround is to use a function call.
      def _read_file():
        return tf.read_file(image_tensor)

      def _decode_base64():
        return tf.decode_base64(image_tensor)

      image = tf.cond(is_file_path, lambda: _read_file(), lambda: _decode_base64())
      image = tf.image.decode_jpeg(image, channels=channels)
      image = tf.expand_dims(image, 0)
      image = tf.image.resize_bilinear(image, [height, width], align_corners=False)
      image = tf.squeeze(image, squeeze_dims=[0])
      image = tf.cast(image, dtype=tf.uint8)
      return image

    # The CloudML Prediction API always "feeds" the Tensorflow graph with
    # dynamic batch sizes e.g. (?,).  decode_jpeg only processes scalar
    # strings because it cannot guarantee a batch of images would have
    # the same output size.  We use tf.map_fn to give decode_jpeg a scalar
    # string from dynamic batches.
    image = tf.map_fn(_decode_and_resize, image_str_tensor, back_prop=False, dtype=tf.uint8)
    image = tf.image.convert_image_dtype(image, dtype=tf.float32)
    # "gradients_[feature_name]" will be used for computing integrated gradients.
    image = tf.identity(image, name='gradients_' + feature_name)
    image = tf.subtract(image, 0.5)
    inception_input = tf.multiply(image, 2.0)

    # Build Inception layers, which expect a tensor of type float from [-1, 1)
    # and shape [batch_size, height, width, channels].
    with tf.contrib.slim.arg_scope(inception_v3_arg_scope()):
      _, end_points = inception_v3(inception_input, is_training=False)

    embeddings = end_points['PreLogits']
    inception_embeddings = tf.squeeze(embeddings, [1, 2], name='SpatialSqueeze')
    return inception_embeddings

  def _tito_from_checkpoint(tito_in, checkpoint, exclude):
    """ Create an all-constants tito function from an original tito function.

    Given a tensor-in-tensor-out function which contains variables and a checkpoint path,
    create a new tensor-in-tensor-out function which includes only constants, and can be
    used in tft.map.
    """

    def _tito_out(tensor_in):
      checkpoint_dir = tmp_dir
      if tmp_dir is None:
        checkpoint_dir = tempfile.mkdtemp()

      g = tf.Graph()
      with g.as_default():
        si = tf.placeholder(dtype=tensor_in.dtype, shape=tensor_in.shape, name=tensor_in.op.name)
        so = tito_in(si)
        all_vars = tf.contrib.slim.get_variables_to_restore(exclude=exclude)
        saver = tf.train.Saver(all_vars)
        # Downloading the checkpoint from GCS to local speeds up saver.restore() a lot.
        checkpoint_tmp = os.path.join(checkpoint_dir, 'checkpoint')
        with file_io.FileIO(checkpoint, 'r') as f_in, file_io.FileIO(checkpoint_tmp, 'w') as f_out:
          f_out.write(f_in.read())
        with tf.Session() as sess:
          saver.restore(sess, checkpoint_tmp)
          output_graph_def = tf.graph_util.convert_variables_to_constants(sess,
                                                                          g.as_graph_def(),
                                                                          [so.op.name])
        file_io.delete_file(checkpoint_tmp)
        if tmp_dir is None:
          shutil.rmtree(checkpoint_dir)

      tensors_out = tf.import_graph_def(output_graph_def,
                                        input_map={si.name: tensor_in},
                                        return_elements=[so.name])
      return tensors_out[0]

    return _tito_out

  if not checkpoint:
    checkpoint = INCEPTION_V3_CHECKPOINT
  return _tito_from_checkpoint(_image_to_vec, checkpoint, INCEPTION_EXCLUDED_VARIABLES)
def _make_image_to_vec_tito ( feature_name , tmp_dir = None , checkpoint = None ) : def _image_to_vec ( image_str_tensor ) : def _decode_and_resize ( image_tensor ) : height = 299 width = 299 channels = 3 image_tensor = tf . where ( tf . equal ( image_tensor , '' ) , IMAGE_DEFAULT_STRING , image_tensor ) slash_positions = tf . equal ( tf . string_split ( [ image_tensor ] , delimiter = "" ) . values , '/' ) is_file_path = tf . cast ( tf . count_nonzero ( slash_positions ) , tf . bool ) def _read_file ( ) : return tf . read_file ( image_tensor ) def _decode_base64 ( ) : return tf . decode_base64 ( image_tensor ) image = tf . cond ( is_file_path , lambda : _read_file ( ) , lambda : _decode_base64 ( ) ) image = tf . image . decode_jpeg ( image , channels = channels ) image = tf . expand_dims ( image , 0 ) image = tf . image . resize_bilinear ( image , [ height , width ] , align_corners = False ) image = tf . squeeze ( image , squeeze_dims = [ 0 ] ) image = tf . cast ( image , dtype = tf . uint8 ) return image image = tf . map_fn ( _decode_and_resize , image_str_tensor , back_prop = False , dtype = tf . uint8 ) image = tf . image . convert_image_dtype ( image , dtype = tf . float32 ) image = tf . identity ( image , name = 'gradients_' + feature_name ) image = tf . subtract ( image , 0.5 ) inception_input = tf . multiply ( image , 2.0 ) with tf . contrib . slim . arg_scope ( inception_v3_arg_scope ( ) ) : _ , end_points = inception_v3 ( inception_input , is_training = False ) embeddings = end_points [ 'PreLogits' ] inception_embeddings = tf . squeeze ( embeddings , [ 1 , 2 ] , name = 'SpatialSqueeze' ) return inception_embeddings def _tito_from_checkpoint ( tito_in , checkpoint , exclude ) : def _tito_out ( tensor_in ) : checkpoint_dir = tmp_dir if tmp_dir is None : checkpoint_dir = tempfile . mkdtemp ( ) g = tf . Graph ( ) with g . as_default ( ) : si = tf . placeholder ( dtype = tensor_in . dtype , shape = tensor_in . shape , name = tensor_in . op . name ) so = tito_in ( si ) all_vars = tf . contrib . slim . get_variables_to_restore ( exclude = exclude ) saver = tf . train . Saver ( all_vars ) checkpoint_tmp = os . path . join ( checkpoint_dir , 'checkpoint' ) with file_io . FileIO ( checkpoint , 'r' ) as f_in , file_io . FileIO ( checkpoint_tmp , 'w' ) as f_out : f_out . write ( f_in . read ( ) ) with tf . Session ( ) as sess : saver . restore ( sess , checkpoint_tmp ) output_graph_def = tf . graph_util . convert_variables_to_constants ( sess , g . as_graph_def ( ) , [ so . op . name ] ) file_io . delete_file ( checkpoint_tmp ) if tmp_dir is None : shutil . rmtree ( checkpoint_dir ) tensors_out = tf . import_graph_def ( output_graph_def , input_map = { si . name : tensor_in } , return_elements = [ so . name ] ) return tensors_out [ 0 ] return _tito_out if not checkpoint : checkpoint = INCEPTION_V3_CHECKPOINT return _tito_from_checkpoint ( _image_to_vec , checkpoint , INCEPTION_EXCLUDED_VARIABLES )
Creates a tensor-in-tensor-out function that produces embeddings from image bytes.

  Image to embedding is implemented with Tensorflow's inception v3 model and a pretrained
  checkpoint. It returns 1x2048 'PreLogits' embeddings for each image.

  Args:
    feature_name: The name of the feature. Used only to identify the image tensors so
      we can get gradients for probe in image prediction explaining.
    tmp_dir: a local directory that is used for downloading the checkpoint. If
      non, a temp folder will be made and deleted.
    checkpoint: the inception v3 checkpoint gs or local path. If None, default checkpoint
      is used.

  Returns: a tensor-in-tensor-out function that takes image string tensor and returns embeddings.