def _skip_if_strategy_unsupported(self, strategy_fn, check_model_type=False): if (strategy_fn != default_strategy_fn and (testing_utils.should_run_eagerly() or (check_model_type and testing_utils.get_model_type() == 'subclass'))): self.skipTest('Non-default strategies are unsupported with subclassed ' 'models or with passing run_eagerly=True to ' 'Model.compile()')
def test_layer_tracking(self): with self.cached_session(): model = _get_model(input_shape=(4, )) if testing_utils.get_model_type() == 'subclass': # Subclassed model must be built separately. model._set_inputs(tensor_spec.TensorSpec((None, 4))) # Ensure that checkpoints are compatible with another model with the same # layers, even if the model isn't built until after initialization. layers = _get_layers(input_shape=None, add_input_layer=False) model2 = models.Sequential(layers) # Build model by calling it. model2.predict_on_batch(np.random.random((10, 4))) model_path = os.path.join(self.get_temp_dir(), 'model_ckpt') model.save_weights(model_path) model2_path = os.path.join(self.get_temp_dir(), 'model2_ckpt') model2.save_weights(model2_path) # Check that the checkpoints are compatible with both models. model.load_weights(model2_path) self.assertAllClose(self.evaluate(model.weights), self.evaluate(model2.weights)) model.load_weights(model_path) model2.load_weights(model_path) self.assertAllClose(self.evaluate(model.weights), self.evaluate(model2.weights))
def test_sparse_tensor_dataset_dict_predict_inputs_via_input_layer_args(self): # Create a model that accepts a sparse input and converts the sparse tensor # back to a dense tensor. if testing_utils.get_model_type() == "subclass": input_name = "input_1" # Subclass models don"t support custom input names else: input_name = "test_input_name" model_input = input_layer.Input( shape=(1, None), sparse=True, name=input_name) layers = [ToDense(default_value=-1)] model = get_model_from_layers_with_input(layers, model_input=model_input) # Define some input data. input_data = dataset_ops.Dataset.from_tensors({ input_name: sparse_tensor.SparseTensor([[0, 0, 0], [1, 0, 0], [1, 0, 1]], [1, 2, 3], [2, 1, 3]) }) expected_output = np.array([[[1, -1, -1]], [[2, 3, -1]]]) output = model.predict(input_data) self.assertAllEqual(expected_output, output) input_data_2 = dataset_ops.Dataset.from_tensors({ input_name: sparse_tensor.SparseTensor( [[0, 0, 0], [1, 0, 0], [1, 0, 1], [2, 0, 1]], [5, 6, 7, 8], [3, 1, 4]) }) expected_output_2 = np.array([[[5, -1, -1, -1]], [[6, 7, -1, -1]], [[-1, 8, -1, -1]]]) output_2 = model.predict(input_data_2) self.assertAllEqual(expected_output_2, output_2)
def test_revive(self): input_shape = None if testing_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(SubclassedModel, self).__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 = testing_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)
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. if testing_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) 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)
def test_calling_model_on_same_dataset(self): if ((not testing_utils.should_run_eagerly()) and testing_utils.get_model_type() == 'subclass' and context.executing_eagerly()): self.skipTest('b/120673224') model = testing_utils.get_small_mlp(1, 4, input_dim=3) optimizer = RMSPropOptimizer(learning_rate=0.001) loss = 'mse' metrics = ['mae'] model.compile(optimizer, loss, metrics=metrics, run_eagerly=testing_utils.should_run_eagerly()) inputs = np.zeros((10, 3), np.float32) targets = np.zeros((10, 4), np.float32) dataset = dataset_ops.Dataset.from_tensor_slices((inputs, targets)) dataset = dataset.repeat(100) dataset = dataset.batch(10) # Call fit with validation data model.fit(dataset, epochs=1, steps_per_epoch=2, verbose=0, validation_data=dataset, validation_steps=2) model.fit(dataset, epochs=1, steps_per_epoch=2, verbose=0, validation_data=dataset, validation_steps=2)
def test_sparse_tensor_eval_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. if testing_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=(1, None), sparse=True, name=input_name) 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"]) # Define some input data. input_data = { input_name: sparse_tensor.SparseTensor([[0, 0, 0], [1, 0, 0], [1, 0, 1]], [1, 2, 3], [2, 1, 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: sparse_tensor.SparseTensor( [[0, 0, 0], [1, 0, 0], [1, 0, 1], [2, 0, 1]], [5, 6, 7, 8], [3, 1, 4]) } expected_output_2 = np.array([[[5, -1, -1, -1]], [[6, 7, -1, -1]], [[-1, 8, -1, -1]]]) output_2 = model.evaluate(input_data_2, expected_output_2, steps=1) self.assertAllEqual(1.0, output_2[-1])
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 testing_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=dtypes.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])
def test_TensorBoard_weight_histograms(self): model = self._get_model() x, y = np.ones((10, 10, 10, 1)), np.ones((10, 1)) tb_cbk = keras.callbacks.TensorBoard(self.logdir, histogram_freq=1) model_type = testing_utils.get_model_type() model.fit( x, y, batch_size=2, epochs=2, validation_data=(x, y), callbacks=[tb_cbk]) summary_file = list_summaries(self.logdir) self.assertEqual( summary_file.scalars, { _ObservedSummary(logdir=self.train_dir, tag='epoch_loss'), _ObservedSummary(logdir=self.validation_dir, tag='epoch_loss'), }, ) self.assertEqual( self._strip_layer_names(summary_file.histograms, model_type), { _ObservedSummary(logdir=self.train_dir, tag='bias_0'), _ObservedSummary(logdir=self.train_dir, tag='kernel_0'), }, )
def test_training_and_eval_methods_on_multi_input_output_dataset(self): if testing_utils.should_run_distributed(): self.skipTest('b/137397816') 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 = testing_utils.get_multi_io_model(branch_a, branch_b) model.compile( optimizer='rmsprop', loss='mse', run_eagerly=testing_utils.should_run_eagerly(), run_distributed=testing_utils.should_run_distributed()) 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 = dataset_ops.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) predict_dataset_tuple = dataset_ops.Dataset.from_tensor_slices( (input_a_np, input_b_np)) # TODO(b/123360757): Remove below assertion once predict() supports # muti-input datasets. with self.assertRaisesRegexp(ValueError, 'Error when checking model input'): model.predict(predict_dataset_tuple, steps=1) # Test with dict input_dict = {'input_1': input_a_np, 'input_2': input_b_np} if testing_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 = dataset_ops.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 = dataset_ops.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)
def test_clone_and_build_compiled(self): model = _get_model() model.compile( testing_utils.get_v2_optimizer('rmsprop'), 'mse', metrics=['acc', metrics.categorical_accuracy], run_eagerly=testing_utils.should_run_eagerly()) self._clone_and_build_test_helper(model, testing_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 testing_utils.get_model_type() == "subclass": return "input_1" # Subclass models don"t support input names. else: return "test_input_name"
def test_clone_and_build_compiled(self): model = _get_model() model.compile( testing_utils.get_v2_optimizer('rmsprop'), 'mse', metrics=['acc', metrics.categorical_accuracy], run_eagerly=testing_utils.should_run_eagerly()) self._clone_and_build_test_helper(model, testing_utils.get_model_type())
def test_model(self, strategy_fn, use_operator=False, use_regularizer=False, policy_name='mixed_float16', experimental_run_tf_function=True): if not self._is_strategy_supported(strategy_fn, check_model_type=True): return regularizer = IdentityRegularizer() if use_regularizer else None with strategy_fn().scope(): # Pass loss_scale=None, as this test will fail if the DynamicLossScale # skips applying gradients for a step with policy.policy_scope( policy.Policy(policy_name, loss_scale=None)): layer_list = [] if testing_utils.get_model_type() == 'subclass': # Subclassed models do not have an Input layer, so the model does not # cast inputs to the Input layer's dtype. Therefore, we need to # manually insert a float16 cast. cast_f16_layer = layers.Lambda( lambda x: math_ops.cast(x, 'float16'), input_shape=(1, )) layer_list.append(cast_f16_layer) layer = AddLayer(assert_type=dtypes.float16, use_operator=use_operator, regularizer=regularizer, input_shape=(1, )) cast_f32_layer = layers.Lambda( lambda x: math_ops.cast(x, 'float32')) layer_list += [layer, cast_f32_layer] model = testing_utils.get_model_from_layers( layer_list, input_shape=(1, ), input_dtype=dtypes.float16) def loss_fn(y_true, y_pred): del y_true return math_ops.reduce_mean(y_pred) # Learning rate is small enough that if applied to a float16 variable, # the variable will not change. So this tests the learning rate not # applied to a float16 value, but instead the float32 variable. opt = gradient_descent.SGD(2**-14) model.compile(opt, loss=loss_fn, run_eagerly=testing_utils.should_run_eagerly(), experimental_run_tf_function=testing_utils. should_run_tf_function()) x = np.ones((2, 1)) y = np.ones((2, 1)) dataset = dataset_ops.Dataset.from_tensor_slices((x, y)).batch(2) model.fit(dataset) # Variable starts at 1, and should have gradient of 2 ** -14 subtracted # from it. expected = 1 - 2**-14 if use_regularizer: # Regularizer adds another 2 ** -14 to the gradient. expected -= 2**-14 self.assertEqual(backend.eval(layer.v), expected)
def _is_strategy_supported(self, strategy_fn, check_model_type=False): if (strategy_fn != default_strategy_fn and (testing_utils.should_run_eagerly() or (check_model_type and testing_utils.get_model_type() == 'subclass'))): # Distribution strategies do not support subclassed models or running with # `run_eagerly=True`. return False else: return True
def _skip_if_save_format_unsupported(self, save_format): model_type = testing_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 context.executing_eagerly()): self.skipTest('b/148820505: This combination of features is currently ' 'broken.')
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 = testing_utils.get_multi_io_model(branch_a, branch_b) model.compile( optimizer='rmsprop', loss='mse', run_eagerly=testing_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 = dataset_ops.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) predict_dataset_tuple = dataset_ops.Dataset.from_tensor_slices( (input_a_np, input_b_np)) # TODO(b/123360757): Remove below assertion once predict() supports # muti-input datasets. with self.assertRaisesRegexp(ValueError, 'Error when checking model input'): model.predict(predict_dataset_tuple, steps=1) # Test with dict input_dict = {'input_1': input_a_np, 'input_2': input_b_np} if testing_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 = dataset_ops.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 = dataset_ops.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)
def test_save_and_load(self): saved_model_dir = self._save_model_dir() save_format = testing_utils.get_save_format() save_kwargs = testing_utils.get_save_kwargs() if ((save_format == 'h5' or not save_kwargs.get('save_traces', True)) and testing_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 = testing_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.optimizer_v2.rmsprop.RMSprop(lr=0.0001), metrics=[ keras.metrics.categorical_accuracy, keras.metrics.CategoricalCrossentropy( name='cce', label_smoothing=constant_op.constant(0.2)), ], weighted_metrics=[ keras.metrics.categorical_crossentropy, keras.metrics.CategoricalCrossentropy( name='cce', label_smoothing=constant_op.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)
def test_dynamic_layer(self): if testing_utils.get_model_type() == 'sequential': # TODO(scottzhu): Reenable this once sequential is moved to frozen_keras. self.skipTest( 'Sequential model will check layer instance type and fail.') model = testing_utils.get_model_from_layers( [DynamicLayer(dynamic=True)], input_shape=(3, )) self.assertEqual(model.dynamic, True) model.compile(rmsprop.RMSprop(0.001), loss='mse') self.assertEqual(model.run_eagerly, True) model.train_on_batch(np.random.random((2, 3)), np.random.random( (2, 3)))
def test_dynamic_layer_error(self): if testing_utils.get_model_type() == 'sequential': # TODO(scottzhu): Reenable this once sequential is moved to frozen_keras. self.skipTest( 'Sequential model will check layer instance type and fail.') with self.assertRaisesRegexp(TypeError, 'attempting to use Python control flow'): model = testing_utils.get_model_from_layers([DynamicLayer()], input_shape=(3, )) model.compile(rmsprop.RMSprop(0.001), loss='mse') model.train_on_batch(np.random.random((2, 3)), np.random.random((2, 3)))
def test_load_weights_from_saved_model(self): save_path = self._save_model_dir() save_format = testing_utils.get_save_format() if save_format == 'h5' and testing_utils.get_model_type() == 'subclass': # TODO(b/173646281): HDF5 format currently does not allow saving # subclassed models. return with self.cached_session(): model = testing_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 = testing_utils.get_small_mlp(1, 4, input_dim=3) if testing_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)
def test_dynamic_layer_error_running_in_graph_mode(self): if testing_utils.get_model_type() == 'sequential': # TODO(scottzhu): Reenable this once sequential is moved to frozen_keras. self.skipTest( 'Sequential model will check layer instance type and fail.') with ops.get_default_graph().as_default(): model = testing_utils.get_model_from_layers( [DynamicLayer(dynamic=True)], input_shape=(3, )) self.assertEqual(model.dynamic, True) # But then you cannot run the model since you're in a graph scope. with self.assertRaisesRegexp(ValueError, 'You must enable eager execution'): model.compile(rmsprop.RMSprop(0.001), loss='mse')
def test_trace_model_outputs_after_fitting(self): input_dim = 5 if testing_utils.get_model_type() == 'functional' else None model = testing_utils.get_small_mlp(10, 3, input_dim) model.compile(optimizer='sgd', loss='mse') model.fit(x=np.random.random((8, 5)), y=np.random.random((8, 3)), epochs=2) inputs = array_ops.ones((8, 5)) fn = saving_utils.trace_model_call(model) signature_outputs = fn(inputs) expected_outputs = {model.output_names[0]: model(inputs)} self._assert_all_close(expected_outputs, signature_outputs)
def test_model_save(self): input_dim = 5 model = testing_utils.get_small_mlp(10, 3, input_dim) inputs = array_ops.ones((8, 5)) if testing_utils.get_model_type() == 'subclass': model._set_inputs(inputs) save_dir = os.path.join(self.get_temp_dir(), 'saved_model') save_lib.save(model, save_dir) self.assertAllClose( {model.output_names[0]: model.predict_on_batch(inputs)}, _import_and_infer(save_dir, {model.input_names[0]: np.ones((8, 5))}))
def test_model_save(self): input_dim = 5 model = testing_utils.get_small_mlp(10, 3, input_dim) inputs = array_ops.ones((8, 5)) if testing_utils.get_model_type() == 'subclass': model._set_inputs(inputs) save_dir = os.path.join(self.get_temp_dir(), 'saved_model') save_lib.save(model, save_dir) self.assertAllClose( {model.output_names[0]: model.predict_on_batch(inputs)}, _import_and_infer(save_dir, {model.input_names[0]: np.ones((8, 5))}))
def test_trace_model_outputs_after_fitting(self): input_dim = 5 if testing_utils.get_model_type() == 'functional' else None model = testing_utils.get_small_mlp(10, 3, input_dim) model.compile(optimizer='sgd', loss='mse') model.fit(x=np.random.random((8, 5)), y=np.random.random((8, 3)), epochs=2) inputs = array_ops.ones((8, 5)) fn = saving_utils.trace_model_call(model) signature_outputs = fn(inputs) expected_outputs = {model.output_names[0]: model(inputs)} self._assert_all_close(expected_outputs, signature_outputs)
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 = testing_utils.get_multi_io_model(branch_a, branch_b) model.compile( optimizer='rmsprop', loss='mse', run_eagerly=testing_utils.should_run_eagerly(), experimental_run_tf_function=testing_utils.should_run_tf_function()) 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 = dataset_ops.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 testing_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 = dataset_ops.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 = dataset_ops.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)
def assert_optimizer_iterations_increases(self, optimizer): model = _get_model() model.compile( optimizer, 'mse', metrics=['acc', metrics.categorical_accuracy], run_eagerly=testing_utils.should_run_eagerly()) global_step = keras.backend.variable(123, dtype=dtypes.int64) clone_model = models.clone_and_build_model( model, compile_clone=True, optimizer_iterations=global_step, in_place_reset=(testing_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(K.eval(global_step), 124)
def assert_optimizer_iterations_increases(self, optimizer): model = _get_model() model.compile( optimizer, 'mse', metrics=['acc', metrics.categorical_accuracy], run_eagerly=testing_utils.should_run_eagerly()) global_step = keras.backend.variable(123, dtype=dtypes.int64) clone_model = models.clone_and_build_model( model, compile_clone=True, optimizer_iterations=global_step, in_place_reset=(testing_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(K.eval(global_step), 124)
def test_trace_model_outputs(self): input_dim = 5 if testing_utils.get_model_type() == 'functional' else None model = testing_utils.get_small_mlp(10, 3, input_dim) inputs = array_ops.ones((8, 5)) if input_dim is None: with self.assertRaisesRegexp(ValueError, 'input shapes have not been set'): saving_utils.trace_model_call(model) model._set_inputs(inputs) fn = saving_utils.trace_model_call(model) signature_outputs = fn(inputs) expected_outputs = {model.output_names[0]: model(inputs)} self._assert_all_close(expected_outputs, signature_outputs)
def test_trace_model_outputs(self): input_dim = 5 if testing_utils.get_model_type() == 'functional' else None model = testing_utils.get_small_mlp(10, 3, input_dim) inputs = array_ops.ones((8, 5)) if input_dim is None: with self.assertRaisesRegexp(ValueError, 'input shapes have not been set'): saving_utils.trace_model_call(model) model._set_inputs(inputs) fn = saving_utils.trace_model_call(model) signature_outputs = fn(inputs) expected_outputs = {model.output_names[0]: model(inputs)} self._assert_all_close(expected_outputs, signature_outputs)
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 = testing_utils.get_multi_io_model(branch_a, branch_b) input_a_np = np.random.random((10, input_dim)).astype(np.float32) input_b_np = np.random.random((10, input_dim)).astype(np.float32) if testing_utils.get_model_type() == 'subclass': with self.assertRaisesRegexp(ValueError, 'input shapes have not been set'): saving_utils.trace_model_call(model) model.compile(optimizer='sgd', loss='mse', run_eagerly=testing_utils.should_run_eagerly(), experimental_run_tf_function=testing_utils. should_run_tf_function()) 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) signature_outputs = fn([input_a_np, input_b_np]) outputs = model([input_a_np, input_b_np]) expected_outputs = { model.output_names[0]: outputs[0], model.output_names[1]: outputs[1] } self._assert_all_close(expected_outputs, signature_outputs)
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.assertRaisesRegexp(ValueError, 'has not been compiled'): models.clone_and_build_model(model, compile_clone=True) is_subclassed = (testing_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.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.evaluate(inp, out) with self.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.train_on_batch(inp, out) new_model.compile( testing_utils.get_v2_optimizer('rmsprop'), 'mse', run_eagerly=testing_utils.should_run_eagerly(), run_distributed=testing_utils.should_run_distributed()) new_model.train_on_batch(inp, out) # Create new tensors for inputs and targets input_a = keras.Input(shape=(4, )) target_a = keras.Input(shape=(4, )) new_model = models.clone_and_build_model(model, input_tensors=input_a, target_tensors=[target_a], compile_clone=False, in_place_reset=is_subclassed) with self.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.evaluate(inp, out) with self.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.train_on_batch(inp, out) new_model.compile( testing_utils.get_v2_optimizer('rmsprop'), 'mse', run_eagerly=testing_utils.should_run_eagerly(), run_distributed=testing_utils.should_run_distributed()) new_model.train_on_batch(inp, out)
def _testAddUpdate(self, scope): with scope: layer_with_update = LayerWithUpdate() model = testing_utils.get_model_from_layers([layer_with_update], input_shape=(3, )) x = np.ones((10, 3)) if testing_utils.get_model_type() == 'subclass': model.predict(x, batch_size=10) self.evaluate(variables.variables_initializer(model.variables)) saved_model_dir = self._save_model_dir() model.save(saved_model_dir, save_format='tf') loaded = keras_load.load(saved_model_dir) loaded_layer = loaded.layers[-1] self.evaluate(variables.variables_initializer(loaded.variables)) self.assertEqual(self.evaluate(loaded_layer.v), 0.) loaded.compile('sgd', 'mse') loaded.fit(x, x, batch_size=10) self.assertEqual(self.evaluate(loaded_layer.v), 1.)
def _testAddUpdate(self, scope): with scope: layer_with_update = LayerWithUpdate(dtype=dtypes.int32) model = testing_utils.get_model_from_layers([layer_with_update], input_shape=(3,), input_dtype=dtypes.int32) if testing_utils.get_model_type() == 'subclass': model._set_inputs(constant_op.constant([[1, 2, 3]], dtype=dtypes.int32)) self.evaluate(variables.variables_initializer(model.variables)) saved_model_dir = self._save_model_dir() model.save(saved_model_dir, save_format='tf') loaded = keras_load.load(saved_model_dir) loaded_layer = loaded.layers[-1] self.evaluate(variables.variables_initializer(loaded.variables)) self.assertEqual(self.evaluate(loaded_layer.v), 0) loaded.predict(constant_op.constant([[1, 2, 3]], dtype=dtypes.int32), steps=1) self.assertEqual(self.evaluate(loaded_layer.v), 6)
def test_standard_loader(self): model = testing_utils.get_small_mlp(1, 4, input_dim=3) model.activity_regularizer = regularizers.get('l2') def eager_loss(): return math_ops.reduce_sum(model.weights[0]) model.add_loss(eager_loss) # Call predict to ensure that all layers are built and inputs are set. model.predict(np.random.random((1, 3))) saved_model_dir = self._save_model_dir() tf_save.save(model, saved_model_dir) loaded = tf_load.load(saved_model_dir) self.evaluate(variables.variables_initializer(loaded.variables)) all_close = [ 'variables', 'trainable_variables', 'non_trainable_variables' ] for attr in all_close: self.assertAllClose(self.evaluate(getattr(model, attr)), self.evaluate(getattr(loaded.keras_api, attr))) self.assertLen(loaded.regularization_losses, 1) expected_layers = len(model.layers) if testing_utils.get_model_type() == 'sequential': # The autogenerated Input layer is hidden in the model.layers list, # but included in the loaded sub-layers. expected_layers += 1 self.assertEqual(expected_layers, len(loaded.keras_api.layers)) input_arr = array_ops.ones((4, 3)) training_bool = constant_op.constant(False) if model._expects_training_arg: call_args = [input_arr, training_bool] else: call_args = [input_arr] self.assertAllClose(self.evaluate(model(input_arr)), self.evaluate(loaded(*call_args)))
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 = testing_utils.get_multi_io_model(branch_a, branch_b) input_a_np = np.random.random((10, input_dim)).astype(np.float32) input_b_np = np.random.random((10, input_dim)).astype(np.float32) if testing_utils.get_model_type() == 'subclass': with self.assertRaisesRegexp(ValueError, 'input shapes have not been set'): saving_utils.trace_model_call(model) model.compile(optimizer='sgd', loss='mse') 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) signature_outputs = fn([input_a_np, input_b_np]) outputs = model([input_a_np, input_b_np]) expected_outputs = {model.output_names[0]: outputs[0], model.output_names[1]: outputs[1]} self._assert_all_close(expected_outputs, signature_outputs)
def test_calling_model_on_same_dataset(self): if ((not testing_utils.should_run_eagerly()) and testing_utils.get_model_type() == 'subclass' and context.executing_eagerly()): self.skipTest('b/120673224') model = testing_utils.get_small_mlp(1, 4, input_dim=3) optimizer = 'rmsprop' loss = 'mse' metrics = ['mae'] model.compile(optimizer, loss, metrics=metrics, run_eagerly=testing_utils.should_run_eagerly()) inputs = np.zeros((10, 3), np.float32) targets = np.zeros((10, 4), np.float32) dataset = dataset_ops.Dataset.from_tensor_slices((inputs, targets)) dataset = dataset.repeat(100) dataset = dataset.batch(10) # Call fit with validation data model.fit(dataset, epochs=1, steps_per_epoch=2, verbose=0, validation_data=dataset, validation_steps=2) model.fit(dataset, epochs=1, steps_per_epoch=2, verbose=0, validation_data=dataset, validation_steps=2)
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.assertRaisesRegexp(ValueError, 'has not been compiled'): models.clone_and_build_model(model, compile_clone=True) is_subclassed = (testing_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.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.evaluate(inp, out) with self.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.train_on_batch(inp, out) new_model.compile( testing_utils.get_v2_optimizer('rmsprop'), 'mse', run_eagerly=testing_utils.should_run_eagerly()) new_model.train_on_batch(inp, out) # Create new tensors for inputs and targets input_a = keras.Input(shape=(4,)) target_a = keras.Input(shape=(4,)) new_model = models.clone_and_build_model( model, input_tensors=input_a, target_tensors=[target_a], compile_clone=False, in_place_reset=is_subclassed) with self.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.evaluate(inp, out) with self.assertRaisesRegexp(RuntimeError, 'must compile'): new_model.train_on_batch(inp, out) new_model.compile( testing_utils.get_v2_optimizer('rmsprop'), 'mse', run_eagerly=testing_utils.should_run_eagerly()) new_model.train_on_batch(inp, out)
def testBody(self): mode = "eager" if context.executing_eagerly() else "graph" should_run_eagerly = testing_utils.should_run_eagerly() l.append((mode, should_run_eagerly, testing_utils.get_model_type()))
def testBody(self): model_types.append(testing_utils.get_model_type()) models.append(testing_utils.get_small_mlp(1, 4, input_dim=3))
def testBody(self, with_brackets): with_brackets = "with_brackets" if with_brackets else "without_brackets" model_types.append((with_brackets, testing_utils.get_model_type())) models.append(testing_utils.get_small_mlp(1, 4, input_dim=3))