Ejemplo n.º 1
0
    def test_trace_multi_io_model_outputs(self):
        input_dim = 5
        num_classes = 3
        num_classes_b = 4
        input_a = keras.layers.Input(shape=(input_dim, ), name='input_a')
        input_b = keras.layers.Input(shape=(input_dim, ), name='input_b')

        dense = keras.layers.Dense(num_classes, name='dense')
        dense2 = keras.layers.Dense(num_classes_b, name='dense2')
        dropout = keras.layers.Dropout(0.5, name='dropout')
        branch_a = [input_a, dense]
        branch_b = [input_b, dense, dense2, dropout]

        model = test_utils.get_multi_io_model(branch_a, branch_b)

        input_a_ts = tf.constant(
            np.random.random((10, input_dim)).astype(np.float32))
        input_b_ts = tf.constant(
            np.random.random((10, input_dim)).astype(np.float32))

        if test_utils.get_model_type() == 'subclass':
            with self.assertRaisesRegex(ValueError,
                                        '.*input shape is not availabl*'):
                saving_utils.trace_model_call(model)

        model.compile(optimizer='sgd',
                      loss='mse',
                      run_eagerly=test_utils.should_run_eagerly())
        model.fit(x=[
            np.random.random((8, input_dim)).astype(np.float32),
            np.random.random((8, input_dim)).astype(np.float32)
        ],
                  y=[
                      np.random.random((8, num_classes)).astype(np.float32),
                      np.random.random((8, num_classes_b)).astype(np.float32)
                  ],
                  epochs=2)

        fn = saving_utils.trace_model_call(model)
        # tf.function requires that the input structures match when calling a
        # ConcreteFunction. For some reason V1 models defines the inputs as a list,
        # while V2 models sets the inputs as a tuple.
        if (not tf.executing_eagerly()
                and test_utils.get_model_type() != 'functional'):
            signature_outputs = fn([input_a_ts, input_b_ts])
        else:
            signature_outputs = fn((input_a_ts, input_b_ts))
        outputs = model([input_a_ts, input_b_ts])
        if model.output_names:
            expected_outputs = {
                model.output_names[0]: outputs[0],
                model.output_names[1]: outputs[1]
            }
        else:
            expected_outputs = {'output_1': outputs[0], 'output_2': outputs[1]}
        self._assert_all_close(expected_outputs, signature_outputs)
Ejemplo n.º 2
0
 def testBody(self, arg):
     del arg
     mode = "eager" if tf.executing_eagerly() else "graph"
     should_run_eagerly = test_utils.should_run_eagerly()
     test_cases.append(
         (mode, should_run_eagerly, test_utils.get_model_type())
     )
    def test_sparse_scipy_eval_input_dicts(self):
        # Create a model that accepts a sparse input and converts the sparse tensor
        # back to a dense tensor. Scipy sparse matrices are limited to 2D, so use
        # a one-dimensional shape; note also that scipy's default dtype is int64.
        if test_utils.get_model_type() == "subclass":
            input_name = "input_1"  # Subclass models don"t support input names.
        else:
            input_name = "test_input_name"
        model_input = input_layer.Input(shape=(3, ),
                                        sparse=True,
                                        name=input_name,
                                        dtype=tf.int64)
        layers = [ToDense(default_value=-1)]
        model = get_model_from_layers_with_input(layers,
                                                 model_input=model_input)
        model.compile(optimizer="sgd", loss="mse", metrics=["accuracy"])

        input_data = {
            input_name:
            scipy.sparse.coo_matrix(([1, 2, 3], ([0, 1, 1], [0, 0, 1])),
                                    shape=[2, 3])
        }
        expected_output = np.array([[1, -1, -1], [2, 3, -1]])
        output = model.evaluate(input_data, expected_output, steps=1)
        self.assertAllEqual(1.0, output[-1])

        input_data_2 = {
            input_name:
            scipy.sparse.coo_matrix(
                ([5, 6, 7, 8], ([0, 1, 1, 2], [0, 0, 1, 1])), shape=[3, 3])
        }
        expected_output_2 = np.array([[5, -1, -1], [6, 7, -1], [-1, 8, -1]])
        output_2 = model.evaluate(input_data_2, expected_output_2, steps=1)
        self.assertAllEqual(1.0, output_2[-1])
Ejemplo n.º 4
0
    def test_revive(self):
        input_shape = None
        if test_utils.get_model_type() == 'functional':
            input_shape = (2, 3)

        layer_with_config = CustomLayerWithConfig(1., 2)
        layer_without_config = CustomLayerNoConfig(3., 4)
        subclassed_with_config = SubclassedModelWithConfig(4., 6.)
        subclassed_without_config = SubclassedModelNoConfig(7., 8.)

        inputs = keras.Input((2, 3))
        x = CustomLayerWithConfig(1., 2)(inputs)
        x = CustomLayerNoConfig(3., 4)(x)
        x = SubclassedModelWithConfig(4., 6.)(x)
        x = SubclassedModelNoConfig(7., 8.)(x)
        inner_model_functional = keras.Model(inputs, x)

        inner_model_sequential = keras.Sequential([
            CustomLayerWithConfig(1., 2),
            CustomLayerNoConfig(3., 4),
            SubclassedModelWithConfig(4., 6.),
            SubclassedModelNoConfig(7., 8.)
        ])

        class SubclassedModel(keras.Model):
            def __init__(self):
                super().__init__()
                self.all_layers = [
                    CustomLayerWithConfig(1., 2),
                    CustomLayerNoConfig(3., 4),
                    SubclassedModelWithConfig(4., 6.),
                    SubclassedModelNoConfig(7., 8.)
                ]

            def call(self, inputs):
                x = inputs
                for layer in self.all_layers:
                    x = layer(x)
                return x

        inner_model_subclassed = SubclassedModel()

        layers = [
            layer_with_config, layer_without_config, subclassed_with_config,
            subclassed_without_config, inner_model_functional,
            inner_model_sequential, inner_model_subclassed
        ]
        model = test_utils.get_model_from_layers(layers,
                                                 input_shape=input_shape)
        # Run data through the Model to create save spec and weights.
        model.predict(np.ones((10, 2, 3)), batch_size=10)

        # Test that the correct checkpointed values are loaded, whether the layer is
        # created from the config or SavedModel.
        layer_with_config.c.assign(2 * layer_with_config.c)
        layer_without_config.c.assign(3 * layer_without_config.c)

        model.save(self.path, save_format='tf')
        revived = keras_load.load(self.path)
        self._assert_revived_correctness(model, revived)
Ejemplo n.º 5
0
    def test_sparse_scipy_predict_input_dicts_via_input_layer_args(self):
        # Create a model that accepts a sparse input and converts the sparse
        # tensor back to a dense tensor. Scipy sparse matrices are limited to
        # 2D, so use a one-dimensional shape; note also that scipy's default
        # dtype is int64.
        if test_utils.get_model_type() == "subclass":
            input_name = "input_1"  # Subclass models don"t support input names.
        else:
            input_name = "test_input_name"
        model_input = input_layer.Input(shape=(3, ),
                                        sparse=True,
                                        name=input_name,
                                        dtype=tf.int64)
        layers = [ToDense(default_value=-1)]
        model = get_model_from_layers_with_input(layers,
                                                 model_input=model_input)

        input_data = {
            input_name:
            scipy.sparse.coo_matrix(([1, 2, 3], ([0, 1, 1], [0, 0, 1])),
                                    shape=[2, 3])
        }
        expected_output = np.array([[1, -1, -1], [2, 3, -1]])
        output = model.predict(input_data, steps=1)
        self.assertAllEqual(expected_output, output)

        input_data_2 = {
            input_name:
            scipy.sparse.coo_matrix(
                ([5, 6, 7, 8], ([0, 1, 1, 2], [0, 0, 1, 1])), shape=[3, 3])
        }
        expected_output_2 = np.array([[5, -1, -1], [6, 7, -1], [-1, 8, -1]])
        output_2 = model.predict(input_data_2, steps=1)
        self.assertAllEqual(expected_output_2, output_2)
Ejemplo n.º 6
0
    def test_clone_and_build_compiled(self):
        model = _get_model()
        model.compile(test_utils.get_v2_optimizer('rmsprop'),
                      'mse',
                      metrics=['acc', metrics.categorical_accuracy],
                      run_eagerly=test_utils.should_run_eagerly())

        self._clone_and_build_test_helper(model, test_utils.get_model_type())
def get_input_name(use_dict):
    # Define the input name.
    if not use_dict:
        return None  # This is the same as not setting 'name'.
    elif test_utils.get_model_type() == "subclass":
        return "input_1"  # Subclass models don"t support input names.
    else:
        return "test_input_name"
Ejemplo n.º 8
0
 def _skip_if_strategy_unsupported(self, strategy_fn):
     if (
         strategy_fn != default_strategy_fn
         and test_utils.get_model_type() == "subclass"
     ):
         self.skipTest(
             "Non-default strategies are unsupported with subclassed "
             "models"
         )
Ejemplo n.º 9
0
 def _skip_if_save_format_unsupported(self, save_format):
     model_type = test_utils.get_model_type()
     if save_format == 'h5' and model_type == 'subclass':
         self.skipTest('Saving subclassed models with the HDF5 format is '
                       'unsupported')
     if (save_format == 'tf' and model_type == 'subclass'
             and not tf.executing_eagerly()):
         self.skipTest(
             'b/148820505: This combination of features is currently '
             'broken.')
Ejemplo n.º 10
0
 def _skip_if_save_format_unsupported(self, save_format):
     model_type = test_utils.get_model_type()
     if save_format == "h5" and model_type == "subclass":
         self.skipTest("Saving subclassed models with the HDF5 format is "
                       "unsupported")
     if (save_format == "tf" and model_type == "subclass"
             and not tf.executing_eagerly()):
         self.skipTest(
             "b/148820505: This combination of features is currently "
             "broken.")
Ejemplo n.º 11
0
    def test_load_weights_from_saved_model(self):
        save_path = self._save_model_dir()
        save_format = test_utils.get_save_format()

        if save_format == "h5" and test_utils.get_model_type() == "subclass":
            # TODO(b/173646281): HDF5 format currently does not allow saving
            # subclassed models.
            return

        with self.cached_session():
            model = test_utils.get_small_mlp(1, 4, input_dim=3)
            data = np.random.random((1, 3))
            labels = np.random.random((1, 4))
            model.compile(loss="mse", optimizer="rmsprop")
            model.fit(data, labels)
            model.save(save_path, save_format=save_format)
            new_model = test_utils.get_small_mlp(1, 4, input_dim=3)
            if test_utils.get_model_type() == "subclass":
                # Call on test data to build the model.
                new_model.predict(data)
            new_model.load_weights(save_path)
            self.assertAllClose(model.weights, new_model.weights)
Ejemplo n.º 12
0
  def test_save_and_load(self):
    saved_model_dir = self._save_model_dir()
    save_format = test_utils.get_save_format()
    save_kwargs = test_utils.get_save_kwargs()

    if ((save_format == 'h5' or not save_kwargs.get('save_traces', True)) and
        test_utils.get_model_type() == 'subclass'):
      # HDF5 format currently does not allow saving subclassed models.
      # When saving with `save_traces=False`, the subclassed model must have a
      # get_config/from_config, which the autogenerated model does not have.
      return

    with self.cached_session():
      model = test_utils.get_model_from_layers(
          [keras.layers.Dense(2),
           keras.layers.RepeatVector(3),
           keras.layers.TimeDistributed(keras.layers.Dense(3))],
          input_shape=(3,))
      model.compile(
          loss=keras.losses.MSE,
          optimizer=keras.optimizers.optimizer_v2.rmsprop.RMSprop(lr=0.0001),
          metrics=[
              keras.metrics.categorical_accuracy,
              keras.metrics.CategoricalCrossentropy(
                  name='cce', label_smoothing=tf.constant(0.2)),
          ],
          weighted_metrics=[
              keras.metrics.categorical_crossentropy,
              keras.metrics.CategoricalCrossentropy(
                  name='cce', label_smoothing=tf.constant(0.2)),
          ],
          sample_weight_mode='temporal')

      x = np.random.random((1, 3))
      y = np.random.random((1, 3, 3))
      model.train_on_batch(x, y)

      out = model.predict(x)
      keras.models.save_model(
          model, saved_model_dir, save_format=save_format,
          **save_kwargs)

      loaded_model = keras.models.load_model(saved_model_dir)
      self._assert_same_weights_and_metrics(model, loaded_model)

      out2 = loaded_model.predict(x)
      self.assertAllClose(out, out2, atol=1e-05)

      eval_out = model.evaluate(x, y)
      eval_out2 = loaded_model.evaluate(x, y)
      self.assertArrayNear(eval_out, eval_out2, 0.001)
Ejemplo n.º 13
0
    def test_training_and_eval_methods_on_multi_input_output_dataset(self):
        input_a = keras.layers.Input(shape=(3, ), name="input_1")
        input_b = keras.layers.Input(shape=(3, ), name="input_2")
        dense = keras.layers.Dense(4, name="dense")
        dropout = keras.layers.Dropout(0.5, name="dropout")
        branch_a = [input_a, dense]
        branch_b = [input_b, dense, dropout]

        model = test_utils.get_multi_io_model(branch_a, branch_b)
        model.compile(
            optimizer="rmsprop",
            loss="mse",
            run_eagerly=test_utils.should_run_eagerly(),
        )

        input_a_np = np.random.random((10, 3)).astype(dtype=np.float32)
        input_b_np = np.random.random((10, 3)).astype(dtype=np.float32)
        output_d_np = np.random.random((10, 4)).astype(dtype=np.float32)
        output_e_np = np.random.random((10, 4)).astype(dtype=np.float32)

        # Test with tuples
        dataset_tuple = tf.data.Dataset.from_tensor_slices(
            ((input_a_np, input_b_np), (output_d_np, output_e_np)))
        dataset_tuple = dataset_tuple.repeat(100)
        dataset_tuple = dataset_tuple.batch(10)

        model.fit(dataset_tuple, epochs=1, steps_per_epoch=2, verbose=1)
        model.evaluate(dataset_tuple, steps=2, verbose=1)

        # Test with dict
        input_dict = {"input_1": input_a_np, "input_2": input_b_np}
        if test_utils.get_model_type() == "subclass":
            output_dict = {"output_1": output_d_np, "output_2": output_e_np}
        else:
            output_dict = {"dense": output_d_np, "dropout": output_e_np}

        dataset_dict = tf.data.Dataset.from_tensor_slices(
            (input_dict, output_dict))
        dataset_dict = dataset_dict.repeat(100)
        dataset_dict = dataset_dict.batch(10)

        model.fit(dataset_dict, epochs=1, steps_per_epoch=2, verbose=1)
        model.evaluate(dataset_dict, steps=2, verbose=1)

        predict_dataset_dict = tf.data.Dataset.from_tensor_slices(input_dict)
        predict_dataset_dict = predict_dataset_dict.repeat(100)
        predict_dataset_dict = predict_dataset_dict.batch(10)
        model.predict(predict_dataset_dict, steps=1)
Ejemplo n.º 14
0
  def assert_optimizer_iterations_increases(self, optimizer):
    model = _get_model()
    model.compile(
        optimizer,
        'mse',
        metrics=['acc', metrics.categorical_accuracy],
        run_eagerly=test_utils.should_run_eagerly())

    global_step = keras.backend.variable(123, dtype=tf.int64)
    clone_model = models.clone_and_build_model(
        model, compile_clone=True, optimizer_iterations=global_step,
        in_place_reset=(test_utils.get_model_type() == 'subclass'))

    inp = np.random.random((10, 4))
    out = np.random.random((10, 4))
    clone_model.train_on_batch(inp, out)

    self.assertEqual(backend.eval(global_step), 124)
Ejemplo n.º 15
0
    def test_trace_model_outputs(self):
        input_dim = 5 if test_utils.get_model_type() == 'functional' else None
        model = test_utils.get_small_mlp(10, 3, input_dim)
        inputs = tf.ones((8, 5))

        if input_dim is None:
            with self.assertRaisesRegex(ValueError,
                                        '.*input shape is not availabl*'):
                saving_utils.trace_model_call(model)
            model._set_inputs(inputs)

        fn = saving_utils.trace_model_call(model)
        signature_outputs = fn(inputs)
        if model.output_names:
            expected_outputs = {model.output_names[0]: model(inputs)}
        else:
            expected_outputs = {'output_1': model(inputs)}

        self._assert_all_close(expected_outputs, signature_outputs)
Ejemplo n.º 16
0
    def test_clone_and_build_non_compiled_model(self):
        inp = np.random.random((10, 4))
        out = np.random.random((10, 4))

        model = _get_model()

        with self.assertRaisesRegex(ValueError, "has not been compiled"):
            models.clone_and_build_model(model, compile_clone=True)

        is_subclassed = test_utils.get_model_type() == "subclass"
        # With placeholder creation
        new_model = models.clone_and_build_model(
            model, compile_clone=False, in_place_reset=is_subclassed
        )
        with self.assertRaisesRegex(RuntimeError, "must compile"):
            new_model.evaluate(inp, out)
        with self.assertRaisesRegex(RuntimeError, "must compile"):
            new_model.train_on_batch(inp, out)
        new_model.compile(
            test_utils.get_v2_optimizer("rmsprop"),
            "mse",
            run_eagerly=test_utils.should_run_eagerly(),
        )
        new_model.train_on_batch(inp, out)

        # Create new tensors for inputs.
        input_a = keras.Input(shape=(4,))
        new_model = models.clone_and_build_model(
            model,
            input_tensors=input_a,
            compile_clone=False,
            in_place_reset=is_subclassed,
        )
        with self.assertRaisesRegex(RuntimeError, "must compile"):
            new_model.evaluate(inp, out)
        with self.assertRaisesRegex(RuntimeError, "must compile"):
            new_model.train_on_batch(inp, out)
        new_model.compile(
            test_utils.get_v2_optimizer("rmsprop"),
            "mse",
            run_eagerly=test_utils.should_run_eagerly(),
        )
        new_model.train_on_batch(inp, out)
Ejemplo n.º 17
0
    def test_trace_model_outputs_after_fitting(self):
        input_dim = 5 if test_utils.get_model_type() == 'functional' else None
        model = test_utils.get_small_mlp(10, 3, input_dim)
        model.compile(optimizer='sgd',
                      loss='mse',
                      run_eagerly=test_utils.should_run_eagerly())
        model.fit(x=np.random.random((8, 5)).astype(np.float32),
                  y=np.random.random((8, 3)).astype(np.float32),
                  epochs=2)

        inputs = tf.ones((8, 5))

        fn = saving_utils.trace_model_call(model)
        signature_outputs = fn(inputs)
        if model.output_names:
            expected_outputs = {model.output_names[0]: model(inputs)}
        else:
            expected_outputs = {'output_1': model(inputs)}

        self._assert_all_close(expected_outputs, signature_outputs)
Ejemplo n.º 18
0
    def test_model_save(self):
        input_dim = 5
        model = test_utils.get_small_mlp(10, 3, input_dim)
        inputs = tf.ones((8, 5))

        if test_utils.get_model_type() == 'subclass':
            model._set_inputs(inputs)

        save_dir = os.path.join(self.get_temp_dir(), 'saved_model')
        tf.saved_model.save(model, save_dir)

        if model.output_names:
            output_name = model.output_names[0]
            input_name = model.input_names[0]
        else:
            output_name = 'output_1'
            input_name = 'input_1'

        self.assertAllClose({output_name: model.predict_on_batch(inputs)},
                            _import_and_infer(save_dir,
                                              {input_name: np.ones((8, 5))}))
def get_model_from_layers_with_input(layers,
                                     input_shape=None,
                                     input_dtype=None,
                                     model_input=None):
    """Builds a model from a sequence of layers."""
    if model_input is not None and input_shape is not None:
        raise ValueError("Cannot specify a model_input and an input shape.")

    model_type = test_utils.get_model_type()
    if model_type == "subclass":
        return _SubclassModel(layers, model_input)

    if model_type == "sequential":
        model = keras.models.Sequential()
        if model_input is not None:
            model.add(model_input)
        elif input_shape is not None:
            model.add(keras.Input(shape=input_shape, dtype=input_dtype))
        for layer in layers:
            model.add(layer)
        return model

    if model_type == "functional":
        if model_input is not None:
            inputs = model_input
        else:
            if not input_shape:
                raise ValueError(
                    "Cannot create a functional model from layers with no "
                    "input shape.")
            inputs = keras.Input(shape=input_shape, dtype=input_dtype)
        outputs = inputs
        for layer in layers:
            outputs = layer(outputs)
        return keras.Model(inputs, outputs)

    raise ValueError("Unknown model type {}".format(model_type))
Ejemplo n.º 20
0
 def testBody(self):
     mode = "eager" if tf.executing_eagerly() else "graph"
     should_run_eagerly = test_utils.should_run_eagerly()
     l.append(
         (mode, should_run_eagerly, test_utils.get_model_type()))
Ejemplo n.º 21
0
 def testBody(self):
     model_types.append(test_utils.get_model_type())
     models.append(test_utils.get_small_mlp(1, 4, input_dim=3))
Ejemplo n.º 22
0
 def testBody(self, with_brackets):
     with_brackets = ("with_brackets"
                      if with_brackets else "without_brackets")
     model_types.append(
         (with_brackets, test_utils.get_model_type()))
     models.append(test_utils.get_small_mlp(1, 4, input_dim=3))