1# Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Tests for training routines.""" 16 17import collections 18import io 19import sys 20 21from absl.testing import parameterized 22import numpy as np 23 24from tensorflow.python.data.ops import dataset_ops 25from tensorflow.python.eager import context 26from tensorflow.python.eager import def_function 27from tensorflow.python.framework import ops 28from tensorflow.python.framework import tensor_shape 29from tensorflow.python.framework import test_util as tf_test_util 30from tensorflow.python.keras import backend 31from tensorflow.python.keras import combinations 32from tensorflow.python.keras import keras_parameterized 33from tensorflow.python.keras import layers as layers_module 34from tensorflow.python.keras import losses 35from tensorflow.python.keras import metrics as metrics_module 36from tensorflow.python.keras import optimizer_v2 37from tensorflow.python.keras import testing_utils 38from tensorflow.python.keras.callbacks import Callback 39from tensorflow.python.keras.engine import input_layer 40from tensorflow.python.keras.engine import sequential 41from tensorflow.python.keras.engine import training as training_module 42from tensorflow.python.keras.engine import training_utils_v1 43from tensorflow.python.keras.utils import data_utils 44from tensorflow.python.keras.utils import np_utils 45from tensorflow.python.ops import array_ops 46from tensorflow.python.ops import init_ops 47from tensorflow.python.ops import math_ops 48from tensorflow.python.ops import nn_ops 49from tensorflow.python.ops import sparse_ops 50from tensorflow.python.ops import state_ops 51from tensorflow.python.ops import template 52from tensorflow.python.ops import variable_scope 53from tensorflow.python.ops import variables as variables_module 54from tensorflow.python.platform import test 55from tensorflow.python.platform import tf_logging as logging 56from tensorflow.python.training.rmsprop import RMSPropOptimizer 57 58try: 59 import scipy.sparse as scipy_sparse # pylint: disable=g-import-not-at-top 60except ImportError: 61 scipy_sparse = None 62 63 64class TrainingTest(keras_parameterized.TestCase): 65 66 @keras_parameterized.run_all_keras_modes 67 @keras_parameterized.run_with_all_model_types 68 def test_model_instrumentation(self): 69 layers = [ 70 layers_module.Dense(10, dtype=np.float64), 71 layers_module.Dense(10, dtype=np.float64) 72 ] 73 model = testing_utils.get_model_from_layers(layers, input_shape=(1,)) 74 75 self.assertTrue(model._instrumented_keras_api) 76 self.assertTrue(model._instrumented_keras_model_class) 77 self.assertFalse(model._instrumented_keras_layer_class) 78 79 @keras_parameterized.run_with_all_model_types 80 @keras_parameterized.run_all_keras_modes 81 def test_fit_training_arg(self): 82 83 class ReturnTraining(layers_module.Layer): 84 85 def call(self, inputs, training): 86 if training: 87 return inputs + array_ops.constant([100], 'float32') 88 else: 89 return inputs + array_ops.constant([0], 'float32') 90 91 model = sequential.Sequential([ReturnTraining()]) 92 model.compile( 93 'sgd', 94 'mse', 95 run_eagerly=testing_utils.should_run_eagerly()) 96 hist = model.fit(x=np.array([0.]), y=np.array([0.])) 97 self.assertAllClose(hist.history['loss'][0], 10000) 98 99 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 100 def test_fit_on_empty(self): 101 model = sequential.Sequential([layers_module.Dense(1)]) 102 model.compile('sgd', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 103 with self.assertRaisesRegex(ValueError, 104 'Expect x to be a non-empty array or dataset.'): 105 model.fit(x=np.array([]), y=np.array([])) 106 107 @keras_parameterized.run_all_keras_modes 108 def test_run_eagerly_setting(self): 109 model = sequential.Sequential([layers_module.Dense(1)]) 110 run_eagerly = testing_utils.should_run_eagerly() 111 model.compile('sgd', 'mse', run_eagerly=run_eagerly) 112 self.assertEqual(model.run_eagerly, run_eagerly) 113 114 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 115 @parameterized.named_parameters( 116 ('train_on_batch', 'train_on_batch'), 117 ('test_on_batch', 'test_on_batch'), 118 ('predict_on_batch', 'predict_on_batch'), 119 ('fit', 'fit'), 120 ('evaluate', 'evaluate'), 121 ('predict', 'predict'), 122 ) 123 def test_disallow_methods_inside_tf_function(self, method_name): 124 model = sequential.Sequential([layers_module.Dense(1)]) 125 run_eagerly = testing_utils.should_run_eagerly() 126 model.compile('sgd', 'mse', run_eagerly=run_eagerly) 127 128 @def_function.function 129 def my_fn(): 130 getattr(model, method_name)(1) 131 132 error_msg = 'inside a `tf.function`' 133 with self.assertRaisesRegex(RuntimeError, error_msg): 134 my_fn() 135 136 @keras_parameterized.run_all_keras_modes 137 def test_fit_and_validate_learning_phase(self): 138 139 class ReturnTraining(layers_module.Layer): 140 141 def call(self, inputs): 142 return backend.in_train_phase(lambda: array_ops.ones_like(inputs), 143 lambda: array_ops.zeros_like(inputs)) 144 145 model = sequential.Sequential([ReturnTraining(input_shape=(2,))]) 146 model.compile( 147 'sgd', 148 loss='mae', 149 run_eagerly=testing_utils.should_run_eagerly()) 150 151 inputs = np.ones((40, 2), dtype=np.float32) 152 targets = np.ones((40, 1), dtype=np.float32) 153 154 # Test correctness with `steps_per_epoch`. 155 train_dataset = dataset_ops.Dataset.from_tensor_slices( 156 (inputs, targets)).batch(10) 157 val_dataset = dataset_ops.Dataset.from_tensor_slices( 158 (inputs, targets)).batch(10) 159 history = model.fit( 160 train_dataset, epochs=2, verbose=1, validation_data=val_dataset) 161 162 # The training loss should be 0.0 163 self.assertAllClose(history.history['loss'][0], 0.0) 164 # The validation loss should be 1.0. 165 self.assertAllClose(history.history['val_loss'][0], 1.0) 166 167 @keras_parameterized.run_all_keras_modes 168 def test_fit_and_validate_training_arg(self): 169 170 class ReturnTraining(layers_module.Layer): 171 172 def call(self, inputs, training=None): 173 return backend.in_train_phase( 174 lambda: array_ops.ones_like(inputs), 175 lambda: array_ops.zeros_like(inputs), 176 training=training) 177 178 model = sequential.Sequential([ReturnTraining(input_shape=(2,))]) 179 model.compile( 180 'sgd', 181 loss='mae', 182 run_eagerly=testing_utils.should_run_eagerly()) 183 184 inputs = np.ones((40, 2), dtype=np.float32) 185 targets = np.ones((40, 1), dtype=np.float32) 186 187 # Test correctness with `steps_per_epoch`. 188 train_dataset = dataset_ops.Dataset.from_tensor_slices( 189 (inputs, targets)).batch(10) 190 val_dataset = dataset_ops.Dataset.from_tensor_slices( 191 (inputs, targets)).batch(10) 192 history = model.fit( 193 train_dataset, epochs=2, verbose=1, validation_data=val_dataset) 194 195 # The training loss should be 0.0 196 self.assertAllClose(history.history['loss'][0], 0.0) 197 # The validation loss should be 1.0. 198 self.assertAllClose(history.history['val_loss'][0], 1.0) 199 200 @keras_parameterized.run_all_keras_modes 201 @keras_parameterized.run_with_all_model_types 202 def test_target_dtype_matches_output(self): 203 204 def loss_fn(labels, preds): 205 self.assertEqual(labels.dtype, preds.dtype) 206 return labels - preds 207 208 layers = [ 209 layers_module.Dense(10, dtype=np.float64), 210 layers_module.Dense(10, dtype=np.float64) 211 ] 212 model = testing_utils.get_model_from_layers(layers, input_shape=(1,)) 213 inputs = np.ones(10, dtype=np.float64) 214 targets = np.ones(10, dtype=np.float64) 215 model.compile( 216 'sgd', 217 loss=loss_fn, 218 run_eagerly=testing_utils.should_run_eagerly()) 219 model.train_on_batch(inputs, targets) 220 model.test_on_batch(inputs, targets) 221 self.assertEqual(model.predict(inputs).dtype, np.float64) 222 223 @keras_parameterized.run_all_keras_modes 224 def test_fit_and_validate_nested_training_arg(self): 225 226 class NestedReturnTraining(layers_module.Layer): 227 228 def call(self, inputs, training=None): 229 return backend.in_train_phase( 230 lambda: array_ops.ones_like(inputs), 231 lambda: array_ops.zeros_like(inputs), 232 training=training) 233 234 class ReturnTraining(layers_module.Layer): 235 236 def __init__(self, input_shape=None, **kwargs): 237 super(ReturnTraining, self).__init__(input_shape=input_shape, **kwargs) 238 self._nested_layer = None 239 240 def build(self, input_shape): 241 self._nested_layer = NestedReturnTraining() 242 self.built = True 243 244 def call(self, inputs): 245 return self._nested_layer(inputs) 246 247 model = sequential.Sequential([ReturnTraining(input_shape=(2,))]) 248 model.compile( 249 'sgd', 250 loss='mae', 251 run_eagerly=testing_utils.should_run_eagerly()) 252 253 inputs = np.ones((40, 2), dtype=np.float32) 254 targets = np.ones((40, 1), dtype=np.float32) 255 256 # Test correctness with `steps_per_epoch`. 257 train_dataset = dataset_ops.Dataset.from_tensor_slices( 258 (inputs, targets)).batch(10) 259 val_dataset = dataset_ops.Dataset.from_tensor_slices( 260 (inputs, targets)).batch(10) 261 history = model.fit( 262 train_dataset, epochs=2, verbose=1, validation_data=val_dataset) 263 264 # The training loss should be 0.0 265 self.assertAllClose(history.history['loss'][0], 0.0) 266 # The validation loss should be 1.0. 267 self.assertAllClose(history.history['val_loss'][0], 1.0) 268 269 @keras_parameterized.run_with_all_model_types(exclude_models='sequential') 270 @keras_parameterized.run_all_keras_modes 271 def test_fit_on_arrays(self): 272 input_a = layers_module.Input(shape=(3,), name='input_a') 273 input_b = layers_module.Input(shape=(3,), name='input_b') 274 275 dense = layers_module.Dense(4, name='dense') 276 dropout = layers_module.Dropout(0.5, name='dropout') 277 branch_a = [input_a, dense] 278 branch_b = [input_b, dense, dropout] 279 280 model = testing_utils.get_multi_io_model(branch_a, branch_b) 281 282 optimizer = RMSPropOptimizer(learning_rate=0.001) 283 loss = 'mse' 284 loss_weights = [1., 0.5] 285 model.compile( 286 optimizer, 287 loss, 288 metrics=[metrics_module.CategoricalAccuracy(), 'mae'], 289 loss_weights=loss_weights, 290 run_eagerly=testing_utils.should_run_eagerly()) 291 292 input_a_np = np.random.random((10, 3)) 293 input_b_np = np.random.random((10, 3)) 294 295 output_d_np = np.random.random((10, 4)) 296 output_e_np = np.random.random((10, 4)) 297 298 # Test fit at different verbosity 299 model.fit( 300 [input_a_np, input_b_np], [output_d_np, output_e_np], 301 epochs=1, 302 batch_size=5, 303 verbose=0) 304 model.fit( 305 [input_a_np, input_b_np], [output_d_np, output_e_np], 306 epochs=1, 307 batch_size=5, 308 verbose=1) 309 model.fit( 310 [input_a_np, input_b_np], [output_d_np, output_e_np], 311 epochs=2, 312 batch_size=5, 313 verbose=2) 314 model.train_on_batch([input_a_np, input_b_np], [output_d_np, output_e_np]) 315 316 # Test with validation data 317 model.fit( 318 [input_a_np, input_b_np], [output_d_np, output_e_np], 319 validation_data=([input_a_np, input_b_np], [output_d_np, 320 output_e_np]), 321 epochs=1, 322 batch_size=5, 323 verbose=0) 324 model.fit( 325 [input_a_np, input_b_np], [output_d_np, output_e_np], 326 validation_data=([input_a_np, input_b_np], [output_d_np, 327 output_e_np]), 328 epochs=2, 329 batch_size=5, 330 verbose=1) 331 model.fit( 332 [input_a_np, input_b_np], [output_d_np, output_e_np], 333 validation_data=([input_a_np, input_b_np], [output_d_np, 334 output_e_np]), 335 epochs=2, 336 batch_size=5, 337 verbose=2) 338 # Test with validation split 339 model.fit( 340 [input_a_np, input_b_np], [output_d_np, output_e_np], 341 epochs=2, 342 batch_size=5, 343 verbose=0, 344 validation_split=0.2) 345 346 if testing_utils.get_model_type() == 'functional': 347 # Test with dictionary inputs 348 model.fit( 349 { 350 'input_a': input_a_np, 351 'input_b': input_b_np 352 }, { 353 'dense': output_d_np, 354 'dropout': output_e_np 355 }, 356 epochs=1, 357 batch_size=5, 358 verbose=0) 359 model.fit( 360 { 361 'input_a': input_a_np, 362 'input_b': input_b_np 363 }, { 364 'dense': output_d_np, 365 'dropout': output_e_np 366 }, 367 epochs=1, 368 batch_size=5, 369 verbose=1) 370 model.fit( 371 { 372 'input_a': input_a_np, 373 'input_b': input_b_np 374 }, { 375 'dense': output_d_np, 376 'dropout': output_e_np 377 }, 378 validation_data=({ 379 'input_a': input_a_np, 380 'input_b': input_b_np 381 }, { 382 'dense': output_d_np, 383 'dropout': output_e_np 384 }), 385 epochs=1, 386 batch_size=5, 387 verbose=0) 388 model.train_on_batch({ 389 'input_a': input_a_np, 390 'input_b': input_b_np 391 }, { 392 'dense': output_d_np, 393 'dropout': output_e_np 394 }) 395 396 # Test with lists for loss, metrics 397 loss = ['mae', 'mse'] 398 model.compile( 399 optimizer, 400 loss, 401 metrics=[metrics_module.CategoricalAccuracy(), 'mae'], 402 run_eagerly=testing_utils.should_run_eagerly()) 403 model.fit( 404 [input_a_np, input_b_np], [output_d_np, output_e_np], 405 epochs=1, 406 batch_size=5, 407 verbose=0) 408 409 # Test with dictionaries for loss, metrics, loss weights 410 if testing_utils.get_model_type() == 'functional': 411 loss = {'dense': 'mse', 'dropout': 'mae'} 412 loss_weights = {'dense': 1., 'dropout': 0.5} 413 metrics = { 414 'dense': 'mse', 415 'dropout': metrics_module.CategoricalAccuracy() 416 } 417 model.compile( 418 optimizer, 419 loss, 420 metrics=metrics, 421 loss_weights=loss_weights, 422 run_eagerly=testing_utils.should_run_eagerly()) 423 model.fit( 424 [input_a_np, input_b_np], [output_d_np, output_e_np], 425 epochs=1, 426 batch_size=5, 427 verbose=0) 428 429 # Build single-input model 430 x = layers_module.Input(shape=(3,), name='input_a') 431 y = layers_module.Dense(4)(x) 432 model = training_module.Model(x, y) 433 model.compile( 434 optimizer, 435 loss='mse', 436 run_eagerly=testing_utils.should_run_eagerly()) 437 # This will work 438 model.fit([input_a_np], output_d_np, epochs=1) 439 440 # Test model on a list of floats 441 input_a_np = np.random.random((10, 3)) 442 input_b_np = np.random.random((10, 4)) 443 444 # Test execution on inputs that are lists of scalars. 445 # TF2 and TF1 have slightly different semantics: 446 if context.executing_eagerly(): 447 # In TF2 to avoid any ambiguity when there are nested lists 448 # the entire input gets converted to a 449 # single numpy array (& it only works in the case of a single io model) 450 model.fit(np.ndarray.tolist(input_a_np), 451 np.ndarray.tolist(input_b_np), 452 epochs=2, 453 batch_size=5, 454 verbose=2) 455 else: 456 # In TF1 there was logic to try disambiguating between the individual 457 # inputs when lists are nested. This allowed multi-io functional models 458 # to support lists of scalars as input, but it caused ambiguity issues 459 # for subclass models & made it trickier to pass multi-dimensional inputs 460 # as lists of scalars to single io models. This was an excessive amount 461 # of complexity for what boiled down to a convenience method we were 462 # mainly just using for writing tests. 463 model.fit([np.ndarray.tolist(input_a_np)], 464 [np.ndarray.tolist(input_b_np)], 465 epochs=2, 466 batch_size=5, 467 verbose=2) 468 469 @keras_parameterized.run_all_keras_modes 470 def test_evaluate_predict_on_arrays(self): 471 a = layers_module.Input(shape=(3,), name='input_a') 472 b = layers_module.Input(shape=(3,), name='input_b') 473 474 dense = layers_module.Dense(4, name='dense') 475 c = dense(a) 476 d = dense(b) 477 e = layers_module.Dropout(0.5, name='dropout')(c) 478 479 model = training_module.Model([a, b], [d, e]) 480 481 optimizer = RMSPropOptimizer(learning_rate=0.001) 482 loss = 'mse' 483 loss_weights = [1., 0.5] 484 model.compile( 485 optimizer, 486 loss, 487 metrics=['mae', metrics_module.CategoricalAccuracy()], 488 loss_weights=loss_weights, 489 sample_weight_mode=None, 490 run_eagerly=testing_utils.should_run_eagerly()) 491 492 input_a_np = np.random.random((10, 3)) 493 input_b_np = np.random.random((10, 3)) 494 495 output_d_np = np.random.random((10, 4)) 496 output_e_np = np.random.random((10, 4)) 497 498 # Test evaluate at different verbosity 499 out = model.evaluate( 500 [input_a_np, input_b_np], [output_d_np, output_e_np], 501 batch_size=5, 502 verbose=0) 503 self.assertEqual(len(out), 7) 504 out = model.evaluate( 505 [input_a_np, input_b_np], [output_d_np, output_e_np], 506 batch_size=5, 507 verbose=1) 508 self.assertEqual(len(out), 7) 509 out = model.evaluate( 510 [input_a_np, input_b_np], [output_d_np, output_e_np], 511 batch_size=5, 512 verbose=2) 513 self.assertEqual(len(out), 7) 514 out = model.test_on_batch([input_a_np, input_b_np], 515 [output_d_np, output_e_np]) 516 self.assertEqual(len(out), 7) 517 518 # Test evaluate with dictionary inputs 519 model.evaluate( 520 { 521 'input_a': input_a_np, 522 'input_b': input_b_np 523 }, { 524 'dense': output_d_np, 525 'dropout': output_e_np 526 }, 527 batch_size=5, 528 verbose=0) 529 model.evaluate( 530 { 531 'input_a': input_a_np, 532 'input_b': input_b_np 533 }, { 534 'dense': output_d_np, 535 'dropout': output_e_np 536 }, 537 batch_size=5, 538 verbose=1) 539 540 # Test predict 541 out = model.predict([input_a_np, input_b_np], batch_size=5) 542 self.assertEqual(len(out), 2) 543 out = model.predict({'input_a': input_a_np, 'input_b': input_b_np}) 544 self.assertEqual(len(out), 2) 545 out = model.predict_on_batch({ 546 'input_a': input_a_np, 547 'input_b': input_b_np 548 }) 549 self.assertEqual(len(out), 2) 550 551 def _make_sequence_input_functions(self, input_type): 552 # train and test 553 xy_namedtuple = collections.namedtuple('xy_namedtuple', ['x', 'y']) 554 555 # predict 556 x_namedtuple = collections.namedtuple('x_namedtuple', ['x']) 557 558 if input_type == 'dataset': 559 dataset = dataset_ops.Dataset.range(16).map( 560 lambda _: array_ops.ones(shape=(1,))) 561 562 xy_dataset = dataset_ops.Dataset.zip((dataset, dataset)).batch(4) 563 x_dataset = dataset.batch(4) 564 def xy_function(use_namedtuple): 565 return xy_dataset.map(xy_namedtuple) if use_namedtuple else xy_dataset 566 567 def x_function(use_namedtuple): 568 return x_dataset.map(x_namedtuple) if use_namedtuple else x_dataset 569 570 return xy_function, x_function 571 572 elif input_type == 'generator': 573 def xy_generator(use_namedtuple): 574 x, y = np.ones((4, 1)), np.ones((4, 1)) 575 for _ in range(4): 576 if use_namedtuple: 577 yield xy_namedtuple(x, y) 578 else: 579 yield x, y 580 581 def x_generator(use_namedtuple): 582 x = np.ones((4, 1)) 583 for _ in range(4): 584 if use_namedtuple: 585 yield x_namedtuple(x) 586 else: 587 yield x 588 589 return xy_generator, x_generator 590 591 elif input_type == 'sequence': 592 class XYSequence(data_utils.Sequence): 593 594 def __init__(self, use_namedtuple): 595 self._use_namedtuple = use_namedtuple 596 super(XYSequence, self).__init__() 597 598 def __getitem__(self, idx): 599 x, y = np.ones((4, 1)), np.ones((4, 1)) 600 if self._use_namedtuple: 601 return xy_namedtuple(x, y) 602 return x, y 603 604 def __len__(self): 605 return 4 606 607 class XSequence(data_utils.Sequence): 608 609 def __init__(self, use_namedtuple): 610 self._use_namedtuple = use_namedtuple 611 super(XSequence, self).__init__() 612 613 def __getitem__(self, idx): 614 x = np.ones((4, 1)) 615 if self._use_namedtuple: 616 return x_namedtuple(x) 617 return x 618 619 def __len__(self): 620 return 4 621 622 return XYSequence, XSequence 623 624 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 625 @keras_parameterized.run_with_all_model_types 626 @parameterized.named_parameters( 627 ('dataset', 'dataset'), 628 ('generator', 'generator'), 629 ('sequence', 'sequence'), 630 ) 631 def test_sequence_input_types(self, input_type): 632 """Ensure that namedtuples and tuples are plumbed identically.""" 633 if not context.executing_eagerly(): 634 self.skipTest('Improved checking is only present in data_adapter.') 635 636 xy_function, x_function = self._make_sequence_input_functions(input_type) 637 fit_kwargs, evaluate_kwargs, predict_kwargs = {}, {}, {} 638 if input_type == 'generator': 639 fit_kwargs['steps_per_epoch'] = 4 640 evaluate_kwargs['steps'] = 4 641 predict_kwargs['steps'] = 4 642 643 model = testing_utils.get_small_mlp(1, 1, 1) 644 model.compile( 645 loss='mse', 646 optimizer='sgd', 647 run_eagerly=testing_utils.should_run_eagerly()) 648 649 model.fit(xy_function(use_namedtuple=False), **fit_kwargs) 650 model.evaluate(xy_function(use_namedtuple=False), **evaluate_kwargs) 651 model.predict(x_function(use_namedtuple=False), **predict_kwargs) 652 653 @keras_parameterized.run_all_keras_modes 654 def test_custom_mapping_in_config(self): 655 656 class MyModel(training_module.Model): 657 658 def call(self, inputs): 659 return inputs 660 661 def get_config(self): 662 self.a = {} 663 return {'a': self.a} 664 665 model = MyModel() 666 self.assertIn('{"a": {}}', model.to_json()) 667 668 def test_training_on_sparse_data_with_dense_placeholders_v1(self): 669 with ops.Graph().as_default(): 670 if scipy_sparse is None: 671 return 672 673 test_inputs = [ 674 scipy_sparse.random(6, 3, density=0.25).tocsr() for _ in range(2) 675 ] 676 test_outputs = [ 677 scipy_sparse.random(6, i, density=0.25).tocsr() for i in range(3, 5) 678 ] 679 in1 = layers_module.Input(shape=(3,)) 680 in2 = layers_module.Input(shape=(3,)) 681 out1 = layers_module.Dropout(0.5, name='dropout')(in1) 682 out2 = layers_module.Dense(4, name='dense_1')(in2) 683 model = training_module.Model([in1, in2], [out1, out2]) 684 model.predict(test_inputs, batch_size=2) 685 optimizer = 'rmsprop' 686 model.compile( 687 optimizer, 688 'mse', 689 metrics=['mae', metrics_module.CategoricalAccuracy()]) 690 model.fit(test_inputs, test_outputs, 691 epochs=1, batch_size=2, validation_split=0.5) 692 model.evaluate(test_inputs, test_outputs, batch_size=2) 693 694 @keras_parameterized.run_all_keras_modes 695 def test_compile_with_sparse_placeholders(self): 696 inputs = layers_module.Input(shape=(10,), sparse=True) 697 weights = variables_module.Variable( 698 np.ones((10, 1)).astype(np.float32), name='weights') 699 weights_mult = lambda x: sparse_ops.sparse_tensor_dense_matmul(x, weights) 700 output_layer = layers_module.Lambda(weights_mult)(inputs) 701 model = training_module.Model([inputs], output_layer) 702 model.compile( 703 loss='binary_crossentropy', 704 optimizer='adam', 705 metrics=['accuracy'], 706 run_eagerly=testing_utils.should_run_eagerly()) 707 708 @keras_parameterized.run_all_keras_modes 709 def test_that_trainable_disables_updates(self): 710 val_a = np.random.random((10, 4)) 711 val_out = np.random.random((10, 4)) 712 713 a = layers_module.Input(shape=(4,)) 714 layer = layers_module.BatchNormalization(input_shape=(4,)) 715 b = layer(a) 716 model = training_module.Model(a, b) 717 718 model.trainable = False 719 if not ops.executing_eagerly_outside_functions(): 720 self.assertEmpty(model.updates) 721 722 model.compile( 723 'sgd', 724 'mse', 725 run_eagerly=testing_utils.should_run_eagerly()) 726 if not ops.executing_eagerly_outside_functions(): 727 self.assertEmpty(model.updates) 728 729 x1 = model.predict(val_a) 730 model.train_on_batch(val_a, val_out) 731 x2 = model.predict(val_a) 732 self.assertAllClose(x1, x2, atol=1e-7) 733 734 model.trainable = True 735 model.compile( 736 'sgd', 737 'mse', 738 run_eagerly=testing_utils.should_run_eagerly()) 739 if not ops.executing_eagerly_outside_functions(): 740 self.assertAllGreater(len(model.updates), 0) 741 742 model.train_on_batch(val_a, val_out) 743 x2 = model.predict(val_a) 744 assert np.abs(np.sum(x1 - x2)) > 1e-5 745 746 layer.trainable = False 747 model.compile( 748 'sgd', 749 'mse', 750 run_eagerly=testing_utils.should_run_eagerly()) 751 if not ops.executing_eagerly_outside_functions(): 752 self.assertEmpty(model.updates) 753 754 x1 = model.predict(val_a) 755 model.train_on_batch(val_a, val_out) 756 x2 = model.predict(val_a) 757 self.assertAllClose(x1, x2, atol=1e-7) 758 759 def test_weight_deduplication_in_methods(self): 760 inp = layers_module.Input(shape=(1,)) 761 bn = layers_module.BatchNormalization() 762 d = layers_module.Dense(1) 763 764 m0 = training_module.Model(inp, d(bn(inp))) 765 m1 = training_module.Model(inp, d(bn(inp))) 766 767 x0 = m0(inp) 768 x1 = m1(inp) 769 x = layers_module.Add()([x0, x1]) 770 771 model = training_module.Model(inp, x) 772 self.assertLen(model.trainable_weights, 4) 773 self.assertLen(model.non_trainable_weights, 2) 774 self.assertLen(model.weights, 6) 775 776 @keras_parameterized.run_all_keras_modes 777 def test_weight_deduplication(self): 778 779 class WatchingLayer(layers_module.Layer): 780 781 def __init__(self, dense_to_track): 782 # This will cause the kernel and bias to be double counted, effectively 783 # doubling the learning rate if weights are not deduped. 784 self._kernel = dense_to_track.kernel 785 self._bias = dense_to_track.bias 786 super(WatchingLayer, self).__init__() 787 788 inp = layers_module.Input(shape=(1,)) 789 dense_layer = layers_module.Dense(1) 790 dense_output = dense_layer(inp) # This will build the dense kernel 791 792 # Deterministically set weights to make the test repeatable. 793 dense_layer.set_weights([np.ones((1, 1)), np.zeros((1,))]) 794 output = WatchingLayer(dense_layer)(dense_output) 795 796 model = training_module.Model(inp, output) 797 798 # 0.25 is the edge of the radius of convergence for the double apply case. 799 # At lr=0.24, the double apply case will very slowly descend while the 800 # correct case will drop very quickly. 801 model.compile( 802 loss='mse', 803 optimizer=optimizer_v2.gradient_descent.SGD(0.24), 804 run_eagerly=testing_utils.should_run_eagerly()) 805 806 x = np.ones((64 * 2,)) 807 y = 4.5 * x - 3. 808 809 history = model.fit(x, y, batch_size=64, epochs=2, verbose=2) 810 811 # If the gradient apply is duplicated then the loss after 2 epochs will 812 # be ~0.15, compared to the correct answer of O(1e-7). 813 self.assertLess(history.history['loss'][-1], 1e-6) 814 815 @keras_parameterized.run_all_keras_modes 816 def test_weight_shared_across_layers(self): 817 818 class AddWeightLayer(layers_module.Layer): 819 820 def __init__(self, trainable_var, non_trainable_var): 821 self.trainable_var = trainable_var 822 self.non_trainable_var = non_trainable_var 823 super(AddWeightLayer, self).__init__() 824 825 def call(self, inputs): 826 return inputs + self.trainable_var 827 828 class LayerWithWeightSharedLayers(layers_module.Layer): 829 830 def __init__(self): 831 super(LayerWithWeightSharedLayers, self).__init__() 832 shared_trainable_var = variables_module.Variable(1.) 833 shared_non_trainable_var = variables_module.Variable( 834 1., trainable=False) 835 self.layer1 = AddWeightLayer(shared_trainable_var, 836 shared_non_trainable_var) 837 self.layer2 = AddWeightLayer(shared_trainable_var, 838 shared_non_trainable_var) 839 840 def call(self, inputs): 841 return self.layer2(self.layer1(inputs)) 842 843 l = LayerWithWeightSharedLayers() 844 layers = list(l._flatten_layers(include_self=False, recursive=False)) 845 self.assertEqual(layers, [l.layer1, l.layer2]) 846 self.assertEqual(l.variables, 847 [l.layer1.trainable_var, l.layer1.non_trainable_var]) 848 self.assertEqual(l.trainable_variables, [l.layer1.trainable_var]) 849 self.assertEqual(l.non_trainable_variables, [l.layer1.non_trainable_var]) 850 self.assertLen(l.get_weights(), 2) 851 852 @keras_parameterized.run_all_keras_modes 853 def test_weight_tracking_for_template(self): 854 def variable_scoped_function(trainable=True): 855 return variable_scope.get_variable( 856 'dummy', shape=[1], trainable=trainable, 857 initializer=init_ops.zeros_initializer()) 858 def nested_template(): 859 nested1 = template.make_template('nested', variable_scoped_function) 860 nested2 = template.make_template('nested', variable_scoped_function) 861 v1 = nested1() 862 v2 = nested2() 863 864 # nested1 and nested2 should not share variables 865 self.assertIsNot(v1, v2) 866 867 # Variables created by nested1 should be isolated from variables 868 # created by nested2. 869 self.assertEqual(1, len(nested1.variables)) 870 self.assertEqual(1, len(nested2.variables)) 871 self.assertIs(nested1.variables[0], v1) 872 self.assertIs(nested2.variables[0], v2) 873 self.assertEqual(1, len(nested1.trainable_variables)) 874 self.assertEqual(1, len(nested2.trainable_variables)) 875 self.assertIs(nested1.trainable_variables[0], v1) 876 self.assertIs(nested2.trainable_variables[0], v2) 877 self.assertEqual(len(nested1.non_trainable_variables), 0) 878 self.assertEqual(len(nested2.non_trainable_variables), 0) 879 return v1, v2 880 881 tmpl1 = template.make_template('s1', nested_template) 882 tmpl2 = template.make_template('s1', nested_template) 883 884 v1, v2 = tmpl1() 885 v5, v6 = tmpl2() 886 887 model = training_module.Model() 888 model.template = tmpl1 889 self.assertEqual(2, len(model.variables)) 890 self.assertIs(model.variables[0], v1) 891 self.assertIs(model.variables[1], v2) 892 self.assertEqual(2, len(model.variables)) 893 self.assertIs(model.trainable_variables[0], v1) 894 self.assertIs(model.trainable_variables[1], v2) 895 self.assertEqual(len(model.non_trainable_variables), 0) 896 model.templates = [tmpl2] 897 for v, w in zip(model.variables, [v1, v2, v5, v6]): 898 self.assertIs(v, w) 899 for v, w in zip(model.trainable_variables, [v1, v2, v5, v6]): 900 self.assertIs(v, w) 901 self.assertEqual(len(model.non_trainable_variables), 0) 902 # Make sure losses, layers, and updates aren't broken by having a Template 903 # in the mix, which does not expose any updates or losses. 904 self.assertEqual([], model.layers) 905 self.assertEqual([], model.updates) 906 self.assertEqual([], model.losses) 907 self.assertEqual([], model.templates.layers) 908 self.assertEqual([], model.templates.updates) 909 self.assertEqual([], model.templates.losses) 910 911 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 912 def test_logs_passed_to_callbacks(self): 913 input_dim = 5 914 num_classes = 1 915 916 class TestCallback(Callback): 917 918 def __init__(self): 919 super(TestCallback, self).__init__() 920 self.epoch_end_logs = None 921 self.batch_end_logs = None 922 self.epoch_end_call_count = 0 923 self.batch_end_call_count = 0 924 925 def on_epoch_end(self, epoch, logs=None): 926 self.epoch_end_logs = logs 927 self.epoch_end_call_count += 1 928 929 def on_batch_end(self, batch, logs=None): 930 self.batch_end_logs = logs 931 self.batch_end_call_count += 1 932 933 model = testing_utils.get_small_sequential_mlp( 934 num_hidden=10, num_classes=num_classes, input_dim=input_dim) 935 model.compile( 936 loss='binary_crossentropy', 937 metrics=['acc'], 938 weighted_metrics=['mae'], 939 optimizer=RMSPropOptimizer(learning_rate=0.01), 940 run_eagerly=testing_utils.should_run_eagerly()) 941 942 np.random.seed(1337) 943 (x_train, y_train), (_, _) = testing_utils.get_test_data( 944 train_samples=10, 945 test_samples=10, 946 input_shape=(input_dim,), 947 num_classes=num_classes) 948 949 test_callback = TestCallback() 950 model.fit( 951 x_train, 952 y_train, 953 batch_size=2, 954 epochs=2, 955 verbose=0, 956 callbacks=[test_callback], 957 validation_data=(x_train, y_train)) 958 self.assertEqual(test_callback.batch_end_call_count, 10) 959 self.assertEqual(test_callback.epoch_end_call_count, 2) 960 961 self.assertSetEqual( 962 set(test_callback.batch_end_logs.keys()), set(['acc', 'loss', 'mae'])) 963 self.assertSetEqual( 964 set(test_callback.epoch_end_logs.keys()), 965 set(['acc', 'loss', 'mae', 'val_acc', 'val_loss', 'val_mae'])) 966 967 @keras_parameterized.run_all_keras_modes 968 def test_mismatched_output_shape_and_target_shape(self): 969 model = sequential.Sequential([ 970 layers_module.Dense(2, input_shape=(3, 4)), 971 layers_module.Dense(5), 972 ]) 973 model.compile( 974 RMSPropOptimizer(learning_rate=0.001), 975 loss='sparse_categorical_crossentropy', 976 run_eagerly=testing_utils.should_run_eagerly()) 977 # Test with Numpy data 978 x_train = np.random.random((10, 3, 4)).astype(np.float32) 979 y_train = np.random.randint(0, 5, size=(10, 3)).astype(np.float32) 980 model.fit(x_train, y_train, batch_size=5, epochs=1) 981 982 # Test with iterator 983 dataset = dataset_ops.Dataset.from_tensor_slices((x_train, y_train)) 984 dataset = dataset.repeat(10) 985 dataset = dataset.batch(10) 986 model.fit(dataset, epochs=1, steps_per_epoch=2) 987 988 if context.executing_eagerly(): 989 # Test with eager execution 990 model.compile(RMSPropOptimizer(learning_rate=0.001), 991 loss='sparse_categorical_crossentropy', 992 run_eagerly=True) 993 model.fit(x_train, y_train, batch_size=5, epochs=1) 994 995 # Test with eager execution and iterator 996 model.fit(dataset, epochs=1, steps_per_epoch=2) 997 998 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 999 def test_losses_in_defun(self): 1000 layer = layers_module.Dense(1, kernel_regularizer='l1') 1001 layer(array_ops.ones([1, 10])) 1002 1003 @def_function.function 1004 def get_losses(): 1005 return layer.losses 1006 1007 self.assertAllEqual( 1008 self.evaluate(layer.losses), self.evaluate(get_losses())) 1009 1010 @keras_parameterized.run_all_keras_modes 1011 def test_logging(self): 1012 mock_stdout = io.StringIO() 1013 model = sequential.Sequential() 1014 model.add(layers_module.Dense(10, activation='relu')) 1015 model.add(layers_module.Dense(1, activation='sigmoid')) 1016 model.compile( 1017 RMSPropOptimizer(learning_rate=0.001), 1018 loss='binary_crossentropy', 1019 run_eagerly=testing_utils.should_run_eagerly()) 1020 with test.mock.patch.object(sys, 'stdout', mock_stdout): 1021 model.fit( 1022 np.ones((10, 10), 'float32'), np.ones((10, 1), 'float32'), epochs=10) 1023 self.assertTrue('Epoch 5/10' in mock_stdout.getvalue()) 1024 1025 @combinations.generate(combinations.combine(mode=['graph', 'eager'])) 1026 def test_training_with_loss_instance(self): 1027 a = layers_module.Input(shape=(3,), name='input_a') 1028 b = layers_module.Input(shape=(3,), name='input_b') 1029 1030 dense = layers_module.Dense(4, name='dense') 1031 c = dense(a) 1032 d = dense(b) 1033 e = layers_module.Dropout(0.5, name='dropout')(c) 1034 1035 model = training_module.Model([a, b], [d, e]) 1036 loss_weights = [1., 0.5] 1037 model.compile( 1038 RMSPropOptimizer(learning_rate=0.001), 1039 loss=losses.MeanSquaredError(), 1040 metrics=[metrics_module.CategoricalAccuracy(), 'mae'], 1041 loss_weights=loss_weights) 1042 1043 input_a_np = np.random.random((10, 3)) 1044 input_b_np = np.random.random((10, 3)) 1045 1046 output_d_np = np.random.random((10, 4)) 1047 output_e_np = np.random.random((10, 4)) 1048 1049 model.fit([input_a_np, input_b_np], [output_d_np, output_e_np], 1050 epochs=1, 1051 batch_size=5) 1052 1053 @combinations.generate(combinations.combine(mode=['graph', 'eager'])) 1054 def test_static_batch_in_input_layer(self): 1055 if context.executing_eagerly(): 1056 self.skipTest('Not inferred in eager.') 1057 1058 class Counter(Callback): 1059 1060 def __init__(self): 1061 self.batches = 0 1062 1063 def on_batch_end(self, batch, logs=None): 1064 self.batches += 1 1065 1066 x, y = np.ones((64, 10), 'float32'), np.ones((64, 1), 'float32') 1067 1068 for batch_size, expected_batches in [(None, 2), (4, 16)]: 1069 inputs = input_layer.Input(batch_size=batch_size, shape=(10,)) 1070 outputs = layers_module.Dense(1, activation='sigmoid')(inputs) 1071 model = training_module.Model(inputs, outputs) 1072 1073 model.compile(optimizer_v2.adam.Adam(0.001), 'binary_crossentropy') 1074 counter = Counter() 1075 model.fit(x, y, callbacks=[counter]) 1076 self.assertEqual(counter.batches, expected_batches) 1077 1078 model = sequential.Sequential( 1079 [layers_module.Dense(1, batch_input_shape=(batch_size, 10))]) 1080 model.compile(optimizer_v2.adam.Adam(0.001), 'binary_crossentropy') 1081 counter = Counter() 1082 model.fit(x, y, callbacks=[counter]) 1083 self.assertEqual(counter.batches, expected_batches) 1084 1085 @combinations.generate(combinations.combine(mode=['graph', 'eager'])) 1086 def test_static_batch_in_input_layer_consistency_checks(self): 1087 if context.executing_eagerly(): 1088 self.skipTest('Not inferred in eager.') 1089 x, y = np.ones((64, 10), 'float32'), np.ones((64, 1), 'float32') 1090 1091 inputs = input_layer.Input(batch_size=2, shape=(10,)) 1092 outputs = layers_module.Dense(1, activation='sigmoid')(inputs) 1093 model = training_module.Model(inputs, outputs) 1094 model.compile(optimizer_v2.adam.Adam(0.001), 'binary_crossentropy') 1095 with self.assertRaisesRegex(ValueError, 1096 'incompatible with the specified batch size'): 1097 model.fit(x, y, batch_size=4) 1098 1099 @combinations.generate(combinations.combine(mode=['graph', 'eager'])) 1100 def test_compatible_batch_size_functional_model(self): 1101 1102 class MyLayer(layers_module.Layer): 1103 1104 def call(self, inputs): 1105 return array_ops.concat(inputs, axis=0) 1106 1107 input1 = input_layer.Input(batch_size=2, shape=(10,)) 1108 input2 = input_layer.Input(batch_size=3, shape=(10,)) 1109 outputs = MyLayer()([input1, input2]) 1110 with self.assertRaisesRegex(ValueError, 1111 'specified batch sizes of the Input Layers'): 1112 training_module.Model([input1, input2], outputs) 1113 1114 @combinations.generate(combinations.combine(mode=['graph', 'eager'])) 1115 def test_calling_subclass_model_on_different_datasets(self): 1116 1117 class SubclassedModel(training_module.Model): 1118 1119 def call(self, inputs): 1120 return inputs * 2 1121 1122 model = SubclassedModel() 1123 dataset_one = dataset_ops.Dataset.range(2).batch(2) 1124 dataset_two = dataset_ops.Dataset.range(3, 10).batch(2) 1125 self.assertAllEqual([[0], [2]], model.predict(dataset_one, steps=1)) 1126 self.assertAllEqual([[6], [8], [10], [12]], 1127 model.predict(dataset_two, steps=2)) 1128 1129 @combinations.generate(combinations.combine(mode=['eager'])) 1130 def test_training_on_sparse_categorical_crossentropy_loss_with_softmax(self): 1131 np.random.seed(1337) 1132 train_x = np.ones((100, 4)) 1133 train_y = np.random.randint(0, 1, size=(100, 1)) 1134 1135 reference_model = testing_utils.get_small_sequential_mlp(16, 2, 1136 input_dim=4) 1137 reference_model.compile(loss='sparse_categorical_crossentropy', 1138 optimizer=RMSPropOptimizer(learning_rate=0.001), 1139 run_eagerly=True) 1140 fixed_weights = reference_model.get_weights() 1141 reference_model_loss = reference_model.train_on_batch(train_x, train_y) 1142 1143 test_model = testing_utils.get_small_sequential_mlp(16, 2, input_dim=4) 1144 test_model.compile(loss='sparse_categorical_crossentropy', 1145 optimizer=RMSPropOptimizer(learning_rate=0.001), 1146 run_eagerly=False) 1147 test_model.set_weights(fixed_weights) 1148 test_model_loss = test_model.train_on_batch(train_x, train_y) 1149 self.assertAlmostEqual(test_model_loss, reference_model_loss, places=4) 1150 1151 @combinations.generate(combinations.combine(mode=['eager'])) 1152 def test_training_on_categorical_crossentropy_loss_with_softmax(self): 1153 np.random.seed(1337) 1154 train_x = np.ones((100, 4)) 1155 train_y = np_utils.to_categorical( 1156 np.random.randint(0, 1, size=(100, 1)), 2) 1157 1158 reference_model = testing_utils.get_small_sequential_mlp(16, 2, 1159 input_dim=4) 1160 reference_model.compile(loss='categorical_crossentropy', 1161 optimizer=RMSPropOptimizer(learning_rate=0.001), 1162 run_eagerly=True) 1163 fixed_weights = reference_model.get_weights() 1164 reference_model_loss = reference_model.train_on_batch(train_x, train_y) 1165 1166 test_model = testing_utils.get_small_sequential_mlp(16, 2, input_dim=4) 1167 test_model.compile(loss='categorical_crossentropy', 1168 optimizer=RMSPropOptimizer(learning_rate=0.001), 1169 run_eagerly=False) 1170 test_model.set_weights(fixed_weights) 1171 test_model_loss = test_model.train_on_batch(train_x, train_y) 1172 self.assertAlmostEqual(test_model_loss, reference_model_loss, places=4) 1173 1174 @combinations.generate(combinations.combine(mode=['eager'])) 1175 def test_training_on_binary_crossentropy_loss(self): 1176 train_x = np.ones((100, 4), dtype=np.float32) 1177 train_y = np.ones((100, 1), dtype=np.float32) 1178 reference_model = testing_utils.get_small_sequential_mlp(16, 1, 1179 input_dim=4) 1180 reference_model.compile(loss='binary_crossentropy', 1181 optimizer=RMSPropOptimizer(learning_rate=0.001), 1182 run_eagerly=True) 1183 fixed_weights = reference_model.get_weights() 1184 reference_model_loss = reference_model.train_on_batch(train_x, train_y) 1185 1186 test_model = testing_utils.get_small_sequential_mlp(16, 1, input_dim=4) 1187 test_model.compile(loss='binary_crossentropy', 1188 optimizer=RMSPropOptimizer(learning_rate=0.001), 1189 run_eagerly=False) 1190 test_model.set_weights(fixed_weights) 1191 test_model_loss = test_model.train_on_batch(train_x, train_y) 1192 self.assertAlmostEqual(test_model_loss, reference_model_loss, places=4) 1193 1194 @keras_parameterized.run_with_all_model_types 1195 @keras_parameterized.run_all_keras_modes 1196 @parameterized.named_parameters( 1197 ('default', 1, 4), ('integer_two', 2, 2), ('integer_four', 4, 1), 1198 ('simple_list', [1, 3, 4], 3), ('duplicated_list', [4, 2, 2], 2)) 1199 def test_validation_freq(self, validation_freq, expected_runs): 1200 x, y = np.ones((10, 10)), np.ones((10, 1)) 1201 model = testing_utils.get_small_mlp(2, 1, 10) 1202 model.compile( 1203 'sgd', 1204 'mse', 1205 run_eagerly=testing_utils.should_run_eagerly()) 1206 1207 class ValCounter(Callback): 1208 1209 def __init__(self): 1210 self.val_runs = 0 1211 1212 def on_test_begin(self, logs=None): 1213 self.val_runs += 1 1214 1215 val_counter = ValCounter() 1216 model.fit( 1217 x, 1218 y, 1219 epochs=4, 1220 validation_data=(x, y), 1221 validation_freq=validation_freq, 1222 callbacks=[val_counter]) 1223 self.assertEqual(val_counter.val_runs, expected_runs) 1224 1225 @keras_parameterized.run_with_all_model_types 1226 @keras_parameterized.run_all_keras_modes 1227 def test_validation_steps_without_data(self): 1228 if context.executing_eagerly(): 1229 self.skipTest('Check removed in new `fit`') 1230 x, y = np.ones((10, 10)), np.ones((10, 1)) 1231 model = testing_utils.get_small_mlp(2, 1, 10) 1232 model.compile( 1233 'sgd', 1234 'mse', 1235 run_eagerly=testing_utils.should_run_eagerly()) 1236 1237 with self.assertRaisesRegex( 1238 ValueError, '`validation_steps` should not be specified if ' 1239 '`validation_data` is None.'): 1240 model.fit(x, y, epochs=4, validation_data=None, validation_steps=3) 1241 1242 @keras_parameterized.run_with_all_model_types 1243 @keras_parameterized.run_all_keras_modes 1244 def test_layer_with_variable_output(self): 1245 1246 class VariableOutputLayer(layers_module.Layer): 1247 1248 def build(self, input_shape): 1249 self.v = self.add_weight('output_var', shape=(2, 5), initializer='ones') 1250 1251 def call(self, inputs): 1252 return self.v 1253 1254 model = testing_utils.get_model_from_layers( 1255 [VariableOutputLayer(), layers_module.Dense(1)], input_shape=(10,)) 1256 # TODO(omalleyt): Make this work with `run_eagerly=True`. 1257 model.compile('sgd', 'mse', run_eagerly=False) 1258 model.fit(np.ones((10, 10)), np.ones((10, 1)), batch_size=2, epochs=5) 1259 1260 self.assertLen(model.trainable_variables, 3) 1261 1262 @keras_parameterized.run_with_all_model_types 1263 @keras_parameterized.run_all_keras_modes 1264 @testing_utils.enable_v2_dtype_behavior 1265 def test_model_dtype(self): 1266 1267 class AssertTypeLayer(layers_module.Layer): 1268 1269 def call(self, inputs): 1270 assert inputs.dtype.name == self.dtype, ( 1271 'Input tensor has type %s which does not match assert type %s' % 1272 (inputs.dtype.name, self.assert_type)) 1273 return inputs + 1. 1274 1275 for dtype in ('float16', 'float32', 'float64'): 1276 model = testing_utils.get_model_from_layers( 1277 [AssertTypeLayer(dtype=dtype)], input_shape=(10,)) 1278 model.compile( 1279 'sgd', 1280 'mse', 1281 run_eagerly=testing_utils.should_run_eagerly()) 1282 1283 x = np.ones((10, 10)) 1284 y = np.ones((10, 10)) 1285 model.fit(x, y) 1286 model.test_on_batch(x, y) 1287 model(x) 1288 1289 @keras_parameterized.run_with_all_model_types 1290 @keras_parameterized.run_all_keras_modes 1291 @testing_utils.enable_v2_dtype_behavior 1292 def test_model_input_dtype(self): 1293 model = testing_utils.get_small_mlp(1, 10, 10) 1294 model.compile( 1295 'sgd', 1296 'mse', 1297 run_eagerly=testing_utils.should_run_eagerly()) 1298 x = np.ones((10, 10)).astype(np.float64) 1299 y = np.ones((10, 10)).astype(np.float64) 1300 dataset = dataset_ops.Dataset.from_tensor_slices((x, y)).batch(2) 1301 model.fit(dataset) 1302 self.assertEqual(model._compute_dtype, 'float32') 1303 1304 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1305 def test_subclassed_model_with_training_arg(self): 1306 1307 class LayerWithTrainingArg(layers_module.Layer): 1308 1309 def call(self, inputs, training=None): 1310 self.training = training 1311 return inputs 1312 1313 class ModelWithTrainingArg(training_module.Model): 1314 1315 def __init__(self): 1316 super(ModelWithTrainingArg, self).__init__() 1317 self.l1 = LayerWithTrainingArg() 1318 1319 def call(self, inputs, training=None): 1320 self.training = training 1321 inputs = self.l1(inputs, training=training) 1322 return inputs 1323 1324 x = np.zeros((1, 2)) 1325 model = ModelWithTrainingArg() 1326 model.compile( 1327 loss='mse', 1328 optimizer='sgd', 1329 run_eagerly=testing_utils.should_run_eagerly()) 1330 model.fit(x, x, epochs=1) 1331 1332 if context.executing_eagerly(): 1333 expected_training_arg = True 1334 else: 1335 expected_training_arg = backend.symbolic_learning_phase() 1336 1337 self.assertIs(model.training, expected_training_arg) 1338 self.assertIs(model.l1.training, expected_training_arg) 1339 1340 @keras_parameterized.run_all_keras_modes 1341 def test_error_when_model_is_not_compiled(self): 1342 inputs = input_layer.Input(shape=(1,)) 1343 outputs = layers_module.Dense(1)(inputs) 1344 model = training_module.Model(inputs, outputs) 1345 with self.assertRaisesRegex(RuntimeError, 'must compile your model'): 1346 model.fit(np.ones((1, 1)), np.ones((1, 1))) 1347 1348 class MyModel(training_module.Model): 1349 1350 def call(self, x): 1351 self.add_loss(math_ops.reduce_sum(x)) 1352 return x 1353 1354 model = MyModel() 1355 with self.assertRaisesRegex(RuntimeError, 'must compile your model'): 1356 model.fit(np.random.random((32, 1)), epochs=2) 1357 1358 @keras_parameterized.run_all_keras_modes 1359 @testing_utils.enable_v2_dtype_behavior 1360 def test_losses_of_different_dtypes(self): 1361 inp = input_layer.Input(shape=(2,)) 1362 out_1 = layers_module.Dense( 1363 2, dtype='float32', kernel_regularizer='l2')( 1364 inp) 1365 out_2 = layers_module.Dense( 1366 2, dtype='float16', kernel_regularizer='l2')( 1367 inp) 1368 model = training_module.Model(inp, [out_1, out_2]) 1369 extra_loss = math_ops.reduce_sum(math_ops.cast(out_2, 'float64')) 1370 model.add_loss(extra_loss) 1371 model.compile('sgd', ['mse', 'mse'], 1372 run_eagerly=testing_utils.should_run_eagerly()) 1373 x, y = np.ones((10, 2)), np.ones((10, 2)) 1374 model.fit(x, [y, y]) 1375 1376 @keras_parameterized.run_all_keras_modes 1377 @testing_utils.enable_v2_dtype_behavior 1378 def test_losses_of_different_dtypes_with_subclassed_model(self): 1379 1380 class MyModel(training_module.Model): 1381 1382 def build(self, _): 1383 self.dense = layers_module.Dense(2) 1384 1385 def call(self, inputs): 1386 self.add_loss(math_ops.cast(nn_ops.l2_loss(inputs), 'float64')) 1387 return self.dense(inputs) 1388 1389 model = MyModel(dtype='float32') 1390 model.compile('sgd', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 1391 x, y = np.ones((10, 2)), np.ones((10, 2)) 1392 model.fit(x, y) 1393 1394 @keras_parameterized.run_all_keras_modes 1395 @testing_utils.enable_v2_dtype_behavior 1396 def test_regularizer_of_different_dtype(self): 1397 inp = input_layer.Input(shape=(2,)) 1398 1399 def regularizer(weight): 1400 return math_ops.cast(nn_ops.l2_loss(weight), 'float64') 1401 1402 out = layers_module.Dense( 1403 2, dtype='float32', kernel_regularizer=regularizer)( 1404 inp) 1405 model = training_module.Model(inp, out) 1406 model.compile('sgd', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 1407 x, y = np.ones((10, 2)), np.ones((10, 2)) 1408 model.fit(x, y) 1409 1410 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1411 def test_outputs_are_floats(self): 1412 x, y = np.ones((10, 1)), np.ones((10, 1)) 1413 model = sequential.Sequential([layers_module.Dense(1)]) 1414 model.compile('sgd', 'mse', metrics=['accuracy'], 1415 run_eagerly=testing_utils.should_run_eagerly()) 1416 1417 history = model.fit(x, y, epochs=2) 1418 self.assertIsInstance(history.history['loss'][0], float) 1419 self.assertIsInstance(history.history['accuracy'][0], float) 1420 1421 loss, accuracy = model.train_on_batch(x, y) 1422 self.assertIsInstance(loss, float) 1423 self.assertIsInstance(accuracy, float) 1424 1425 loss, accuracy = model.evaluate(x, y) 1426 self.assertIsInstance(loss, float) 1427 self.assertIsInstance(accuracy, float) 1428 1429 loss, accuracy = model.test_on_batch(x, y) 1430 self.assertIsInstance(loss, float) 1431 self.assertIsInstance(accuracy, float) 1432 1433 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1434 def test_int_output(self): 1435 x, y = np.ones((10, 1)), np.ones((10, 1)) 1436 model = sequential.Sequential([layers_module.Dense(1)]) 1437 1438 class MyMetric(metrics_module.Metric): 1439 1440 def update_state(self, y_true, y_pred, sample_weight=None): 1441 del y_true, y_pred, sample_weight 1442 1443 def result(self): 1444 return array_ops.constant(1, dtype='int64') 1445 1446 model.compile('sgd', 'mse', metrics=[MyMetric()], 1447 run_eagerly=testing_utils.should_run_eagerly()) 1448 history = model.fit(x, y, epochs=2) 1449 self.assertIsInstance(history.history['my_metric'][0], int) 1450 1451 @keras_parameterized.run_all_keras_modes 1452 def test_calling_aggregate_gradient(self): 1453 1454 class _Optimizer(optimizer_v2.gradient_descent.SGD): 1455 """Mock optimizer to check if _aggregate_gradient is called.""" 1456 1457 _HAS_AGGREGATE_GRAD = True 1458 1459 def __init__(self): 1460 self.aggregate_gradients_called = False 1461 super(_Optimizer, self).__init__(name='MyOptimizer') 1462 1463 def _aggregate_gradients(self, grads): 1464 self.aggregate_gradients_called = True 1465 return super(_Optimizer, self)._aggregate_gradients(grads) 1466 1467 mock_optimizer = _Optimizer() 1468 1469 model = sequential.Sequential() 1470 model.add(layers_module.Dense(10, activation='relu')) 1471 1472 model.compile(mock_optimizer, 'mse', 1473 run_eagerly=testing_utils.should_run_eagerly()) 1474 x, y = np.ones((10, 10)), np.ones((10, 10)) 1475 model.fit(x, y) 1476 self.assertEqual(model.optimizer.aggregate_gradients_called, True) 1477 1478 class _OptimizerOverrideApplyGradients(_Optimizer): 1479 """Override apply_gradients. 1480 1481 To test the case where the optimizer does not define the 1482 experimental_aggregate_gradients parameter. 1483 """ 1484 1485 _HAS_AGGREGATE_GRAD = False 1486 1487 def apply_gradients(self, grads_and_vars, name=None): # pylint: disable=useless-super-delegation 1488 return super(_OptimizerOverrideApplyGradients, 1489 self).apply_gradients(grads_and_vars, name) 1490 1491 mock_optimizer = _OptimizerOverrideApplyGradients() 1492 model.compile(mock_optimizer, 'mse', 1493 run_eagerly=testing_utils.should_run_eagerly()) 1494 x, y = np.ones((10, 10)), np.ones((10, 10)) 1495 model.fit(x, y) 1496 self.assertEqual(model.optimizer.aggregate_gradients_called, True) 1497 1498 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1499 def test_gradients_are_none(self): 1500 1501 class DenseWithExtraWeight(layers_module.Dense): 1502 1503 def build(self, input_shape): 1504 # Gradients w.r.t. extra_weights are None 1505 self.extra_weight_1 = self.add_weight('extra_weight_1', shape=(), 1506 initializer='ones') 1507 super(DenseWithExtraWeight, self).build(input_shape) 1508 self.extra_weight_2 = self.add_weight('extra_weight_2', shape=(), 1509 initializer='ones') 1510 1511 model = sequential.Sequential([DenseWithExtraWeight(4, input_shape=(4,))]) 1512 # Test clipping can handle None gradients 1513 opt = optimizer_v2.adam.Adam(clipnorm=1.0, clipvalue=1.0) 1514 model.compile(opt, 'mse', run_eagerly=testing_utils.should_run_eagerly()) 1515 inputs = np.random.normal(size=(64, 4)) 1516 targets = np.random.normal(size=(64, 4)) 1517 old_kernel = model.get_weights()[1] 1518 model.fit(inputs, targets) 1519 new_kernel = model.get_weights()[1] 1520 self.assertNotAllEqual(old_kernel, new_kernel) 1521 1522 @keras_parameterized.run_all_keras_modes 1523 def test_layer_ordering(self): 1524 1525 class MyLayer(layers_module.Layer): 1526 pass 1527 1528 class MyModel(training_module.Model): 1529 1530 def __init__(self, name): 1531 super(MyModel, self).__init__(name=name) 1532 1533 self.weight = variables_module.Variable(0, name=name) 1534 1535 self.direct_sublayer = MyLayer(name='direct') 1536 self.direct_sublayer.d = {'d': MyLayer(name='direct/dict')} 1537 1538 self.dict_sublayer = {'d': MyLayer(name='dict')} 1539 self.dict_sublayer['d'].direct = MyLayer(name='dict/direct') 1540 1541 model = MyModel('model') 1542 # All sublayers, including self and recursive sublayers. 1543 self.assertEqual(['model', 'direct', 'direct/dict', 'dict', 'dict/direct'], 1544 [l.name for l in model._flatten_layers()]) 1545 # Only direct sublayers, including those in data structures. 1546 self.assertEqual(['direct', 'dict'], [l.name for l in model.layers]) 1547 1548 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1549 def test_trainable_state_setting(self): 1550 1551 class UpdateLayer(layers_module.Layer): 1552 1553 def __init__(self): 1554 super(UpdateLayer, self).__init__() 1555 self.v = variables_module.Variable(0., trainable=False) 1556 1557 def call(self, x): 1558 self.add_update(lambda: self.v.assign_add(1.)) 1559 return x * self.v 1560 1561 layer = UpdateLayer() 1562 model_with_updates = sequential.Sequential([layer]) 1563 model_with_updates.compile( 1564 'sgd', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 1565 1566 layer.trainable = False 1567 model_without_updates = sequential.Sequential([layer]) 1568 model_without_updates.compile( 1569 'sgd', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 1570 1571 x, y = np.ones((10, 1)), np.ones((10, 1)) 1572 1573 self.assertEqual(self.evaluate(layer.v), 0.) 1574 model_with_updates.fit(x, y, batch_size=10) 1575 # assign_add called. 1576 self.assertEqual(self.evaluate(layer.v), 1.) 1577 model_without_updates.fit(x, y, batch_size=10) 1578 # assign_add not called. 1579 self.assertEqual(self.evaluate(layer.v), 1.) 1580 1581 @keras_parameterized.run_all_keras_modes( 1582 always_skip_v1=True) 1583 @parameterized.named_parameters( 1584 ('numpy_array', 'numpy_array'), 1585 ('dataset_array', 'dataset_array'), 1586 ('dataset_dict', 'dataset_dict')) 1587 def test_single_input_no_tuple_wrapping(self, input_type): 1588 x = np.ones((10, 1)) 1589 1590 if input_type == 'numpy_array': 1591 batch_size = 3 1592 expected_data_type = ops.Tensor 1593 elif input_type == 'dataset_array': 1594 x = dataset_ops.Dataset.from_tensor_slices(x).batch(3) 1595 batch_size = None 1596 expected_data_type = ops.Tensor 1597 else: 1598 x = {'my_input': x} 1599 x = dataset_ops.Dataset.from_tensor_slices(x).batch(3) 1600 batch_size = None 1601 expected_data_type = dict 1602 1603 test_case = self 1604 1605 class MyModel(training_module.Model): 1606 1607 def train_step(self, data): 1608 # No tuple wrapping for single x input and no targets. 1609 test_case.assertIsInstance(data, expected_data_type) 1610 return super(MyModel, self).train_step(data) 1611 1612 def test_step(self, data): 1613 test_case.assertIsInstance(data, expected_data_type) 1614 return super(MyModel, self).test_step(data) 1615 1616 def predict_step(self, data): 1617 test_case.assertIsInstance(data, expected_data_type) 1618 return super(MyModel, self).predict_step(data) 1619 1620 inputs = layers_module.Input(shape=(1,), name='my_input') 1621 outputs = layers_module.Dense(1)(inputs) 1622 model = MyModel(inputs, outputs) 1623 model.add_loss(math_ops.reduce_sum(outputs)) 1624 model.compile('sgd', 'mse') 1625 model.fit(x, batch_size=batch_size) 1626 model.evaluate(x, batch_size=batch_size) 1627 model.predict(x, batch_size=batch_size) 1628 1629 @keras_parameterized.run_all_keras_modes( 1630 always_skip_v1=True) 1631 @parameterized.named_parameters( 1632 ('custom_metrics', False, True), 1633 ('compiled_metrics', True, False), 1634 ('both_compiled_and_custom_metrics', True, True)) 1635 def test_evaluate_with_custom_test_step( 1636 self, use_compiled_metrics, use_custom_metrics): 1637 1638 class MyModel(training_module.Model): 1639 1640 def test_step(self, data): 1641 x, y = data 1642 pred = self(x) 1643 metrics = {} 1644 if use_compiled_metrics: 1645 self.compiled_metrics.update_state(y, pred) 1646 self.compiled_loss(y, pred) 1647 for metric in self.metrics: 1648 metrics[metric.name] = metric.result() 1649 if use_custom_metrics: 1650 custom_metrics = { 1651 'mean': math_ops.reduce_mean(pred), 1652 'sum': math_ops.reduce_sum(pred) 1653 } 1654 metrics.update(custom_metrics) 1655 return metrics 1656 1657 inputs = layers_module.Input((2,)) 1658 outputs = layers_module.Dense(3)(inputs) 1659 model = MyModel(inputs, outputs) 1660 if use_compiled_metrics: 1661 model.compile('adam', 'mse', metrics=['mae', 'mape'], 1662 run_eagerly=testing_utils.should_run_eagerly()) 1663 else: 1664 model.compile('adam', 'mse', 1665 run_eagerly=testing_utils.should_run_eagerly()) 1666 x = np.random.random((4, 2)) 1667 y = np.random.random((4, 3)) 1668 results_list = model.evaluate(x, y) 1669 results_dict = model.evaluate(x, y, return_dict=True) 1670 self.assertLen(results_list, len(results_dict)) 1671 if use_compiled_metrics and use_custom_metrics: 1672 self.assertLen(results_list, 5) 1673 self.assertEqual(results_list, 1674 [results_dict['loss'], 1675 results_dict['mae'], results_dict['mape'], 1676 results_dict['mean'], results_dict['sum']]) 1677 if use_compiled_metrics and not use_custom_metrics: 1678 self.assertLen(results_list, 3) 1679 self.assertEqual(results_list, 1680 [results_dict['loss'], 1681 results_dict['mae'], results_dict['mape']]) 1682 if not use_compiled_metrics and use_custom_metrics: 1683 self.assertLen(results_list, 2) 1684 self.assertEqual(results_list, 1685 [results_dict['mean'], results_dict['sum']]) 1686 1687 1688class TestExceptionsAndWarnings(keras_parameterized.TestCase): 1689 1690 @keras_parameterized.run_all_keras_modes 1691 def test_compile_warning_for_loss_missing_output(self): 1692 with self.cached_session(): 1693 inp = layers_module.Input(shape=(16,), name='input_a') 1694 out_1 = layers_module.Dense(8, name='dense_1')(inp) 1695 out_2 = layers_module.Dense( 1696 3, activation='softmax', name='dense_2')( 1697 out_1) 1698 model = training_module.Model(inputs=[inp], outputs=[out_1, out_2]) 1699 optimizer = RMSPropOptimizer(learning_rate=0.001) 1700 1701 model.compile( 1702 optimizer, 1703 loss={ 1704 'dense_2': 'categorical_crossentropy', 1705 }, 1706 metrics={ 1707 'dense_2': 'categorical_accuracy', 1708 'dense_1': metrics_module.CategoricalAccuracy(), 1709 }, 1710 run_eagerly=testing_utils.should_run_eagerly()) 1711 1712 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1713 def test_predict_error_with_empty_x(self): 1714 inputs = layers_module.Input(shape=(2,)) 1715 outputs = layers_module.Dense(4)(inputs) 1716 model = training_module.Model(inputs=inputs, outputs=outputs) 1717 model.compile(loss='mse') 1718 1719 with self.assertRaisesRegex(ValueError, 1720 'Expect x to be a non-empty array or dataset.'): 1721 model.predict(np.array([])) 1722 1723 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 1724 def test_on_batch_error_inconsistent_batch_size(self): 1725 input_node1 = layers_module.Input(shape=(5,)) 1726 input_node2 = layers_module.Input(shape=(5,)) 1727 output_node = layers_module.Concatenate()([input_node1, input_node2]) 1728 output_node = layers_module.Dense(4)(output_node) 1729 model = training_module.Model([input_node1, input_node2], output_node) 1730 model.compile(loss='mse') 1731 1732 with self.assertRaisesRegex(ValueError, 'Data cardinality is ambiguous'): 1733 model.train_on_batch([np.ones((10, 5)), np.ones((10, 5))], 1734 np.ones((11, 4))) 1735 1736 with self.assertRaisesRegex(ValueError, 'Data cardinality is ambiguous'): 1737 model.test_on_batch([np.ones((10, 5)), np.ones((10, 5))], 1738 np.ones((11, 4))) 1739 1740 with self.assertRaisesRegex(ValueError, 'Data cardinality is ambiguous'): 1741 model.predict_on_batch([np.ones((10, 5)), np.ones((11, 5))]) 1742 1743 1744class LossWeightingTest(keras_parameterized.TestCase): 1745 1746 @keras_parameterized.run_all_keras_modes 1747 def test_class_weights(self): 1748 num_classes = 5 1749 batch_size = 5 1750 epochs = 10 1751 weighted_class = 3 1752 weight = .5 1753 train_samples = 1000 1754 test_samples = 1000 1755 input_dim = 5 1756 learning_rate = 0.001 1757 1758 model = testing_utils.get_small_sequential_mlp( 1759 num_hidden=10, num_classes=num_classes, input_dim=input_dim) 1760 model.compile( 1761 loss='categorical_crossentropy', 1762 metrics=['acc', metrics_module.CategoricalAccuracy()], 1763 weighted_metrics=['mae', metrics_module.CategoricalAccuracy()], 1764 optimizer=RMSPropOptimizer(learning_rate=learning_rate), 1765 run_eagerly=testing_utils.should_run_eagerly()) 1766 1767 np.random.seed(1337) 1768 (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data( 1769 train_samples=train_samples, 1770 test_samples=test_samples, 1771 input_shape=(input_dim,), 1772 num_classes=num_classes) 1773 int_y_test = y_test.copy() 1774 # convert class vectors to binary class matrices 1775 y_train = np_utils.to_categorical(y_train, num_classes) 1776 y_test = np_utils.to_categorical(y_test, num_classes) 1777 test_ids = np.where(int_y_test == np.array(weighted_class))[0] 1778 1779 class_weight = dict([(i, 1.) for i in range(num_classes)]) 1780 class_weight[weighted_class] = weight 1781 1782 model.fit( 1783 x_train, 1784 y_train, 1785 batch_size=batch_size, 1786 epochs=epochs // 3, 1787 verbose=0, 1788 class_weight=class_weight, 1789 validation_data=(x_train, y_train)) 1790 model.fit( 1791 x_train, 1792 y_train, 1793 batch_size=batch_size, 1794 epochs=epochs // 2, 1795 verbose=0, 1796 class_weight=class_weight) 1797 model.fit( 1798 x_train, 1799 y_train, 1800 batch_size=batch_size, 1801 epochs=epochs // 2, 1802 verbose=0, 1803 class_weight=class_weight, 1804 validation_split=0.1) 1805 1806 model.train_on_batch( 1807 x_train[:batch_size], y_train[:batch_size], class_weight=class_weight) 1808 ref_score = model.evaluate(x_test, y_test, verbose=0) # pylint: disable=unused-variable 1809 score = model.evaluate( # pylint: disable=unused-variable 1810 x_test[test_ids, :], y_test[test_ids, :], verbose=0) 1811 # TODO(b/152990697): Fix the class weights test here. 1812 # self.assertLess(score[0], ref_score[0]) 1813 1814 @keras_parameterized.run_all_keras_modes 1815 def test_temporal_sample_weights(self): 1816 num_classes = 5 1817 batch_size = 5 1818 epochs = 10 1819 weighted_class = 3 1820 weight = 10. 1821 train_samples = 1000 1822 test_samples = 1000 1823 input_dim = 5 1824 timesteps = 3 1825 learning_rate = 0.001 1826 1827 with self.cached_session(): 1828 model = sequential.Sequential() 1829 model.add( 1830 layers_module.TimeDistributed( 1831 layers_module.Dense(num_classes), 1832 input_shape=(timesteps, input_dim))) 1833 model.add(layers_module.Activation('softmax')) 1834 1835 np.random.seed(1337) 1836 (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data( 1837 train_samples=train_samples, 1838 test_samples=test_samples, 1839 input_shape=(input_dim,), 1840 num_classes=num_classes) 1841 int_y_test = y_test.copy() 1842 int_y_train = y_train.copy() 1843 # convert class vectors to binary class matrices 1844 y_train = np_utils.to_categorical(y_train, num_classes) 1845 y_test = np_utils.to_categorical(y_test, num_classes) 1846 test_ids = np.where(int_y_test == np.array(weighted_class))[0] 1847 1848 sample_weight = np.ones((y_train.shape[0])) 1849 sample_weight[int_y_train == weighted_class] = weight 1850 1851 temporal_x_train = np.reshape(x_train, (len(x_train), 1, 1852 x_train.shape[1])) 1853 temporal_x_train = np.repeat(temporal_x_train, timesteps, axis=1) 1854 temporal_x_test = np.reshape(x_test, (len(x_test), 1, x_test.shape[1])) 1855 temporal_x_test = np.repeat(temporal_x_test, timesteps, axis=1) 1856 1857 temporal_y_train = np.reshape(y_train, (len(y_train), 1, 1858 y_train.shape[1])) 1859 temporal_y_train = np.repeat(temporal_y_train, timesteps, axis=1) 1860 temporal_y_test = np.reshape(y_test, (len(y_test), 1, y_test.shape[1])) 1861 temporal_y_test = np.repeat(temporal_y_test, timesteps, axis=1) 1862 1863 temporal_sample_weight = np.reshape(sample_weight, (len(sample_weight), 1864 1)) 1865 temporal_sample_weight = np.repeat( 1866 temporal_sample_weight, timesteps, axis=1) 1867 1868 model.compile( 1869 RMSPropOptimizer(learning_rate=learning_rate), 1870 loss='categorical_crossentropy', 1871 metrics=['acc', metrics_module.CategoricalAccuracy()], 1872 weighted_metrics=['mae', metrics_module.CategoricalAccuracy()], 1873 sample_weight_mode='temporal', 1874 run_eagerly=testing_utils.should_run_eagerly()) 1875 1876 model.fit( 1877 temporal_x_train, 1878 temporal_y_train, 1879 batch_size=batch_size, 1880 epochs=epochs // 3, 1881 verbose=0, 1882 sample_weight=temporal_sample_weight) 1883 model.fit( 1884 temporal_x_train, 1885 temporal_y_train, 1886 batch_size=batch_size, 1887 epochs=epochs // 3, 1888 verbose=0, 1889 sample_weight=temporal_sample_weight, 1890 validation_split=0.1) 1891 1892 model.train_on_batch( 1893 temporal_x_train[:batch_size], 1894 temporal_y_train[:batch_size], 1895 sample_weight=temporal_sample_weight[:batch_size]) 1896 model.test_on_batch( 1897 temporal_x_train[:batch_size], 1898 temporal_y_train[:batch_size], 1899 sample_weight=temporal_sample_weight[:batch_size]) 1900 ref_score = model.evaluate(temporal_x_test, temporal_y_test, verbose=0) 1901 if not context.executing_eagerly(): 1902 score = model.evaluate( 1903 temporal_x_test[test_ids], temporal_y_test[test_ids], verbose=0) 1904 self.assertLess(score[0], ref_score[0]) 1905 1906 @keras_parameterized.run_all_keras_modes 1907 @keras_parameterized.run_with_all_model_types(exclude_models='sequential') 1908 def test_fit_with_incorrect_weights(self): 1909 input_a = layers_module.Input(shape=(3,), name='input_a') 1910 input_b = layers_module.Input(shape=(3,), name='input_b') 1911 1912 dense = layers_module.Dense(2, name='output_1') 1913 dropout = layers_module.Dropout(0.5, name='output_2') 1914 branch_a = [input_a, dense] 1915 branch_b = [input_b, dense, dropout] 1916 1917 model = testing_utils.get_multi_io_model(branch_a, branch_b) 1918 model.compile( 1919 optimizer='adam', 1920 loss='mse', 1921 run_eagerly=testing_utils.should_run_eagerly()) 1922 x = np.random.random((10, 3)) 1923 y = np.random.random((10, 2)) 1924 1925 with self.assertRaises(ValueError): 1926 model.fit([x, x], [y, y], epochs=1, sample_weight={'unknown': x}) 1927 1928 with self.assertRaises(ValueError): 1929 model.fit([x, x], [y, y], epochs=1, class_weight={'unknown': 1}) 1930 1931 @keras_parameterized.run_all_keras_modes 1932 def test_default_sample_weight(self): 1933 """Verifies that fit works without having to set sample_weight.""" 1934 num_classes = 5 1935 input_dim = 5 1936 timesteps = 3 1937 learning_rate = 0.001 1938 1939 with self.cached_session(): 1940 model = sequential.Sequential() 1941 model.add( 1942 layers_module.TimeDistributed( 1943 layers_module.Dense(num_classes), 1944 input_shape=(timesteps, input_dim))) 1945 1946 x = np.random.random((10, timesteps, input_dim)) 1947 y = np.random.random((10, timesteps, num_classes)) 1948 optimizer = RMSPropOptimizer(learning_rate=learning_rate) 1949 1950 # sample_weight_mode is a list and mode value is None 1951 model.compile( 1952 optimizer, 1953 loss='mse', 1954 sample_weight_mode=[None], 1955 run_eagerly=testing_utils.should_run_eagerly()) 1956 model.fit(x, y, epochs=1, batch_size=10) 1957 1958 # sample_weight_mode is a list and mode value is `temporal` 1959 model.compile( 1960 optimizer, 1961 loss='mse', 1962 sample_weight_mode=['temporal'], 1963 run_eagerly=testing_utils.should_run_eagerly()) 1964 model.fit(x, y, epochs=1, batch_size=10) 1965 1966 # sample_weight_mode is a dict and mode value is None 1967 model.compile( 1968 optimizer, 1969 loss='mse', 1970 sample_weight_mode={'time_distributed': None}, 1971 run_eagerly=testing_utils.should_run_eagerly()) 1972 model.fit(x, y, epochs=1, batch_size=10) 1973 1974 # sample_weight_mode is a dict and mode value is `temporal` 1975 model.compile( 1976 optimizer, 1977 loss='mse', 1978 sample_weight_mode={'time_distributed': 'temporal'}, 1979 run_eagerly=testing_utils.should_run_eagerly()) 1980 model.fit(x, y, epochs=1, batch_size=10) 1981 1982 # sample_weight_mode is a not a list/dict and mode value is None 1983 model.compile( 1984 optimizer, 1985 loss='mse', 1986 sample_weight_mode=None, 1987 run_eagerly=testing_utils.should_run_eagerly()) 1988 model.fit(x, y, epochs=1, batch_size=10) 1989 1990 # sample_weight_mode is a not a list/dict and mode value is `temporal` 1991 model.compile( 1992 optimizer, 1993 loss='mse', 1994 sample_weight_mode='temporal', 1995 run_eagerly=testing_utils.should_run_eagerly()) 1996 model.fit(x, y, epochs=1, batch_size=10) 1997 1998 def test_sample_weight_tensor(self): 1999 """Tests that sample weight may be defined as a tensor in the graph.""" 2000 with ops.get_default_graph().as_default(): 2001 # Create a simple pass-through model 2002 inputs = layers_module.Input(shape=1, name='input_layer') 2003 model = training_module.Model(inputs=inputs, outputs=inputs) 2004 model.compile( 2005 loss='mean_absolute_error', 2006 optimizer='adam') 2007 2008 # Prepare sample weights iterator tensor 2009 sample_weights = array_ops.constant( 2010 [[0, .4, 1, 1], [2, .4, .3, 1]]) 2011 dataset = dataset_ops.Dataset.from_tensor_slices(sample_weights) 2012 sample_weights = dataset_ops.make_one_shot_iterator(dataset).get_next() 2013 sample_weights = training_utils_v1.standardize_sample_weights( 2014 sample_weights, model.output_names) 2015 2016 # Update model loss with sample weight tensor. 2017 model._compile_weights_loss_and_weighted_metrics(sample_weights) 2018 2019 feeds = {'input_layer:0': [[0], [0], [0], [0]], 2020 'input_layer_target:0': [[1], [1], [1], [1]]} 2021 with self.cached_session() as sess: 2022 self.assertAllClose( 2023 (.4 + 1 + 1) / 4, sess.run(model.total_loss, feed_dict=feeds)) 2024 self.assertAllClose( 2025 (2+ .4 + .3 + 1) / 4, sess.run(model.total_loss, feed_dict=feeds)) 2026 2027 2028@keras_parameterized.run_all_keras_modes 2029class MaskingTest(keras_parameterized.TestCase): 2030 2031 def _get_model(self, input_shape=None): 2032 layers = [ 2033 layers_module.Masking(mask_value=0), 2034 layers_module.TimeDistributed( 2035 layers_module.Dense(1, kernel_initializer='one')) 2036 ] 2037 model = testing_utils.get_model_from_layers(layers, input_shape) 2038 model.compile( 2039 loss='mse', 2040 optimizer=RMSPropOptimizer(learning_rate=0.001), 2041 run_eagerly=testing_utils.should_run_eagerly()) 2042 return model 2043 2044 @keras_parameterized.run_with_all_model_types 2045 def test_masking(self): 2046 model = self._get_model(input_shape=(2, 1)) 2047 x = np.array([[[1], [1]], [[0], [0]]]) 2048 y = np.array([[[1], [1]], [[1], [1]]]) 2049 loss = model.train_on_batch(x, y) 2050 self.assertEqual(loss, 0) 2051 2052 @keras_parameterized.run_with_all_model_types(exclude_models='functional') 2053 def test_masking_deferred(self): 2054 model = self._get_model() 2055 x = np.array([[[1], [1]], [[0], [0]]]) 2056 y = np.array([[[1], [1]], [[1], [1]]]) 2057 loss = model.train_on_batch(x, y) 2058 self.assertEqual(loss, 0) 2059 2060 def test_mask_argument_in_layer(self): 2061 # Test that the mask argument gets correctly passed to a layer in the 2062 # functional API. 2063 2064 class CustomMaskedLayer(layers_module.Layer): 2065 2066 def __init__(self): 2067 super(CustomMaskedLayer, self).__init__() 2068 self.supports_masking = True 2069 2070 def call(self, inputs, mask=None): 2071 assert mask is not None 2072 return inputs 2073 2074 def compute_output_shape(self, input_shape): 2075 return input_shape 2076 2077 x = np.random.random((5, 3)) 2078 inputs = layers_module.Input((3,)) 2079 masked = layers_module.Masking(mask_value=0)(inputs) 2080 outputs = CustomMaskedLayer()(masked) 2081 2082 model = training_module.Model(inputs, outputs) 2083 model.compile( 2084 loss='mse', 2085 optimizer=RMSPropOptimizer(learning_rate=0.001), 2086 run_eagerly=testing_utils.should_run_eagerly()) 2087 y = np.random.random((5, 3)) 2088 model.train_on_batch(x, y) 2089 2090 2091@keras_parameterized.run_all_keras_modes 2092class TestDynamicTrainability(keras_parameterized.TestCase): 2093 2094 def test_trainable_warning(self): 2095 x = np.random.random((5, 3)) 2096 y = np.random.random((5, 2)) 2097 2098 model = sequential.Sequential() 2099 model.add(layers_module.Dense(2, input_dim=3)) 2100 model.trainable = False 2101 model.compile( 2102 'rmsprop', 2103 'mse', 2104 run_eagerly=testing_utils.should_run_eagerly()) 2105 model.trainable = True 2106 model.train_on_batch(x, y) 2107 self.assertRaises(Warning) 2108 2109 def test_trainable_argument(self): 2110 with self.cached_session(): 2111 x = np.random.random((5, 3)) 2112 y = np.random.random((5, 2)) 2113 2114 model = sequential.Sequential() 2115 model.add(layers_module.Dense(2, input_dim=3, trainable=False)) 2116 model.compile( 2117 'rmsprop', 2118 'mse', 2119 run_eagerly=testing_utils.should_run_eagerly()) 2120 out = model.predict(x) 2121 model.train_on_batch(x, y) 2122 out_2 = model.predict(x) 2123 self.assertAllClose(out, out_2) 2124 2125 # test with nesting 2126 inputs = layers_module.Input(shape=(3,)) 2127 output = model(inputs) 2128 model = training_module.Model(inputs, output) 2129 model.compile( 2130 'rmsprop', 2131 'mse', 2132 run_eagerly=testing_utils.should_run_eagerly()) 2133 out = model.predict(x) 2134 model.train_on_batch(x, y) 2135 out_2 = model.predict(x) 2136 self.assertAllClose(out, out_2) 2137 2138 def test_layer_trainability_switch(self): 2139 # with constructor argument, in Sequential 2140 model = sequential.Sequential() 2141 model.add(layers_module.Dense(2, trainable=False, input_dim=1)) 2142 self.assertListEqual(model.trainable_weights, []) 2143 2144 # by setting the `trainable` argument, in Sequential 2145 model = sequential.Sequential() 2146 layer = layers_module.Dense(2, input_dim=1) 2147 model.add(layer) 2148 self.assertListEqual(model.trainable_weights, layer.trainable_weights) 2149 layer.trainable = False 2150 self.assertListEqual(model.trainable_weights, []) 2151 2152 # with constructor argument, in Model 2153 x = layers_module.Input(shape=(1,)) 2154 y = layers_module.Dense(2, trainable=False)(x) 2155 model = training_module.Model(x, y) 2156 self.assertListEqual(model.trainable_weights, []) 2157 2158 # by setting the `trainable` argument, in Model 2159 x = layers_module.Input(shape=(1,)) 2160 layer = layers_module.Dense(2) 2161 y = layer(x) 2162 model = training_module.Model(x, y) 2163 self.assertListEqual(model.trainable_weights, layer.trainable_weights) 2164 layer.trainable = False 2165 self.assertListEqual(model.trainable_weights, []) 2166 2167 def test_model_trainability_switch(self): 2168 # a non-trainable model has no trainable weights 2169 x = layers_module.Input(shape=(1,)) 2170 y = layers_module.Dense(2)(x) 2171 model = training_module.Model(x, y) 2172 model.trainable = False 2173 self.assertListEqual(model.trainable_weights, []) 2174 2175 # same for Sequential 2176 model = sequential.Sequential() 2177 model.add(layers_module.Dense(2, input_dim=1)) 2178 model.trainable = False 2179 self.assertListEqual(model.trainable_weights, []) 2180 2181 def test_nested_model_trainability(self): 2182 # a Sequential inside a Model 2183 inner_model = sequential.Sequential() 2184 inner_model.add(layers_module.Dense(2, input_dim=1)) 2185 2186 x = layers_module.Input(shape=(1,)) 2187 y = inner_model(x) 2188 outer_model = training_module.Model(x, y) 2189 self.assertListEqual(outer_model.trainable_weights, 2190 inner_model.trainable_weights) 2191 inner_model.trainable = False 2192 self.assertListEqual(outer_model.trainable_weights, []) 2193 inner_model.trainable = True 2194 inner_model.layers[-1].trainable = False 2195 self.assertListEqual(outer_model.trainable_weights, []) 2196 2197 # a Sequential inside a Sequential 2198 inner_model = sequential.Sequential() 2199 inner_model.add(layers_module.Dense(2, input_dim=1)) 2200 outer_model = sequential.Sequential() 2201 outer_model.add(inner_model) 2202 self.assertListEqual(outer_model.trainable_weights, 2203 inner_model.trainable_weights) 2204 inner_model.trainable = False 2205 self.assertListEqual(outer_model.trainable_weights, []) 2206 inner_model.trainable = True 2207 inner_model.layers[-1].trainable = False 2208 self.assertListEqual(outer_model.trainable_weights, []) 2209 2210 # a Model inside a Model 2211 x = layers_module.Input(shape=(1,)) 2212 y = layers_module.Dense(2)(x) 2213 inner_model = training_module.Model(x, y) 2214 x = layers_module.Input(shape=(1,)) 2215 y = inner_model(x) 2216 outer_model = training_module.Model(x, y) 2217 self.assertListEqual(outer_model.trainable_weights, 2218 inner_model.trainable_weights) 2219 inner_model.trainable = False 2220 self.assertListEqual(outer_model.trainable_weights, []) 2221 inner_model.trainable = True 2222 inner_model.layers[-1].trainable = False 2223 self.assertListEqual(outer_model.trainable_weights, []) 2224 2225 # a Model inside a Sequential 2226 x = layers_module.Input(shape=(1,)) 2227 y = layers_module.Dense(2)(x) 2228 inner_model = training_module.Model(x, y) 2229 outer_model = sequential.Sequential() 2230 outer_model.add(inner_model) 2231 self.assertListEqual(outer_model.trainable_weights, 2232 inner_model.trainable_weights) 2233 inner_model.trainable = False 2234 self.assertListEqual(outer_model.trainable_weights, []) 2235 inner_model.trainable = True 2236 inner_model.layers[-1].trainable = False 2237 self.assertListEqual(outer_model.trainable_weights, []) 2238 2239 def test_gan_workflow(self): 2240 shared_layer = layers_module.BatchNormalization() 2241 2242 inputs1 = input_layer.Input(10) 2243 outputs1 = shared_layer(inputs1) 2244 model1 = training_module.Model(inputs1, outputs1) 2245 shared_layer.trainable = False 2246 model1.compile( 2247 'sgd', 2248 'mse', 2249 run_eagerly=testing_utils.should_run_eagerly()) 2250 2251 inputs2 = input_layer.Input(10) 2252 outputs2 = shared_layer(inputs2) 2253 model2 = training_module.Model(inputs2, outputs2) 2254 shared_layer.trainable = True 2255 model2.compile( 2256 'sgd', 2257 'mse', 2258 run_eagerly=testing_utils.should_run_eagerly()) 2259 2260 x, y = np.ones((10, 10)), np.ones((10, 10)) 2261 2262 out1_0 = model1.predict_on_batch(x) 2263 model1.train_on_batch(x, y) 2264 out1_1 = model1.predict_on_batch(x) 2265 self.assertAllClose(out1_0, out1_1) 2266 2267 out2_0 = model2.predict_on_batch(x) 2268 model2.train_on_batch(x, y) 2269 out2_1 = model2.predict_on_batch(x) 2270 self.assertNotAllClose(out2_0, out2_1) 2271 2272 def test_toggle_value(self): 2273 input_0 = layers_module.Input(shape=(1,)) 2274 dense_0 = layers_module.Dense( 2275 1, kernel_initializer='ones', bias_initializer='ones') 2276 dense_1 = layers_module.Dense( 2277 1, kernel_initializer='ones', bias_initializer='ones') 2278 result = layers_module.Add()([dense_0(input_0), dense_1(input_0)]) 2279 model = training_module.Model(input_0, result) 2280 dense_0.trainable = False 2281 model.compile( 2282 'sgd', 2283 'mse', 2284 run_eagerly=testing_utils.should_run_eagerly()) 2285 2286 x = np.ones((10, 1)) 2287 y = 5 * x + 2 2288 model.train_on_batch(x, y) 2289 dense_0.trainable = True 2290 model.train_on_batch(x, y) 2291 kernel, bias = dense_0.get_weights() 2292 self.assertAllEqual([kernel[0, 0], bias[0]], [1., 1.]) 2293 2294 kernel, bias = dense_1.get_weights() 2295 self.assertAllClose([kernel[0, 0], bias[0]], [1.1176, 1.1176]) 2296 2297 2298class TestTrainingWithDataTensors(keras_parameterized.TestCase): 2299 2300 def test_training_and_eval_methods_on_symbolic_tensors_single_io(self): 2301 with ops.Graph().as_default(): 2302 x = layers_module.Input(shape=(3,), name='input') 2303 y = layers_module.Dense(4, name='dense')(x) 2304 model = training_module.Model(x, y) 2305 2306 optimizer = RMSPropOptimizer(learning_rate=0.001) 2307 loss = 'mse' 2308 model.compile( 2309 optimizer, 2310 loss, 2311 metrics=['mae', metrics_module.CategoricalAccuracy()]) 2312 2313 inputs = backend.zeros(shape=(10, 3)) 2314 targets = backend.zeros(shape=(10, 4)) 2315 2316 model.fit(inputs, targets, epochs=1, steps_per_epoch=2, verbose=0) 2317 model.evaluate(inputs, targets, steps=2, verbose=0) 2318 model.predict(inputs, steps=2) 2319 model.train_on_batch(inputs, targets) 2320 model.test_on_batch(inputs, targets) 2321 model.fit(inputs, targets, 2322 epochs=1, steps_per_epoch=2, verbose=0, 2323 validation_data=(inputs, targets), validation_steps=2) 2324 2325 # Test with dynamic shape 2326 inputs = array_ops.placeholder_with_default( 2327 np.zeros((2, 3)), shape=tensor_shape.TensorShape([None, 3])) 2328 targets = array_ops.placeholder_with_default( 2329 np.zeros((2, 4)), shape=tensor_shape.TensorShape([None, 4])) 2330 self.assertEqual(inputs.shape.dims[0].value, None) 2331 model.fit(inputs, targets, epochs=1, steps_per_epoch=2, verbose=0) 2332 model.evaluate(inputs, targets, steps=2, verbose=0) 2333 model.predict(inputs, steps=2) 2334 model.train_on_batch(inputs, targets) 2335 model.test_on_batch(inputs, targets) 2336 model.fit(inputs, targets, 2337 epochs=1, steps_per_epoch=2, verbose=0, 2338 validation_data=(inputs, targets), validation_steps=2) 2339 2340 def test_training_and_eval_methods_on_symbolic_tensors_multi_io(self): 2341 a = layers_module.Input(shape=(3,), name='input_a') 2342 b = layers_module.Input(shape=(3,), name='input_b') 2343 2344 dense = layers_module.Dense(4, name='dense') 2345 c = dense(a) 2346 d = dense(b) 2347 e = layers_module.Dropout(0.5, name='dropout')(c) 2348 2349 model = training_module.Model([a, b], [d, e]) 2350 2351 optimizer = 'rmsprop' 2352 loss = 'mse' 2353 loss_weights = [1., 0.5] 2354 model.compile( 2355 optimizer, 2356 loss, 2357 metrics=['mae', metrics_module.CategoricalAccuracy()], 2358 loss_weights=loss_weights) 2359 2360 input_a_tf = array_ops.zeros(shape=(10, 3)) 2361 input_b_tf = array_ops.zeros(shape=(10, 3)) 2362 2363 output_d_tf = array_ops.zeros(shape=(10, 4)) 2364 output_e_tf = array_ops.zeros(shape=(10, 4)) 2365 2366 model.fit([input_a_tf, input_b_tf], [output_d_tf, output_e_tf], 2367 epochs=1, 2368 steps_per_epoch=2, 2369 verbose=0) 2370 model.train_on_batch([input_a_tf, input_b_tf], [output_d_tf, output_e_tf]) 2371 2372 # Test with dictionary inputs 2373 model.fit({ 2374 'input_a': input_a_tf, 2375 'input_b': input_b_tf 2376 }, { 2377 'dense': output_d_tf, 2378 'dropout': output_e_tf 2379 }, 2380 epochs=1, 2381 steps_per_epoch=2, 2382 verbose=0) 2383 model.fit({ 2384 'input_a': input_a_tf, 2385 'input_b': input_b_tf 2386 }, { 2387 'dense': output_d_tf, 2388 'dropout': output_e_tf 2389 }, 2390 validation_data=({ 2391 'input_a': input_a_tf, 2392 'input_b': input_b_tf 2393 }, { 2394 'dense': output_d_tf, 2395 'dropout': output_e_tf 2396 }), 2397 epochs=1, 2398 steps_per_epoch=2, 2399 validation_steps=2, 2400 verbose=0) 2401 model.train_on_batch({ 2402 'input_a': input_a_tf, 2403 'input_b': input_b_tf 2404 }, { 2405 'dense': output_d_tf, 2406 'dropout': output_e_tf 2407 }) 2408 2409 # Test with validation data 2410 model.fit([input_a_tf, input_b_tf], [output_d_tf, output_e_tf], 2411 validation_data=([input_a_tf, 2412 input_b_tf], [output_d_tf, output_e_tf]), 2413 epochs=1, 2414 steps_per_epoch=2, 2415 validation_steps=2, 2416 verbose=0) 2417 # Test evaluation / prediction methods 2418 model.evaluate([input_a_tf, input_b_tf], [output_d_tf, output_e_tf], 2419 steps=2, 2420 verbose=0) 2421 model.predict([input_a_tf, input_b_tf], steps=2) 2422 model.test_on_batch([input_a_tf, input_b_tf], [output_d_tf, output_e_tf]) 2423 2424 @tf_test_util.run_deprecated_v1 2425 def test_model_with_input_feed_tensor(self): 2426 """We test building a model with a TF variable as input. 2427 2428 We should be able to call fit, evaluate, predict, 2429 by only passing them data for the placeholder inputs 2430 in the model. 2431 """ 2432 with ops.Graph().as_default(), self.cached_session(): 2433 input_a_np = np.random.random((10, 3)) 2434 input_b_np = np.random.random((10, 3)) 2435 2436 output_a_np = np.random.random((10, 4)) 2437 output_b_np = np.random.random((10, 3)) 2438 2439 input_v = variables_module.Variable(input_a_np, dtype='float32') 2440 self.evaluate(variables_module.variables_initializer([input_v])) 2441 a = input_layer.Input(tensor=input_v) 2442 b = input_layer.Input(shape=(3,), name='input_b') 2443 2444 a_2 = layers_module.Dense(4, name='dense_1')(a) 2445 dp = layers_module.Dropout(0.5, name='dropout') 2446 b_2 = dp(b) 2447 2448 model = training_module.Model([a, b], [a_2, b_2]) 2449 model.summary() 2450 2451 optimizer = 'rmsprop' 2452 loss = 'mse' 2453 loss_weights = [1., 0.5] 2454 model.compile(optimizer, loss, metrics=['mean_squared_error'], 2455 loss_weights=loss_weights, 2456 sample_weight_mode=None) 2457 2458 # test train_on_batch 2459 out = model.train_on_batch(input_b_np, 2460 [output_a_np, output_b_np]) 2461 out = model.train_on_batch({'input_b': input_b_np}, 2462 [output_a_np, output_b_np]) 2463 out = model.test_on_batch({'input_b': input_b_np}, 2464 [output_a_np, output_b_np]) 2465 out = model.predict_on_batch({'input_b': input_b_np}) 2466 2467 # test fit 2468 out = model.fit({'input_b': input_b_np}, 2469 [output_a_np, output_b_np], epochs=1, batch_size=10) 2470 out = model.fit(input_b_np, 2471 [output_a_np, output_b_np], epochs=1, batch_size=10) 2472 2473 # test evaluate 2474 out = model.evaluate({'input_b': input_b_np}, 2475 [output_a_np, output_b_np], batch_size=10) 2476 out = model.evaluate(input_b_np, 2477 [output_a_np, output_b_np], batch_size=10) 2478 2479 # test predict 2480 out = model.predict({'input_b': input_b_np}, batch_size=10) 2481 out = model.predict(input_b_np, batch_size=10) 2482 self.assertEqual(len(out), 2) 2483 2484 # Now test a model with a single input 2485 # i.e. we don't pass any data to fit the model. 2486 self.evaluate(variables_module.variables_initializer([input_v])) 2487 a = input_layer.Input(tensor=input_v) 2488 a_2 = layers_module.Dense(4, name='dense_1')(a) 2489 a_2 = layers_module.Dropout(0.5, name='dropout')(a_2) 2490 model = training_module.Model(a, a_2) 2491 model.summary() 2492 2493 optimizer = 'rmsprop' 2494 loss = 'mse' 2495 model.compile(optimizer, loss, metrics=['mean_squared_error']) 2496 2497 # test train_on_batch 2498 out = model.train_on_batch(None, 2499 output_a_np) 2500 out = model.train_on_batch(None, 2501 output_a_np) 2502 out = model.test_on_batch(None, 2503 output_a_np) 2504 out = model.predict_on_batch(None) 2505 out = model.train_on_batch([], 2506 output_a_np) 2507 out = model.train_on_batch({}, 2508 output_a_np) 2509 2510 # test fit 2511 _ = model.fit(None, output_a_np, epochs=1, steps_per_epoch=3) 2512 _ = model.fit(None, output_a_np, epochs=1, steps_per_epoch=3) 2513 2514 # test evaluate 2515 _ = model.evaluate(None, output_a_np, steps=3) 2516 _ = model.evaluate(None, output_a_np, steps=3) 2517 2518 # test predict 2519 out = model.predict(None, steps=3) 2520 out = model.predict(None, steps=3) 2521 self.assertEqual(out.shape, (10 * 3, 4)) 2522 2523 # Same, without learning phase 2524 # i.e. we don't pass any data to fit the model. 2525 self.evaluate(variables_module.variables_initializer([input_v])) 2526 a = input_layer.Input(tensor=input_v) 2527 a_2 = layers_module.Dense(4, name='dense_1')(a) 2528 model = training_module.Model(a, a_2) 2529 model.summary() 2530 2531 optimizer = 'rmsprop' 2532 loss = 'mse' 2533 model.compile(optimizer, loss, metrics=['mean_squared_error']) 2534 2535 # test train_on_batch 2536 out = model.train_on_batch(None, 2537 output_a_np) 2538 out = model.train_on_batch(None, 2539 output_a_np) 2540 out = model.test_on_batch(None, 2541 output_a_np) 2542 out = model.predict_on_batch(None) 2543 out = model.train_on_batch([], 2544 output_a_np) 2545 out = model.train_on_batch({}, 2546 output_a_np) 2547 2548 # test fit 2549 _ = model.fit(None, output_a_np, epochs=1, steps_per_epoch=10) 2550 _ = model.fit(None, output_a_np, epochs=1, steps_per_epoch=10) 2551 2552 # test evaluate 2553 _ = model.evaluate(None, output_a_np, steps=10) 2554 _ = model.evaluate(None, output_a_np, steps=10) 2555 2556 # test predict 2557 out = model.predict(None, steps=3) 2558 out = model.predict(None, steps=3) 2559 self.assertEqual(out.shape, (10 * 3, 4)) 2560 2561 @keras_parameterized.run_all_keras_modes 2562 def test_model_with_partial_loss(self): 2563 with self.cached_session(): 2564 a = input_layer.Input(shape=(3,), name='input_a') 2565 a_2 = layers_module.Dense(4, name='dense_1')(a) 2566 dp = layers_module.Dropout(0.5, name='dropout') 2567 a_3 = dp(a_2) 2568 model = training_module.Model(a, [a_2, a_3]) 2569 2570 optimizer = 'rmsprop' 2571 loss = {'dropout': 'mse'} 2572 model.compile(optimizer, loss, metrics=['mae']) 2573 2574 input_a_np = np.random.random((10, 3)) 2575 output_a_np = np.random.random((10, 4)) 2576 2577 # test train_on_batch 2578 _ = model.train_on_batch(input_a_np, output_a_np) 2579 _ = model.test_on_batch(input_a_np, output_a_np) 2580 # fit 2581 _ = model.fit(input_a_np, output_a_np) 2582 # evaluate 2583 _ = model.evaluate(input_a_np, output_a_np) 2584 2585 # Same without dropout. 2586 a = input_layer.Input(shape=(3,), name='input_a') 2587 a_2 = layers_module.Dense(4, name='dense_1')(a) 2588 a_3 = layers_module.Dense(4, name='dense_2')(a_2) 2589 model = training_module.Model(a, [a_2, a_3]) 2590 2591 optimizer = 'rmsprop' 2592 loss = {'dense_2': 'mse'} 2593 model.compile(optimizer, loss, metrics={'dense_1': 'mae'}) 2594 2595 # test train_on_batch 2596 _ = model.train_on_batch(input_a_np, output_a_np) 2597 _ = model.test_on_batch(input_a_np, output_a_np) 2598 # fit 2599 _ = model.fit(input_a_np, output_a_np) 2600 # evaluate 2601 _ = model.evaluate(input_a_np, output_a_np) 2602 2603 def test_model_with_external_loss(self): 2604 with ops.Graph().as_default(), self.cached_session(): 2605 # None loss, only regularization loss. 2606 a = input_layer.Input(shape=(3,), name='input_a') 2607 a_2 = layers_module.Dense( 2608 4, name='dense_1', kernel_regularizer='l1', bias_regularizer='l2')( 2609 a) 2610 dp = layers_module.Dropout(0.5, name='dropout') 2611 a_3 = dp(a_2) 2612 2613 model = training_module.Model(a, [a_2, a_3]) 2614 2615 optimizer = 'rmsprop' 2616 loss = None 2617 model.compile(optimizer, loss, metrics=['mae']) 2618 2619 input_a_np = np.random.random((10, 3)) 2620 2621 # test train_on_batch 2622 out = model.train_on_batch(input_a_np, None) 2623 out = model.test_on_batch(input_a_np, None) 2624 # fit 2625 out = model.fit(input_a_np, None) 2626 # evaluate 2627 out = model.evaluate(input_a_np, None) 2628 2629 # No dropout, external loss. 2630 a = input_layer.Input(shape=(3,), name='input_a') 2631 a_2 = layers_module.Dense(4, name='dense_1')(a) 2632 a_3 = layers_module.Dense(4, name='dense_2')(a) 2633 2634 model = training_module.Model(a, [a_2, a_3]) 2635 model.add_loss(backend.mean(a_3 + a_2)) 2636 2637 optimizer = 'rmsprop' 2638 loss = None 2639 model.compile(optimizer, loss, metrics=['mae']) 2640 2641 # test train_on_batch 2642 out = model.train_on_batch(input_a_np, None) 2643 out = model.test_on_batch(input_a_np, None) 2644 # fit 2645 out = model.fit(input_a_np, None) 2646 # evaluate 2647 out = model.evaluate(input_a_np, None) 2648 2649 # Test model with no external data at all. 2650 input_v = variables_module.Variable(input_a_np, dtype='float32') 2651 self.evaluate(variables_module.variables_initializer([input_v])) 2652 a = input_layer.Input(tensor=input_v) 2653 a_2 = layers_module.Dense(4, name='dense_1')(a) 2654 a_2 = layers_module.Dropout(0.5, name='dropout')(a_2) 2655 model = training_module.Model(a, a_2) 2656 model.add_loss(backend.mean(a_2)) 2657 2658 model.compile(optimizer='rmsprop', 2659 loss=None, 2660 metrics=['mean_squared_error']) 2661 2662 # test train_on_batch 2663 out = model.train_on_batch(None, None) 2664 out = model.test_on_batch(None, None) 2665 out = model.predict_on_batch(None) 2666 2667 # Test multi-output model with no external data at all. 2668 self.evaluate(variables_module.variables_initializer([input_v])) 2669 a = input_layer.Input(tensor=input_v) 2670 a_1 = layers_module.Dense(4, name='dense_1')(a) 2671 a_2 = layers_module.Dropout(0.5, name='dropout')(a_1) 2672 model = training_module.Model(a, [a_1, a_2]) 2673 model.add_loss(backend.mean(a_2)) 2674 2675 model.compile(optimizer='rmsprop', 2676 loss=None, 2677 metrics=['mean_squared_error']) 2678 2679 # test train_on_batch 2680 out = model.train_on_batch(None, None) 2681 out = model.test_on_batch(None, None) 2682 out = model.predict_on_batch(None) 2683 2684 out = model.predict(None, steps=3) 2685 self.assertEqual(len(out), 2) 2686 self.assertEqual(out[0].shape, (10 * 3, 4)) 2687 self.assertEqual(out[1].shape, (10 * 3, 4)) 2688 2689 def test_target_tensors(self): 2690 with ops.Graph().as_default(), self.cached_session(): 2691 # single-output, as list 2692 model = sequential.Sequential() 2693 model.add(layers_module.Dense(4, input_shape=(4,), name='dense')) 2694 input_val = np.random.random((10, 4)) 2695 target_val = np.random.random((10, 4)) 2696 target = backend.variable(target_val) 2697 model.compile(optimizer='rmsprop', loss='mse', target_tensors=[target]) 2698 model.train_on_batch(input_val, None) 2699 2700 # single-output, as single tensor 2701 model.compile(optimizer='rmsprop', loss='mse', target_tensors=target) 2702 model.train_on_batch(input_val, None) 2703 2704 # single-output, as dict 2705 model.compile(optimizer='rmsprop', loss='mse', 2706 target_tensors={'dense': target}) 2707 model.train_on_batch(input_val, None) 2708 2709 # test invalid arguments 2710 with self.assertRaises(TypeError): 2711 model.compile(optimizer='rmsprop', loss='mse', 2712 target_tensors=set()) 2713 with self.assertRaises(ValueError): 2714 model.compile(optimizer='rmsprop', loss='mse', 2715 target_tensors=[target, target]) 2716 with self.assertRaises(ValueError): 2717 model.compile(optimizer='rmsprop', loss='mse', 2718 target_tensors={'dense2': None}) 2719 with self.assertRaises(ValueError): 2720 model.compile(optimizer='rmsprop', loss='mse', 2721 target_tensors=[target]) 2722 model.train_on_batch(input_val, target_val) 2723 2724 # multi-output, as list 2725 input_val = np.random.random((10, 4)) 2726 target_val_a = np.random.random((10, 4)) 2727 target_val_b = np.random.random((10, 4)) 2728 target_a = backend.variable(target_val_a) 2729 target_b = backend.variable(target_val_b) 2730 2731 inputs = layers_module.Input(shape=(4,)) 2732 output_a = layers_module.Dense(4, name='dense_a')(inputs) 2733 output_b = layers_module.Dense(4, name='dense_b')(inputs) 2734 model = training_module.Model(inputs, [output_a, output_b]) 2735 model.compile(optimizer='rmsprop', loss='mse', 2736 target_tensors=[target_a, target_b]) 2737 model.train_on_batch(input_val, None) 2738 2739 # multi-output, as dict 2740 model.compile(optimizer='rmsprop', loss='mse', 2741 target_tensors={'dense_a': target_a, 2742 'dense_b': target_b}) 2743 model.train_on_batch(input_val, None) 2744 2745 # test with sample weights 2746 model.compile( 2747 optimizer='rmsprop', 2748 loss='mse', 2749 metrics=['mae', metrics_module.CategoricalAccuracy()], 2750 target_tensors=[target_a, target_b]) 2751 model.train_on_batch(input_val, None, 2752 sample_weight={'dense_a': np.random.random((10,))}) 2753 2754 def test_model_custom_target_tensors(self): 2755 with ops.Graph().as_default(), self.cached_session(): 2756 a = input_layer.Input(shape=(3,), name='input_a') 2757 b = input_layer.Input(shape=(3,), name='input_b') 2758 2759 a_2 = layers_module.Dense(4, name='dense_1')(a) 2760 dp = layers_module.Dropout(0.5, name='dropout') 2761 b_2 = dp(b) 2762 2763 y = backend.placeholder([10, 4], name='y') 2764 y1 = backend.placeholder([10, 3], name='y1') 2765 y2 = backend.placeholder([7, 5], name='y2') 2766 model = training_module.Model([a, b], [a_2, b_2]) 2767 2768 optimizer = 'rmsprop' 2769 loss = 'mse' 2770 loss_weights = [1., 0.5] 2771 2772 # test list of target tensors 2773 with self.assertRaises(ValueError): 2774 model.compile(optimizer, loss, metrics=[], loss_weights=loss_weights, 2775 sample_weight_mode=None, target_tensors=[y, y1, y2]) 2776 model.compile(optimizer, loss, metrics=[], loss_weights=loss_weights, 2777 sample_weight_mode=None, target_tensors=[y, y1]) 2778 input_a_np = np.random.random((10, 3)) 2779 input_b_np = np.random.random((10, 3)) 2780 2781 output_a_np = np.random.random((10, 4)) 2782 output_b_np = np.random.random((10, 3)) 2783 2784 _ = model.train_on_batch([input_a_np, input_b_np], 2785 [output_a_np, output_b_np], { 2786 'dense_1': np.random.random((10,)), 2787 'dropout': np.random.random((10,)) 2788 }) 2789 # test dictionary of target_tensors 2790 with self.assertRaises(ValueError): 2791 model.compile(optimizer, loss, 2792 metrics=[], 2793 loss_weights=loss_weights, 2794 sample_weight_mode=None, 2795 target_tensors={'does_not_exist': y2}) 2796 # test dictionary of target_tensors 2797 model.compile(optimizer, loss, 2798 metrics=[], 2799 loss_weights=loss_weights, 2800 sample_weight_mode=None, 2801 target_tensors={'dense_1': y, 'dropout': y1}) 2802 _ = model.train_on_batch([input_a_np, input_b_np], 2803 [output_a_np, output_b_np], { 2804 'dense_1': np.random.random((10,)), 2805 'dropout': np.random.random((10,)) 2806 }) 2807 2808 # test with custom TF placeholder as target 2809 pl_target_a = array_ops.placeholder('float32', shape=(None, 4)) 2810 model.compile(optimizer='rmsprop', loss='mse', 2811 target_tensors={'dense_1': pl_target_a}) 2812 model.train_on_batch([input_a_np, input_b_np], 2813 [output_a_np, output_b_np]) 2814 2815 2816class TestTrainingWithMetrics(keras_parameterized.TestCase): 2817 """Training tests related to metrics.""" 2818 2819 @keras_parameterized.run_all_keras_modes 2820 def test_metrics_names(self): 2821 a = layers_module.Input(shape=(3,), name='input_a') 2822 b = layers_module.Input(shape=(3,), name='input_b') 2823 2824 dense = layers_module.Dense(4, name='dense') 2825 c = dense(a) 2826 d = dense(b) 2827 e = layers_module.Dropout(0.5, name='dropout')(c) 2828 2829 model = training_module.Model([a, b], [d, e]) 2830 2831 optimizer = RMSPropOptimizer(learning_rate=0.001) 2832 metrics = ['mse', metrics_module.BinaryAccuracy()] 2833 model.compile( 2834 optimizer, 2835 loss='mae', 2836 metrics=metrics, 2837 run_eagerly=testing_utils.should_run_eagerly()) 2838 2839 mse_metric = 'mse' if context.executing_eagerly() else 'mean_squared_error' 2840 reference_metric_names = [ 2841 'loss', 'dense_loss', 'dropout_loss', 'dense_' + mse_metric, 2842 'dense_binary_accuracy', 'dropout_' + mse_metric, 2843 'dropout_binary_accuracy' 2844 ] 2845 2846 input_a_np = np.random.random((10, 3)) 2847 input_b_np = np.random.random((10, 3)) 2848 2849 output_d_np = np.random.random((10, 4)) 2850 output_e_np = np.random.random((10, 4)) 2851 2852 model.fit([input_a_np, input_b_np], [output_d_np, output_e_np], 2853 epochs=1, 2854 batch_size=5) 2855 self.assertEqual(reference_metric_names, model.metrics_names) 2856 2857 @keras_parameterized.run_all_keras_modes 2858 def test_metric_state_reset_between_fit_and_evaluate(self): 2859 model = sequential.Sequential() 2860 model.add(layers_module.Dense(3, activation='relu', input_dim=4)) 2861 model.add(layers_module.Dense(1, activation='sigmoid')) 2862 acc_obj = metrics_module.BinaryAccuracy() 2863 model.compile( 2864 loss='mae', 2865 metrics=[acc_obj], 2866 optimizer=RMSPropOptimizer(learning_rate=0.001), 2867 run_eagerly=testing_utils.should_run_eagerly()) 2868 2869 x_train = np.random.random((100, 4)) 2870 y_train = np.random.random((100, 1)) 2871 model.fit(x_train, y_train, batch_size=5, epochs=2) 2872 self.assertEqual(self.evaluate(acc_obj.count), 100) 2873 2874 x_test = np.random.random((10, 4)) 2875 y_test = np.random.random((10, 1)) 2876 model.evaluate(x_test, y_test, batch_size=5) 2877 self.assertEqual(self.evaluate(acc_obj.count), 10) 2878 2879 @keras_parameterized.run_with_all_model_types(exclude_models=['sequential']) 2880 @keras_parameterized.run_all_keras_modes 2881 def test_metrics_valid_compile_input_formats(self): 2882 inp_1 = layers_module.Input(shape=(1,), name='input_1') 2883 inp_2 = layers_module.Input(shape=(1,), name='input_2') 2884 x = layers_module.Dense(3, kernel_initializer='ones', trainable=False) 2885 out_1 = layers_module.Dense( 2886 1, kernel_initializer='ones', name='output_1', trainable=False) 2887 out_2 = layers_module.Dense( 2888 1, kernel_initializer='ones', name='output_2', trainable=False) 2889 2890 branch_a = [inp_1, x, out_1] 2891 branch_b = [inp_2, x, out_2] 2892 model = testing_utils.get_multi_io_model(branch_a, branch_b) 2893 2894 # list of metrics. 2895 model.compile( 2896 optimizer='rmsprop', 2897 loss='mse', 2898 metrics=[metrics_module.MeanSquaredError()], 2899 weighted_metrics=[metrics_module.MeanSquaredError()], 2900 run_eagerly=testing_utils.should_run_eagerly()) 2901 2902 # list of list of metrics. 2903 model.compile( 2904 optimizer='rmsprop', 2905 loss='mse', 2906 metrics=[ 2907 metrics_module.MeanSquaredError(), 2908 [metrics_module.MeanSquaredError(), 2909 metrics_module.Accuracy()] 2910 ], 2911 weighted_metrics=[ 2912 metrics_module.MeanSquaredError(), 2913 [metrics_module.MeanSquaredError(), 2914 metrics_module.Accuracy()] 2915 ], 2916 run_eagerly=testing_utils.should_run_eagerly()) 2917 2918 # dict of metrics. 2919 model.compile( 2920 optimizer='rmsprop', 2921 loss='mse', 2922 metrics={ 2923 'output_1': 2924 metrics_module.MeanSquaredError(), 2925 'output_2': [ 2926 metrics_module.MeanSquaredError(), 2927 metrics_module.Accuracy() 2928 ], 2929 }, 2930 weighted_metrics={ 2931 'output_1': 2932 metrics_module.MeanSquaredError(), 2933 'output_2': [ 2934 metrics_module.MeanSquaredError(), 2935 metrics_module.Accuracy() 2936 ], 2937 }, 2938 run_eagerly=testing_utils.should_run_eagerly()) 2939 2940 @keras_parameterized.run_all_keras_modes 2941 def test_metrics_masking(self): 2942 np.random.seed(1337) 2943 model = sequential.Sequential() 2944 model.add(layers_module.Masking(mask_value=0, input_shape=(2, 1))) 2945 model.add( 2946 layers_module.TimeDistributed( 2947 layers_module.Dense(1, kernel_initializer='ones'))) 2948 model.compile( 2949 RMSPropOptimizer(learning_rate=0.001), 2950 loss='mse', 2951 weighted_metrics=['accuracy'], 2952 run_eagerly=testing_utils.should_run_eagerly()) 2953 2954 # verify that masking is applied. 2955 x = np.array([[[1], [1]], [[1], [1]], [[0], [0]]]) 2956 y = np.array([[[1], [1]], [[0], [1]], [[1], [1]]]) 2957 scores = model.train_on_batch(x, y) 2958 self.assertArrayNear(scores, [0.25, 0.75], 0.1) 2959 2960 # verify that masking is combined with sample weights. 2961 w = np.array([3, 2, 4]) 2962 scores = model.train_on_batch(x, y, sample_weight=w) 2963 self.assertArrayNear(scores, [0.3328, 0.8], 0.001) 2964 2965 @keras_parameterized.run_all_keras_modes 2966 def test_add_metric_with_tensor_on_model(self): 2967 x = layers_module.Input(shape=(1,)) 2968 y = layers_module.Dense(1, kernel_initializer='ones')(x) 2969 model = training_module.Model(x, y) 2970 model.add_metric( 2971 math_ops.reduce_sum(y), name='metric_1', aggregation='mean') 2972 2973 if context.executing_eagerly(): 2974 # This is not a use case in v1 graph mode. 2975 mean_result = metrics_module.Mean()(y) 2976 with self.assertRaisesRegex( 2977 ValueError, 'Expected a symbolic Tensor for the metric value'): 2978 model.add_metric(mean_result, name='metric_2') 2979 else: 2980 with self.assertRaisesRegex( 2981 ValueError, 'Using the result of calling a `Metric` object '): 2982 with backend.get_graph().as_default(): 2983 model.add_metric(metrics_module.Mean(name='metric_2')(y)) 2984 2985 model.compile( 2986 'sgd', 2987 loss='mse', 2988 run_eagerly=testing_utils.should_run_eagerly()) 2989 2990 inputs = np.ones(shape=(10, 1)) 2991 targets = np.ones(shape=(10, 1)) 2992 history = model.fit( 2993 inputs, 2994 targets, 2995 epochs=2, 2996 batch_size=5, 2997 validation_data=(inputs, targets)) 2998 self.assertEqual(history.history['metric_1'][-1], 5) 2999 self.assertEqual(history.history['val_metric_1'][-1], 5) 3000 3001 eval_results = model.evaluate(inputs, targets, batch_size=5) 3002 self.assertEqual(eval_results[-1], 5) 3003 3004 model.predict(inputs, batch_size=5) 3005 model.train_on_batch(inputs, targets) 3006 model.test_on_batch(inputs, targets) 3007 3008 @keras_parameterized.run_all_keras_modes 3009 def test_add_metric_in_model_call(self): 3010 3011 class TestModel(training_module.Model): 3012 3013 def __init__(self): 3014 super(TestModel, self).__init__(name='test_model') 3015 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3016 self.mean = metrics_module.Mean(name='metric_1') 3017 3018 def call(self, x): 3019 self.add_metric( 3020 math_ops.reduce_sum(x), name='metric_2', aggregation='mean') 3021 # Provide same name as in the instance created in __init__ 3022 # for eager mode 3023 self.add_metric(self.mean(x), name='metric_1') 3024 return self.dense1(x) 3025 3026 model = TestModel() 3027 model.compile( 3028 loss='mse', 3029 optimizer=RMSPropOptimizer(0.01), 3030 run_eagerly=testing_utils.should_run_eagerly()) 3031 3032 x = np.ones(shape=(10, 1)) 3033 y = np.ones(shape=(10, 2)) 3034 history = model.fit(x, y, epochs=2, batch_size=5, validation_data=(x, y)) 3035 self.assertAlmostEqual(history.history['metric_1'][-1], 1, 0) 3036 self.assertAlmostEqual(history.history['val_metric_1'][-1], 1, 0) 3037 self.assertAlmostEqual(history.history['metric_2'][-1], 5, 0) 3038 self.assertAlmostEqual(history.history['val_metric_2'][-1], 5, 0) 3039 3040 eval_results = model.evaluate(x, y, batch_size=5) 3041 self.assertAlmostEqual(eval_results[1], 1, 0) 3042 self.assertAlmostEqual(eval_results[2], 5, 0) 3043 3044 model.predict(x, batch_size=5) 3045 model.train_on_batch(x, y) 3046 model.test_on_batch(x, y) 3047 3048 @keras_parameterized.run_with_all_model_types 3049 @keras_parameterized.run_all_keras_modes 3050 def test_add_metric_in_layer_call(self): 3051 3052 class TestLayer(layers_module.Layer): 3053 3054 def build(self, input_shape): 3055 self.a = self.add_variable( 3056 'a', (1, 1), initializer='ones', trainable=False) 3057 self.built = True 3058 3059 def call(self, inputs): 3060 self.add_metric( 3061 math_ops.reduce_sum(inputs), name='metric_1', aggregation='mean') 3062 return inputs + 1 3063 3064 layers = [ 3065 TestLayer(input_shape=(1,)), 3066 layers_module.Dense(2, kernel_initializer='ones') 3067 ] 3068 model = testing_utils.get_model_from_layers(layers, input_shape=(1,)) 3069 model.compile( 3070 loss='mse', 3071 optimizer=RMSPropOptimizer(0.01), 3072 run_eagerly=testing_utils.should_run_eagerly()) 3073 3074 x = np.ones(shape=(10, 1)) 3075 y = np.ones(shape=(10, 2)) 3076 history = model.fit(x, y, epochs=2, batch_size=5, validation_data=(x, y)) 3077 self.assertEqual(history.history['metric_1'][-1], 5) 3078 self.assertAlmostEqual(history.history['val_metric_1'][-1], 5, 0) 3079 3080 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3081 def test_model_metrics_list(self): 3082 3083 class LayerWithAddMetric(layers_module.Layer): 3084 3085 def __init__(self): 3086 super(LayerWithAddMetric, self).__init__() 3087 self.dense = layers_module.Dense(1, kernel_initializer='ones') 3088 3089 def __call__(self, inputs): 3090 outputs = self.dense(inputs) 3091 self.add_metric( 3092 math_ops.reduce_sum(outputs), name='metric_1', aggregation='mean') 3093 return outputs 3094 3095 class LayerWithNestedAddMetricLayer(layers_module.Layer): 3096 3097 def __init__(self): 3098 super(LayerWithNestedAddMetricLayer, self).__init__() 3099 self.layer = LayerWithAddMetric() 3100 3101 def call(self, inputs): 3102 outputs = self.layer(inputs) 3103 self.add_metric( 3104 math_ops.reduce_sum(outputs), name='metric_2', aggregation='mean') 3105 return outputs 3106 3107 x = layers_module.Input(shape=(1,)) 3108 y = LayerWithNestedAddMetricLayer()(x) 3109 3110 model = training_module.Model(x, y) 3111 model.add_metric( 3112 math_ops.reduce_sum(y), name='metric_3', aggregation='mean') 3113 3114 if context.executing_eagerly(): 3115 # This is not a use case in v1 graph mode. 3116 mean_result = metrics_module.Mean()(y) 3117 with self.assertRaisesRegex( 3118 ValueError, 'Expected a symbolic Tensor for the metric value'): 3119 model.add_metric(mean_result, name='metric_4') 3120 3121 else: 3122 with self.assertRaisesRegex( 3123 ValueError, 'Using the result of calling a `Metric` object '): 3124 with backend.get_graph().as_default(): 3125 model.add_metric(metrics_module.Mean(name='metric_4')(y)) 3126 3127 model.compile( 3128 'sgd', 3129 loss='mse', 3130 metrics=[metrics_module.Accuracy('metric_4')], 3131 run_eagerly=testing_utils.should_run_eagerly()) 3132 3133 model.fit(np.ones((10, 1)), np.ones((10, 1)), batch_size=10) 3134 3135 # Verify that the metrics added using `compile` and `add_metric` API are 3136 # included 3137 self.assertEqual([m.name for m in model.metrics], 3138 ['loss', 'metric_4', 'metric_2', 'metric_1', 'metric_3']) 3139 3140 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3141 def test_model_metrics_list_in_call(self): 3142 3143 class TestModel(training_module.Model): 3144 3145 def __init__(self): 3146 super(TestModel, self).__init__(name='test_model') 3147 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3148 3149 def call(self, x): 3150 self.add_metric( 3151 math_ops.reduce_sum(x), name='metric_1', aggregation='mean') 3152 return self.dense1(x) 3153 3154 model = TestModel() 3155 model.compile( 3156 loss='mse', 3157 optimizer=RMSPropOptimizer(0.01), 3158 metrics=[metrics_module.Accuracy('acc')], 3159 run_eagerly=testing_utils.should_run_eagerly()) 3160 x = np.ones(shape=(10, 1)) 3161 y = np.ones(shape=(10, 2)) 3162 model.fit(x, y, epochs=2, batch_size=5, validation_data=(x, y)) 3163 3164 self.assertEqual([m.name for m in model.metrics], 3165 ['loss', 'acc', 'metric_1']) 3166 3167 @keras_parameterized.run_all_keras_modes 3168 def test_multiple_add_metric_calls(self): 3169 3170 class TestModel(training_module.Model): 3171 3172 def __init__(self): 3173 super(TestModel, self).__init__(name='test_model') 3174 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3175 self.mean1 = metrics_module.Mean(name='metric_1') 3176 self.mean2 = metrics_module.Mean(name='metric_2') 3177 3178 def call(self, x): 3179 self.add_metric(self.mean2(x), name='metric_2') 3180 self.add_metric(self.mean1(x), name='metric_1') 3181 self.add_metric( 3182 math_ops.reduce_sum(x), name='metric_3', aggregation='mean') 3183 return self.dense1(x) 3184 3185 model = TestModel() 3186 self.assertListEqual([m.name for m in model.metrics], 3187 ['metric_1', 'metric_2']) 3188 model.compile( 3189 loss='mse', 3190 optimizer=RMSPropOptimizer(0.01), 3191 run_eagerly=testing_utils.should_run_eagerly()) 3192 3193 x = np.ones(shape=(10, 1)) 3194 y = np.ones(shape=(10, 2)) 3195 history = model.fit(x, y, epochs=2, batch_size=5, validation_data=(x, y)) 3196 self.assertAlmostEqual(history.history['metric_1'][-1], 1, 0) 3197 self.assertAlmostEqual(history.history['metric_2'][-1], 1, 0) 3198 self.assertAlmostEqual(history.history['metric_3'][-1], 5, 0) 3199 3200 eval_results = model.evaluate(x, y, batch_size=5) 3201 self.assertArrayNear(eval_results[1:4], [1, 1, 5], 0.1) 3202 3203 model.predict(x, batch_size=5) 3204 model.train_on_batch(x, y) 3205 model.test_on_batch(x, y) 3206 3207 @keras_parameterized.run_all_keras_modes 3208 def test_multiple_add_metric_calls_layer(self): 3209 3210 class TestLayer(layers_module.Layer): 3211 3212 def __init__(self): 3213 super(TestLayer, self).__init__(name='test_layer') 3214 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3215 self.m1 = metrics_module.Mean(name='m_1') 3216 self.m2 = [ 3217 metrics_module.Mean(name='m_2'), 3218 metrics_module.Mean(name='m_3') 3219 ] 3220 self.m3 = { 3221 'mean4': metrics_module.Mean(name='m_4'), 3222 'mean5': metrics_module.Mean(name='m_5') 3223 } 3224 3225 def call(self, x): 3226 self.add_metric(self.m2[0](x)) 3227 self.add_metric(self.m2[1](x)) 3228 self.add_metric(self.m1(x)) 3229 self.add_metric(self.m3['mean4'](x)) 3230 self.add_metric(self.m3['mean5'](x)) 3231 self.add_metric(math_ops.reduce_sum(x), name='m_6', aggregation='mean') 3232 return self.dense1(x) 3233 3234 layer = TestLayer() 3235 self.assertListEqual([m.name for m in layer.metrics], 3236 ['m_1', 'm_2', 'm_3', 'm_4', 'm_5']) 3237 3238 layer(np.ones((10, 10))) 3239 self.assertListEqual([m.name for m in layer.metrics], 3240 ['m_1', 'm_2', 'm_3', 'm_4', 'm_5', 'm_6']) 3241 3242 @keras_parameterized.run_all_keras_modes 3243 def test_duplicate_metric_name_in_add_metric(self): 3244 3245 class TestModel(training_module.Model): 3246 3247 def __init__(self): 3248 super(TestModel, self).__init__(name='test_model') 3249 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3250 self.mean = metrics_module.Mean(name='metric_1') 3251 self.mean2 = metrics_module.Mean(name='metric_1') 3252 3253 def call(self, x): 3254 self.add_metric(self.mean(x), name='metric_1') 3255 return self.dense1(x) 3256 3257 model = TestModel() 3258 model.compile( 3259 loss='mse', 3260 optimizer=RMSPropOptimizer(0.01), 3261 run_eagerly=testing_utils.should_run_eagerly()) 3262 3263 x = np.ones(shape=(10, 1)) 3264 y = np.ones(shape=(10, 2)) 3265 with self.assertRaisesRegex( 3266 ValueError, 3267 'Please provide different names for the metrics you have added. ' 3268 'We found 2 metrics with the name: "metric_1"'): 3269 model.fit(x, y, epochs=2, batch_size=5, validation_data=(x, y)) 3270 3271 @keras_parameterized.run_all_keras_modes 3272 def test_add_metric_without_name(self): 3273 3274 class TestModel(training_module.Model): 3275 3276 def __init__(self): 3277 super(TestModel, self).__init__(name='test_model') 3278 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3279 3280 def call(self, x): 3281 self.add_metric(math_ops.reduce_sum(x), aggregation='mean') 3282 return self.dense1(x) 3283 3284 model = TestModel() 3285 model.compile( 3286 loss='mse', 3287 optimizer=RMSPropOptimizer(0.01), 3288 run_eagerly=testing_utils.should_run_eagerly()) 3289 x = np.ones(shape=(10, 1)) 3290 y = np.ones(shape=(10, 2)) 3291 3292 with self.assertRaisesRegex(ValueError, 3293 'Please provide a name for your metric like'): 3294 model.fit(x, y, epochs=2, batch_size=5, validation_data=(x, y)) 3295 3296 @keras_parameterized.run_all_keras_modes 3297 def test_add_metric_correctness(self): 3298 inputs = input_layer.Input(shape=(1,)) 3299 targets = input_layer.Input(shape=(1,)) 3300 3301 class Bias(layers_module.Layer): 3302 3303 def build(self, input_shape): 3304 self.bias = self.add_variable('bias', (1,), initializer='zeros') 3305 self.mae = metrics_module.MeanAbsoluteError(name='mae_1') 3306 3307 def call(self, inputs): 3308 inputs, targets = inputs 3309 outputs = inputs + self.bias 3310 self.add_metric(self.mae(targets, outputs), name='mae_1') 3311 return outputs 3312 3313 outputs = Bias()([inputs, targets]) 3314 model = training_module.Model([inputs, targets], outputs) 3315 3316 model.add_metric( 3317 metrics_module.mean_absolute_error(targets, outputs), 3318 name='mae_2', 3319 aggregation='mean') 3320 3321 model.compile( 3322 loss='mae', 3323 optimizer=optimizer_v2.gradient_descent.SGD(0.1), 3324 metrics=[metrics_module.MeanAbsoluteError(name='mae_3')], 3325 run_eagerly=testing_utils.should_run_eagerly()) 3326 3327 x = np.array([[0.], [1.], [2.]]) 3328 y = np.array([[0.5], [2.], [3.5]]) 3329 history = model.fit([x, y], y, batch_size=3, epochs=5) 3330 3331 expected_val = [1., 0.9, 0.8, 0.7, 0.6] 3332 for key in ['loss', 'mae_1', 'mae_2', 'mae_3']: 3333 self.assertAllClose(history.history[key], expected_val, 1e-3) 3334 3335 @keras_parameterized.run_all_keras_modes 3336 def test_add_metric_order(self): 3337 3338 class MyLayer(layers_module.Layer): 3339 3340 def call(self, inputs, training=None, mask=None): 3341 self.add_metric( 3342 array_ops.ones([32]) * 2.0, name='two', aggregation='mean') 3343 return inputs 3344 3345 class MyModel(training_module.Model): 3346 3347 def __init__(self, **kwargs): 3348 super(MyModel, self).__init__(**kwargs) 3349 self._sampler = MyLayer(name='sampler') 3350 3351 def call(self, inputs, training=None, mask=None): 3352 z = self._sampler(inputs) 3353 self.add_metric( 3354 array_ops.ones([32]) * 1.0, name='one', aggregation='mean') 3355 self.add_metric( 3356 array_ops.ones([32]) * 3.0, name='three', aggregation='mean') 3357 return z 3358 3359 xdata = np.random.uniform(size=[32, 16]).astype(np.float32) 3360 dataset_train = dataset_ops.Dataset.from_tensor_slices((xdata, xdata)) 3361 dataset_train = dataset_train.batch(32, drop_remainder=True) 3362 3363 model = MyModel() 3364 model.compile( 3365 optimizer='sgd', 3366 loss='mse', 3367 run_eagerly=testing_utils.should_run_eagerly()) 3368 history = model.fit(dataset_train, epochs=3) 3369 self.assertDictEqual( 3370 history.history, { 3371 'loss': [0.0, 0.0, 0.0], 3372 'three': [3.0, 3.0, 3.0], 3373 'two': [2.0, 2.0, 2.0], 3374 'one': [1.0, 1.0, 1.0] 3375 }) 3376 3377 @keras_parameterized.run_all_keras_modes 3378 def test_add_metric_aggregation_mean(self): 3379 3380 class TestModel(training_module.Model): 3381 3382 def __init__(self): 3383 super(TestModel, self).__init__(name='test_model') 3384 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3385 3386 def call(self, x): 3387 self.add_metric( 3388 math_ops.reduce_sum(x), name='metric_1', aggregation='mean') 3389 return self.dense1(x) 3390 3391 model = TestModel() 3392 model.compile( 3393 'rmsprop', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 3394 model.fit(np.ones(shape=(10, 1)), np.ones(shape=(10, 2)), batch_size=5) 3395 3396 @keras_parameterized.run_all_keras_modes 3397 def test_add_metric_aggregation_none(self): 3398 3399 class TestModel(training_module.Model): 3400 3401 def __init__(self): 3402 super(TestModel, self).__init__(name='test_model') 3403 self.dense1 = layers_module.Dense(2, kernel_initializer='ones') 3404 self.mean = metrics_module.Mean(name='metric_1') 3405 3406 def call(self, x): 3407 self.add_metric(self.mean(x), name='metric_1', aggregation=None) 3408 return self.dense1(x) 3409 3410 model = TestModel() 3411 model.compile( 3412 'rmsprop', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 3413 model.fit(np.ones(shape=(10, 1)), np.ones(shape=(10, 2)), batch_size=5) 3414 3415 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3416 def DISABLED_test_add_metric_invalid_aggregation(self): 3417 # TODO(psv): Reenable test once it is fixed. 3418 x = layers_module.Input(shape=(1,)) 3419 y = layers_module.Dense(1, kernel_initializer='ones')(x) 3420 model = training_module.Model(x, y) 3421 with self.assertRaisesRegex(ValueError, 3422 'only `mean` sample-wise metric aggregation'): 3423 model.add_metric( 3424 math_ops.reduce_sum(y), name='metric_1', aggregation='sum') 3425 3426 with self.assertRaisesRegex(ValueError, 3427 'only `mean` sample-wise metric aggregation'): 3428 model.add_metric( 3429 math_ops.reduce_sum(y), name='metric_1', aggregation=None) 3430 3431 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3432 def test_calling_evaluate_in_callback_during_fit(self): 3433 # Check fix for a bug that caused `evaluate` to hit a cached dataset 3434 # when run from inside a fit callback. 3435 x = layers_module.Input(shape=(2,)) 3436 y = layers_module.Dense(2, kernel_initializer='ones', use_bias=False)(x) 3437 model = training_module.Model(x, y) 3438 3439 ones = np.ones((10, 2), dtype=np.float32) 3440 zeros = np.zeros((10, 2), dtype=np.float32) 3441 train_ds = dataset_ops.Dataset.from_tensor_slices( 3442 (ones, ones)).batch(5) 3443 val_ds_1 = dataset_ops.Dataset.from_tensor_slices( 3444 (ones, ones)).batch(5) 3445 val_ds_2 = dataset_ops.Dataset.from_tensor_slices( 3446 (zeros, zeros)).batch(5) 3447 model.compile('sgd', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 3448 3449 class MyCallback(Callback): 3450 3451 def on_epoch_end(self, *args, **kwargs): 3452 eval_result = self.model.evaluate(val_ds_2) 3453 if abs(eval_result) > 1e-7: 3454 raise AssertionError( 3455 'Expected to hit the zeros dataset but got high loss value of %s' 3456 % eval_result) 3457 3458 history = model.fit( 3459 train_ds, validation_data=val_ds_1, callbacks=[MyCallback()]) 3460 # Evaluate at the end of fit should hit the ones dataset (cached) 3461 self.assertGreater(abs(history.history['val_loss'][-1]), 0.1) 3462 # Standalone call to evaluate should not hit the cached dataset 3463 eval_result = model.evaluate(val_ds_2) 3464 self.assertLess(abs(eval_result), 1e-7) 3465 3466 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3467 def test_model_with_nested_compiled_model(self): 3468 3469 class LayerWithAddMetric(layers_module.Layer): 3470 3471 def __init__(self): 3472 super(LayerWithAddMetric, self).__init__() 3473 self.dense = layers_module.Dense(1, kernel_initializer='ones') 3474 3475 def call(self, inputs): 3476 outputs = self.dense(inputs) 3477 self.add_metric( 3478 math_ops.reduce_sum(outputs), name='mean', aggregation='mean') 3479 return outputs 3480 3481 x = layers_module.Input(shape=(1,)) 3482 y = LayerWithAddMetric()(x) 3483 3484 inner_model = training_module.Model(x, y) 3485 inner_model.add_metric( 3486 math_ops.reduce_sum(y), name='mean1', aggregation='mean') 3487 3488 inner_model.compile( 3489 'sgd', 3490 loss='mse', 3491 metrics=[metrics_module.Accuracy('acc')], 3492 run_eagerly=testing_utils.should_run_eagerly()) 3493 inner_model.fit(np.ones((10, 1)), np.ones((10, 1)), batch_size=10) 3494 3495 self.assertEqual([m.name for m in inner_model.metrics], 3496 ['loss', 'acc', 'mean', 'mean1']) 3497 3498 x = layers_module.Input(shape=[1]) 3499 y = inner_model(x) 3500 outer_model = training_module.Model(x, y) 3501 outer_model.add_metric( 3502 math_ops.reduce_sum(y), name='mean2', aggregation='mean') 3503 3504 outer_model.compile( 3505 'sgd', 3506 loss='mse', 3507 metrics=[metrics_module.Accuracy('acc2')], 3508 run_eagerly=testing_utils.should_run_eagerly()) 3509 outer_model.fit(np.ones((10, 1)), np.ones((10, 1)), batch_size=10) 3510 self.assertEqual([m.name for m in outer_model.metrics], 3511 ['loss', 'acc2', 'mean', 'mean1', 'mean2']) 3512 3513 @keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3514 def test_model_with_metric_class_that_returns_dict(self): 3515 x = layers_module.Input(shape=(2,)) 3516 y = layers_module.Dense(3)(x) 3517 model = training_module.Model(x, y) 3518 3519 class DictMetric(metrics_module.Metric): 3520 3521 def __init__(self): 3522 super(DictMetric, self).__init__() 3523 self.sample_count = variables_module.Variable(0) 3524 self.l2_sum = variables_module.Variable(0.) 3525 3526 def update_state(self, y_true, y_pred, sample_weight=None): 3527 self.l2_sum.assign_add( 3528 math_ops.reduce_sum(math_ops.square(y_true - y_pred))) 3529 self.sample_count.assign_add(array_ops.shape(y_true)[0]) 3530 3531 def reset_state(self): 3532 self.sample_count.assign(0) 3533 self.l2_sum.assign(0.) 3534 3535 def result(self): 3536 mse = self.l2_sum / math_ops.cast(self.sample_count, 'float32') 3537 rmse = math_ops.sqrt(mse) 3538 return {'my_mse': mse, 3539 'my_rmse': rmse} 3540 3541 model.compile('sgd', 3542 'mse', 3543 metrics=['mae', DictMetric()], 3544 run_eagerly=testing_utils.should_run_eagerly()) 3545 3546 history = model.fit(np.ones((10, 2)), np.ones((10, 3))) 3547 self.assertEqual(list(history.history.keys()), 3548 ['loss', 'mae', 'my_mse', 'my_rmse']) 3549 list_evaluate_res = model.evaluate( 3550 np.ones((10, 2)), np.ones((10, 3))) 3551 self.assertEqual(len(list_evaluate_res), 4) 3552 dict_evaluate_res = model.evaluate( 3553 np.ones((10, 2)), np.ones((10, 3)), return_dict=True) 3554 self.assertEqual(list(dict_evaluate_res.keys()), 3555 ['loss', 'mae', 'my_mse', 'my_rmse']) 3556 list_train_on_batch_res = model.train_on_batch( 3557 np.ones((10, 2)), np.ones((10, 3))) 3558 self.assertEqual(len(list_train_on_batch_res), 4) 3559 dict_train_on_batch_res = model.train_on_batch( 3560 np.ones((10, 2)), np.ones((10, 3)), return_dict=True) 3561 self.assertEqual(list(dict_train_on_batch_res.keys()), 3562 ['loss', 'mae', 'my_mse', 'my_rmse']) 3563 list_test_on_batch_res = model.test_on_batch( 3564 np.ones((10, 2)), np.ones((10, 3))) 3565 self.assertEqual(len(list_test_on_batch_res), 4) 3566 dict_test_on_batch_res = model.test_on_batch( 3567 np.ones((10, 2)), np.ones((10, 3)), return_dict=True) 3568 self.assertEqual(list(dict_test_on_batch_res.keys()), 3569 ['loss', 'mae', 'my_mse', 'my_rmse']) 3570 3571 3572class BareUpdateLayer(layers_module.Layer): 3573 3574 def build(self, input_shape): 3575 self.counter = self.add_weight( 3576 'counter', 3577 dtype='int32', 3578 shape=(), 3579 initializer='zeros', 3580 trainable=False) 3581 3582 def call(self, inputs): 3583 state_ops.assign_add(self.counter, 1) 3584 return math_ops.cast(self.counter, inputs.dtype) * inputs 3585 3586 3587class LambdaUpdateLayer(layers_module.Layer): 3588 3589 def build(self, input_shape): 3590 self.counter = self.add_weight( 3591 'counter', 3592 dtype='int32', 3593 shape=(), 3594 initializer='zeros', 3595 trainable=False) 3596 3597 def call(self, inputs): 3598 # Make sure update isn't run twice. 3599 self.add_update(lambda: state_ops.assign_add(self.counter, 1)) 3600 return math_ops.cast(self.counter, inputs.dtype) * inputs 3601 3602 3603class NestedUpdateLayer(layers_module.Layer): 3604 3605 def build(self, input_shape): 3606 self.layer = BareUpdateLayer() 3607 self.layer.build(input_shape) 3608 3609 @property 3610 def counter(self): 3611 return self.layer.counter 3612 3613 def call(self, inputs): 3614 return self.layer(inputs) 3615 3616 3617class SubgraphUpdateLayer(layers_module.Layer): 3618 3619 def build(self, input_shape): 3620 self.counter = self.add_weight( 3621 'counter', 3622 dtype='int32', 3623 shape=(), 3624 initializer='zeros', 3625 trainable=False) 3626 3627 def call(self, inputs, training=None): 3628 if training is None: 3629 training = backend.learning_phase() 3630 3631 if training: 3632 self.counter.assign(self.counter + 1) 3633 return inputs 3634 3635 3636@keras_parameterized.run_all_keras_modes(always_skip_v1=True) 3637class TestAutoUpdates(keras_parameterized.TestCase): 3638 3639 @keras_parameterized.run_with_all_model_types 3640 @parameterized.named_parameters( 3641 ('bare_update', BareUpdateLayer), 3642 ('lambda_update', LambdaUpdateLayer), 3643 ('nested_update', NestedUpdateLayer)) 3644 def test_updates_in_model(self, layer_builder): 3645 layer = layer_builder() 3646 x, y = np.ones((10, 10)), np.ones((10, 1)) 3647 model = testing_utils.get_model_from_layers( 3648 [layer, layers_module.Dense(1)], input_shape=(10,)) 3649 model.compile( 3650 'sgd', 3651 'mse', 3652 run_eagerly=testing_utils.should_run_eagerly()) 3653 model.fit(x, y, batch_size=2, epochs=1) 3654 self.assertEqual(self.evaluate(layer.counter), 5) 3655 3656 @keras_parameterized.run_with_all_model_types 3657 def test_lambda_updates_trainable_false(self): 3658 x, y = np.ones((10, 10)), np.ones((10, 1)) 3659 layer = LambdaUpdateLayer() 3660 model = testing_utils.get_model_from_layers( 3661 [layer, layers_module.Dense(1)], input_shape=(10,)) 3662 model.compile( 3663 'sgd', 3664 'mse', 3665 run_eagerly=testing_utils.should_run_eagerly()) 3666 model.fit(x, y, batch_size=2, epochs=1) 3667 self.assertEqual(self.evaluate(layer.counter), 5) 3668 layer.trainable = False 3669 model.compile( 3670 'sgd', 3671 'mse', 3672 run_eagerly=testing_utils.should_run_eagerly()) 3673 model.fit(x, y, batch_size=2, epochs=1) 3674 self.assertEqual(self.evaluate(layer.counter), 5) 3675 3676 @keras_parameterized.run_with_all_model_types 3677 def test_subgraph_updates_in_model(self): 3678 layer = SubgraphUpdateLayer() 3679 x, y = np.ones((10, 10)), np.ones((10, 1)) 3680 model = testing_utils.get_model_from_layers( 3681 [layer, layers_module.Dense(1)], input_shape=(10,)) 3682 model.compile( 3683 'sgd', 3684 'mse', 3685 run_eagerly=testing_utils.should_run_eagerly()) 3686 model.fit(x, y, batch_size=2, epochs=1) 3687 self.assertEqual(self.evaluate(layer.counter), 5) 3688 3689 @parameterized.named_parameters( 3690 ('bare_update', BareUpdateLayer), 3691 ('lambda_update', LambdaUpdateLayer), 3692 ('nested_update', NestedUpdateLayer)) 3693 def test_updates_standalone_layer(self, layer_builder): 3694 layer = layer_builder() 3695 y = layer(np.ones((10, 10))) 3696 self.evaluate(layer.counter.initializer) 3697 self.evaluate(y) 3698 self.assertEqual(self.evaluate(layer.counter), 1) 3699 3700 def test_trainable_false_standalone_layer(self): 3701 layer = LambdaUpdateLayer() 3702 y = layer(np.ones((10, 10))) 3703 self.evaluate(layer.counter.initializer) 3704 self.evaluate(y) 3705 self.assertEqual(self.evaluate(layer.counter), 1) 3706 layer.trainable = False 3707 y = layer(np.ones((10, 10))) 3708 self.evaluate(y) 3709 self.assertEqual(self.evaluate(layer.counter), 1) 3710 3711 @keras_parameterized.run_with_all_model_types 3712 def test_batchnorm_trainable_false(self): 3713 bn = layers_module.BatchNormalization() 3714 model = testing_utils.get_model_from_layers([bn, layers_module.Dense(1)], 3715 input_shape=(10,)) 3716 bn.trainable = False 3717 model.compile( 3718 'sgd', 3719 'mse', 3720 run_eagerly=testing_utils.should_run_eagerly()) 3721 x, y = np.ones((10, 10)), np.ones((10, 1)) 3722 model.fit(x, y, batch_size=2, epochs=1) 3723 self.assertAllEqual(self.evaluate(bn.moving_mean), np.zeros((10,))) 3724 self.assertAllEqual(self.evaluate(bn.moving_variance), np.ones((10,))) 3725 3726 3727class TestFunctionTracing(keras_parameterized.TestCase): 3728 3729 def _seq_model_and_data(self): 3730 model = sequential.Sequential([layers_module.Dense(4, activation='relu')]) 3731 model.compile(loss='mse', optimizer='rmsprop') 3732 x = np.random.random((10, 6)) 3733 y = np.random.random((10, 4)) 3734 return model, x, y 3735 3736 @keras_parameterized.run_all_keras_modes( 3737 always_skip_v1=True, always_skip_eager=True) 3738 def test_no_tracing_between_epoch(self): 3739 model, x, y = self._seq_model_and_data() 3740 3741 logging.set_verbosity(1) 3742 with self.assertLogs(level=1) as logs: 3743 model.fit(x, y, epochs=10, batch_size=5, validation_data=(x, y)) 3744 3745 new_func_graph = 'INFO:absl:Creating new FuncGraph for Python function' 3746 self.assertEqual(sum(new_func_graph in log for log in logs.output), 9) 3747 3748 @keras_parameterized.run_all_keras_modes( 3749 always_skip_v1=True, always_skip_eager=True) 3750 def test_evaluate_no_cached_data(self): 3751 model, x, y = self._seq_model_and_data() 3752 3753 new_func_graph = 'INFO:absl:Creating new FuncGraph for Python function' 3754 logging.set_verbosity(1) 3755 with self.assertLogs(level=1) as eval_logs: 3756 for _ in range(6): 3757 model.evaluate(x, y, batch_size=5) 3758 self.assertEqual(sum(new_func_graph in log for log in eval_logs.output), 20) 3759 3760 3761class TestBuildCustomModel(keras_parameterized.TestCase): 3762 3763 @keras_parameterized.run_all_keras_modes 3764 def test_build_list_of_inputs(self): 3765 3766 class MyModel(training_module.Model): 3767 3768 def __init__(self): 3769 super(MyModel, self).__init__() 3770 self.l1 = layers_module.Dense(1) 3771 self.l2 = layers_module.Dense(2) 3772 3773 def call(self, x): 3774 a, b = x 3775 return self.l1(a) + self.l2(b) 3776 3777 # List of tuples 3778 model = MyModel() 3779 model.build([(None, 1), (None, 2)]) 3780 self.assertEqual(model.l1.kernel.shape.as_list(), [1, 1]) 3781 self.assertEqual(model.l2.kernel.shape.as_list(), [2, 2]) 3782 # List of lists 3783 model = MyModel() 3784 model.build([[None, 1], [None, 2]]) 3785 self.assertEqual(model.l1.kernel.shape.as_list(), [1, 1]) 3786 self.assertEqual(model.l2.kernel.shape.as_list(), [2, 2]) 3787 3788 @keras_parameterized.run_all_keras_modes 3789 def test_build_single_inputs(self): 3790 3791 class MyModel(training_module.Model): 3792 3793 def __init__(self): 3794 super(MyModel, self).__init__() 3795 self.l1 = layers_module.Dense(1) 3796 3797 def call(self, x): 3798 return self.l1(x) 3799 3800 model = MyModel() 3801 model.build((None, 1)) 3802 self.assertEqual(model.l1.kernel.shape.as_list(), [1, 1]) 3803 model = MyModel() 3804 model.build([None, 1]) 3805 self.assertEqual(model.l1.kernel.shape.as_list(), [1, 1]) 3806 3807 @keras_parameterized.run_all_keras_modes 3808 def test_build_dict_inputs(self): 3809 3810 class MyModel(training_module.Model): 3811 3812 def __init__(self): 3813 super(MyModel, self).__init__() 3814 self.l1 = layers_module.Dense(1) 3815 3816 def call(self, inputs): 3817 return self.l1(inputs['x']) 3818 3819 model = MyModel() 3820 model.build({'x': [None, 16]}) 3821 self.assertEqual(model.l1.kernel.shape.as_list(), [16, 1]) 3822 3823 3824if __name__ == '__main__': 3825 test.main() 3826