Пример #1
0
def _deserialize_keras_model(model_topology_json,
                             weight_entries=None,
                             use_unique_name_scope=False):
  """Internal helper method for deserializing a Keras Model.

  Args:
    model_topology_json: content of the JSON containing model topology, in
      Keras (i.e., tfjs-layers) format. It can be any of the following types:
      - A JSON object, i.e., a `dict`.
      - A `str` or `buffer`, in which case it will be parsed as a JSON object.
      - A `file` object or `file`-like object containing the JSON, in which
        case it will be read with the `read()` method and the content parsed
        as a JSON object.
    weight_entries: Weight entries, in tensorflow.js format, as a `list`.
    use_unique_name_scope: Use a unique ID as the name scope for the loaded
      model. This may facilitate loading of multiple Keras models in the
      same TensorFlow Graph or Session context. Default: `False`.
  """
  if isinstance(model_topology_json, (six.string_types, bytes)):
    model_topology_json = json.loads(tf.compat.as_text(model_topology_json))
  elif not isinstance(model_topology_json, dict):
    model_topology_json = json.load(model_topology_json)
  is_tf_keras = ('keras_version' in model_topology_json and
                 model_topology_json['keras_version'].endswith('-tf'))

  if 'model_config' in model_topology_json:
    model_topology_json = model_topology_json['model_config']
  unique_name_scope = uuid.uuid4().hex if use_unique_name_scope else None
  with tf.compat.v1.name_scope(unique_name_scope):
    with CustomObjectScope({'relu6': relu6}):
      if is_tf_keras:
        model = keras.models.model_from_json(json.dumps(model_topology_json))
      else:
        model = keras.models.model_from_json(json.dumps(model_topology_json))

  if weight_entries:
    weights_dict = dict()
    for weight_entry in weight_entries:
      weights_dict[weight_entry['name']] = weight_entry['data']

    # Collect weight names from the model, in the same order as the internal
    # ordering of model.set_weights() used below.
    weight_names = []
    for layer in model.layers:
      for w in layer.weights:
        weight_names.append(
            keras_h5_conversion.normalize_weight_name(
                w.name[len(unique_name_scope) + 1:])
            if use_unique_name_scope
            else keras_h5_conversion.normalize_weight_name(w.name))

    # Prepare list of weight values for calling set_weights().
    weights_list = [weights_dict[name] for name in weight_names]
    model.set_weights(weights_list)

  return model
Пример #2
0
def _deserialize_keras_model(model_topology_json,
                             weight_entries=None,
                             use_unique_name_scope=False):
  """Internal helper method for deserializing a Keras Model.

  Args:
    model_topology_json: content of the JSON containing model topology, in
      Keras (i.e., tfjs-layers) format. It can be any of the following types:
      - A JSON object, i.e., a `dict`.
      - A `str` or `buffer`, in which case it will be parsed as a JSON object.
      - A `file` object or `file`-like object containing the JSON, in which
        case it will be read with the `read()` method and the content parsed
        as a JSON object.
    weight_entries: Weight entries, in tensorflow.js format, as a `list`.
    use_unique_name_scope: Use a unique ID as the name scope for the loaded
      model. This may facilitate loading of multiple Keras models in the
      same TensorFlow Graph or Session context. Default: `False`.
  """
  if isinstance(model_topology_json, (six.string_types, bytes)):
    model_topology_json = json.loads(tf.compat.as_text(model_topology_json))
  elif not isinstance(model_topology_json, dict):
    model_topology_json = json.load(model_topology_json)
  is_tf_keras = ('keras_version' in model_topology_json and
                 model_topology_json['keras_version'].endswith('-tf'))

  if 'model_config' in model_topology_json:
    model_topology_json = model_topology_json['model_config']
  unique_name_scope = uuid.uuid4().hex if use_unique_name_scope else None
  with tf.name_scope(unique_name_scope):
    if is_tf_keras:
      model = tf.keras.models.model_from_json(json.dumps(model_topology_json))
    else:
      model = keras.models.model_from_json(json.dumps(model_topology_json))

  if weight_entries:
    weights_dict = dict()
    for weight_entry in weight_entries:
      weights_dict[weight_entry['name']] = weight_entry['data']

    # Collect weight names from the model, in the same order as the internal
    # ordering of model.set_weights() used below.
    weight_names = []
    for layer in model.layers:
      for w in layer.weights:
        weight_names.append(
            keras_h5_conversion.normalize_weight_name(
                w.name[len(unique_name_scope) + 1:])
            if use_unique_name_scope
            else keras_h5_conversion.normalize_weight_name(w.name))

    # Prepare list of weight values for calling set_weights().
    weights_list = [weights_dict[name] for name in weight_names]
    model.set_weights(weights_list)

  return model
Пример #3
0
def load_keras_model(config_json_path,
                     weights_path_prefix=None,
                     weights_data_buffers=None,
                     load_weights=True,
                     use_unique_name_scope=False):
    """Load a Keras Model from TensorFlow.js-format artifacts.

  Args:
    config_json_path: Path to the TensorFlow.js-format JSON file that includes
      the model topology and weights manifest.
    weights_path_prefix: Optional path prefix for the weights files.
      If not specified (`None`), will assume the prefix is the same directory
      as the dirname of `config_json_path`.
    weights_data_buffers: A buffer of a `list` of buffers containing the weight
      values concatenated and sharded in the order as specified by the
      weights manifest at `config_json_path`. This argument is mutually
      exclusive with `weights_path_prefix`.
    load_weights: Whether the weights are to be loaded according
      to the weights manifest at `config_json_path`. Default: `True`.
    use_unique_name_scope: Use a unique ID as the name scope for the loaded
      model. This may facilitate loading of multiple Keras models in the
      same TensorFlow Graph or Session context. Default: `False`.

  Returns:
    The loaded instance of `keras.Model`.

  Raises:
    TypeError, if the format of the JSON content of `config_json_path` has an
      invalid format.
    KeyError, if required keys do not exist in the JSON content of
      `config_json_path`.
    ValueError, if both `weights_data_buffers` and `weights_path_prefix` are
      provided.
  """
    with open(config_json_path, 'rt') as f:
        model_and_weights_manifest = json.load(f)

    if not isinstance(model_and_weights_manifest, dict):
        raise TypeError(
            'The JSON content of %s is required to be a `dict`, but found %s' %
            (config_json_path, type(model_and_weights_manifest)))
    if 'modelTopology' not in model_and_weights_manifest:
        raise KeyError(
            'Field "modelTopology" is missing from the JSON content in %s' %
            config_json_path)

    model_json = model_and_weights_manifest['modelTopology']

    if 'model_config' in model_json:
        model_json = model_json['model_config']
    unique_name_scope = uuid.uuid4().hex if use_unique_name_scope else None
    with tf.name_scope(unique_name_scope):
        model = keras.models.model_from_json(json.dumps(model_json))

    if load_weights:
        if 'weightsManifest' not in model_and_weights_manifest:
            raise KeyError(
                'Field "weightsManifest" is missing from the JSON content in %s'
                % config_json_path)
        weights_manifest = model_and_weights_manifest['weightsManifest']

        if weights_data_buffers:
            if weights_path_prefix:
                raise ValueError(
                    'The arguments weights_data_buffers and weights_path_prefix are '
                    'mutually exclusive and should not be both specified.')
            weight_entries = read_weights.decode_weights(weights_manifest,
                                                         weights_data_buffers,
                                                         flatten=True)
        else:
            weight_names = [
                keras_h5_conversion.normalize_weight_name(
                    w.name[len(unique_name_scope) +
                           1:]) if use_unique_name_scope else
                keras_h5_conversion.normalize_weight_name(w.name[:-2])
                for w in model.weights
            ]

            if not weights_path_prefix:
                weights_path_prefix = os.path.dirname(config_json_path)
            if not os.path.isdir(weights_path_prefix):
                raise ValueError(
                    'Weights path prefix is not an existing directory: %s' %
                    weights_path_prefix)

            weight_entries = read_weights.read_weights(weights_manifest,
                                                       weights_path_prefix,
                                                       flatten=True)
        weights_dict = dict()
        for weight_entry in weight_entries:
            weights_dict[weight_entry['name']] = weight_entry['data']

        weights_list = []
        for weight_name in weight_names:
            weights_list.append(weights_dict[weight_name])
        model.set_weights(weights_list)

    return model