Пример #1
0
  def testOptimizerWithCallbacks(self):
    np.random.seed(1331)
    input_np = np.random.random((10, 3))
    output_np = np.random.random((10, 4))
    a = input_layer.Input(shape=(3,), name='input_a')
    model = sequential.Sequential()
    model.add(core.Dense(4, name='dense'))
    model.add(core.Dropout(0.5, name='dropout'))
    model(a)
    optimizer = gradient_descent.SGD(learning_rate=0.1)
    model.compile(optimizer, loss='mse', metrics=['mae'])
    # This does not reduce the LR after the first epoch (due to low delta).
    cbks = [
        callbacks.ReduceLROnPlateau(
            monitor='val_loss', factor=0.1, min_delta=0, patience=1, cooldown=5)
    ]
    model.fit(
        input_np,
        output_np,
        batch_size=10,
        validation_data=(input_np, output_np),
        callbacks=cbks,
        epochs=2,
        verbose=0)
    self.assertAllClose(
        float(backend.get_value(model.optimizer.lr)), 0.1, atol=1e-4)

    # This should reduce the LR after the first epoch (due to high delta).
    cbks = [
        callbacks.ReduceLROnPlateau(
            monitor='val_loss',
            factor=0.1,
            min_delta=10,
            patience=1,
            cooldown=5)
    ]
    model.fit(
        input_np,
        output_np,
        batch_size=10,
        validation_data=(input_np, output_np),
        callbacks=cbks,
        epochs=2,
        verbose=2)
    self.assertAllClose(
        float(backend.get_value(model.optimizer.lr)), 0.01, atol=1e-4)
Пример #2
0
  def _run_load_weights_on_restart_test_common_iterations(self):

    def get_input_datasets():
      # Simple training input.
      train_input = [[1]] * 16
      train_label = [[0]] * 16
      ds = dataset_ops.Dataset.from_tensor_slices((train_input, train_label))
      return ds.batch(8, drop_remainder=True)

    class Bias(base_layer.Layer):

      def build(self, input_shape):
        self.bias = self.add_variable('bias', (1,), initializer='zeros')

      def call(self, inputs):
        return inputs + self.bias

    # Very simple bias model to eliminate randomness.
    optimizer = gradient_descent.SGD(0.1)
    model = sequential.Sequential()
    model.add(Bias(input_shape=(1,)))
    model.compile(loss='mae', optimizer=optimizer, metrics=['mae'])
    train_ds = get_input_datasets()

    filepath = os.path.join(self.get_temp_dir(), 'checkpoint.h5')

    # The filepath shouldn't exist at the beginning.
    self.assertFalse(os.path.exists(filepath))
    model.fit(
        train_ds,
        epochs=3,
        callbacks=[
            keras.callbacks.ModelCheckpoint(
                filepath=filepath, save_weights_only=True)
        ])

    # The filepath should exist after fitting with callback.
    self.assertTrue(os.path.exists(filepath))
    model.fit(train_ds, epochs=1)
    weights_after_one_more_epoch = model.get_weights()

    # The filepath should continue to exist after fitting without callback.
    self.assertTrue(os.path.exists(filepath))

    return model, train_ds, filepath, weights_after_one_more_epoch
    def _model_compile(self,
                       strategy,
                       steps_per_execution=1,
                       run_eagerly=False,
                       with_normalization_layer=False,
                       use_lookup_layer=False):
        class ResultAssertingCallback(callbacks_lib.Callback):
            """A callback that asserts the result of the tests."""
            def __init__(self):
                self._prev_epoch = -1

            def on_epoch_end(self, epoch, logs=None):
                logging.info("testModelFit: epoch=%r, logs=%r", epoch, logs)
                if epoch <= self._prev_epoch:
                    raise RuntimeError(
                        "Epoch is supposed to be larger than previous.")
                self._prev_epoch = epoch
                is_loss_float = (logs.get("loss", None) is not None
                                 and isinstance(logs["loss"],
                                                (float, np.floating)))
                if not is_loss_float:
                    raise RuntimeError(
                        "loss is supposed to be in the logs and float.")

            def on_train_end(self, logs=None):
                if self._prev_epoch != 9:
                    raise RuntimeError("Unexpected last epoch: {}".format(
                        self._prev_epoch))

        with strategy.scope():
            model = sequential.Sequential([core_layers.Dense(10)])
            if with_normalization_layer:
                norm = keras.layers.BatchNormalization(axis=-1,
                                                       input_shape=(4, 4, 3),
                                                       momentum=0.8)
                model.add(norm)
            model.add(core_layers.Dense(1, activation="sigmoid"))
            self._accuracy_metric = keras.metrics.Accuracy()

        model.compile(gradient_descent.SGD(),
                      loss="binary_crossentropy",
                      metrics=[self._accuracy_metric],
                      steps_per_execution=steps_per_execution,
                      run_eagerly=run_eagerly)
        return model, [ResultAssertingCallback()]
Пример #4
0
    def test_dataset_creator_usage_in_parameter_server_model_fit(self):
        cluster_def = multi_worker_test_base.create_in_process_cluster(
            num_workers=2, num_ps=1, rpc_layer="grpc")
        cluster_def["chief"] = [
            "localhost:%d" % multi_worker_test_base.pick_unused_port()
        ]
        strategy = parameter_server_strategy_v2.ParameterServerStrategyV2(
            SimpleClusterResolver(ClusterSpec(cluster_def), rpc_layer="grpc"))
        with strategy.scope():
            model = sequential.Sequential([core_layers.Dense(10)])
        model.compile(gradient_descent.SGD(), loss="mse")

        history = model.fit(dataset_creator.DatasetCreator(
            self._get_dataset_fn()),
                            epochs=10,
                            steps_per_epoch=10,
                            verbose=0)
        self.assertLen(history.history["loss"], 10)
Пример #5
0
  def test_saving_model_with_custom_object(self):
    with generic_utils.custom_object_scope(), self.cached_session():

      @generic_utils.register_keras_serializable()
      class CustomLoss(losses.MeanSquaredError):
        pass

      model = sequential.Sequential(
          [core.Dense(units=1, input_shape=(1,))])
      model.compile(optimizer='sgd', loss=CustomLoss())
      model.fit(np.zeros([10, 1]), np.zeros([10, 1]))

      temp_dir = self.get_temp_dir()
      filepath = os.path.join(temp_dir, 'saving')
      model.save(filepath)

      # Make sure the model can be correctly load back.
      _ = save.load_model(filepath, compile=True)
Пример #6
0
  def testSubSequentialTracking(self):

    class _Subclassed(training.Model):

      def __init__(self, wrapped):
        super(_Subclassed, self).__init__()
        self._wrapped = wrapped

      def call(self, x):
        return self._wrapped(x)

    model = sequential.Sequential()
    layer = core.Dense(1)
    model.add(layer)
    model2 = _Subclassed(model)
    model2(array_ops.ones([1, 2]))
    model2.m = (model,)
    self.assertIn(layer.kernel, model2.trainable_weights)
Пример #7
0
 def test_dense_features_layer(self, cycles):
     columns = [
         feature_column_v2.numeric_column("x"),
         feature_column_v2.numeric_column("y")
     ]
     layer = feature_column_v2.DenseFeatures(columns)
     model = sequential.Sequential([layer])
     model_input = {
         "x": constant_op.constant([[1.]]),
         "y": constant_op.constant([[2.]])
     }
     self.assertAllClose([[1., 2.]], model.predict(model_input))
     loaded = self.cycle(model, cycles)
     output, = loaded._default_save_signature(model_input).values()
     self.assertAllClose([[1., 2.]], output)
     signature_output, = loaded.signatures["serving_default"](
         **model_input).values()
     self.assertAllClose([[1., 2.]], signature_output)
Пример #8
0
    def test_dataset_creator_input_options(self):
        dataset_fn = lambda _: dataset_ops.DatasetV2.from_tensor_slices([1, 1])
        input_options = distribute_lib.InputOptions(
            experimental_fetch_to_device=True,
            experimental_per_replica_buffer_size=2)
        x = dataset_creator.DatasetCreator(dataset_fn,
                                           input_options=input_options)
        with collective_all_reduce_strategy.CollectiveAllReduceStrategy(
        ).scope():
            data_handler = data_adapter.get_data_handler(
                x,
                steps_per_epoch=2,
                model=sequential.Sequential([core_layers.Dense(10)]))

        # Ensuring the resulting `DistributedDatasetsFromFunction` has the right
        # options.
        self.assertTrue(
            data_handler._dataset._options.experimental_fetch_to_device)
        self.assertEqual(
            data_handler._dataset._options.
            experimental_per_replica_buffer_size, 2)
Пример #9
0
def mnist_model(input_shape):
  """Creates a MNIST model."""
  model = sequential_model_lib.Sequential()

  # Adding custom pass-through layer to visualize input images.
  model.add(LayerForImageSummary())

  model.add(
      conv_layer_lib.Conv2D(
          32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
  model.add(conv_layer_lib.Conv2D(64, (3, 3), activation='relu'))
  model.add(pool_layer_lib.MaxPooling2D(pool_size=(2, 2)))
  model.add(layer_lib.Dropout(0.25))
  model.add(layer_lib.Flatten())
  model.add(layer_lib.Dense(128, activation='relu'))
  model.add(layer_lib.Dropout(0.5))
  model.add(layer_lib.Dense(NUM_CLASSES, activation='softmax'))

  # Adding custom pass-through layer for summary recording.
  model.add(LayerForHistogramSummary())
  return model
Пример #10
0
 def testIgnoreSaveCounter(self):
   checkpoint_directory = self.get_temp_dir()
   checkpoint_prefix = os.path.join(checkpoint_directory, "ckpt")
   with self.cached_session() as session:
     # Create and save a model using Saver() before using a Checkpoint. This
     # generates a snapshot without the Checkpoint's `save_counter`.
     model = sequential.Sequential()
     model.add(core.Flatten(input_shape=(1,)))
     model.add(core.Dense(1))
     name_saver = saver_lib.Saver(model.trainable_variables)
     save_path = name_saver.save(
         sess=session, save_path=checkpoint_prefix, global_step=1)
     # Checkpoint.restore must successfully load that checkpoint.
     ckpt = trackable_utils.Checkpoint(model=model)
     status = ckpt.restore(save_path)
     status.assert_existing_objects_matched()
     # It should, however, refuse to load a checkpoint where an unrelated
     # `save_counter` variable is missing.
     model.layers[1].var = variables_lib.Variable(0., name="save_counter")
     status = ckpt.restore(save_path)
     with self.assertRaises(AssertionError):
       status.assert_existing_objects_matched()
Пример #11
0
 def test_linear_model_with_feature_column(self):
   vocab_list = ['alpha', 'beta', 'gamma']
   vocab_val = [0.4, 0.6, 0.9]
   data = np.random.choice(vocab_list, size=256)
   y = np.zeros_like(data, dtype=np.float32)
   for vocab, val in zip(vocab_list, vocab_val):
     indices = np.where(data == vocab)
     y[indices] = val + np.random.uniform(
         low=-0.01, high=0.01, size=indices[0].shape)
   cat_column = fc.categorical_column_with_vocabulary_list(
       key='symbol', vocabulary_list=vocab_list)
   ind_column = fc.indicator_column(cat_column)
   dense_feature_layer = dense_features_v2.DenseFeatures([ind_column])
   linear_model = linear.LinearModel(
       use_bias=False, kernel_initializer='zeros')
   combined = sequential.Sequential([dense_feature_layer, linear_model])
   opt = gradient_descent.SGD(learning_rate=0.1)
   combined.compile(opt, 'mse', [])
   combined.fit(x={'symbol': data}, y=y, batch_size=32, epochs=10)
   self.assertAllClose([[0.4], [0.6], [0.9]],
                       combined.layers[1].dense_layers[0].kernel.numpy(),
                       atol=0.01)
Пример #12
0
 def test_wide_deep_model_as_layer(self):
   linear_model = linear.LinearModel(units=1)
   dnn_model = sequential.Sequential([core.Dense(units=1)])
   linear_input = input_layer.Input(shape=(3,), name='linear')
   dnn_input = input_layer.Input(shape=(5,), name='dnn')
   wide_deep_model = wide_deep.WideDeepModel(linear_model, dnn_model)
   wide_deep_output = wide_deep_model((linear_input, dnn_input))
   input_b = input_layer.Input(shape=(1,), name='b')
   output_b = core.Dense(units=1)(input_b)
   model = training.Model(
       inputs=[linear_input, dnn_input, input_b],
       outputs=[wide_deep_output + output_b])
   linear_input_np = np.random.uniform(low=-5, high=5, size=(64, 3))
   dnn_input_np = np.random.uniform(low=-5, high=5, size=(64, 5))
   input_b_np = np.random.uniform(low=-5, high=5, size=(64,))
   output_np = linear_input_np[:, 0] + .2 * dnn_input_np[:, 1] + input_b_np
   model.compile(
       optimizer='sgd',
       loss='mse',
       metrics=[],
       run_eagerly=testing_utils.should_run_eagerly())
   model.fit([linear_input_np, dnn_input_np, input_b_np], output_np, epochs=5)
Пример #13
0
  def test_dataset_creator_input_options_with_cluster_coordinator(self):
    dataset_fn = lambda _: dataset_ops.DatasetV2.from_tensor_slices([1, 1])
    input_options = distribute_lib.InputOptions(
        experimental_fetch_to_device=True,
        experimental_per_replica_buffer_size=2)
    x = dataset_creator.DatasetCreator(dataset_fn, input_options=input_options)
    strategy = self._get_parameter_server_strategy()
    with strategy.scope():
      model = sequential.Sequential([core_layers.Dense(10)])
      model._cluster_coordinator = cluster_coordinator.ClusterCoordinator(
          strategy)
      data_handler = data_adapter.get_data_handler(
          x, steps_per_epoch=2, model=model)

    iter_rv = iter(data_handler._dataset)._values[0]
    iter_rv._rebuild_on(model._cluster_coordinator._cluster.workers[0])
    distributed_iterator = iter_rv._get_values()

    # Ensuring the resulting `DistributedIterator` has the right options.
    self.assertTrue(distributed_iterator._options.experimental_fetch_to_device)
    self.assertEqual(
        distributed_iterator._options.experimental_per_replica_buffer_size, 2)
Пример #14
0
  def test_restore_old_loss_scale_checkpoint(self):
    # Ensure a checkpoint from TF 2.2 can be loaded. The checkpoint format
    # of LossScaleOptimizer changed, but old checkpoints can still be loaded
    opt = gradient_descent.SGD(0.1, momentum=0.1)
    opt = loss_scale_optimizer.LossScaleOptimizer(opt, 'dynamic')
    model = sequential.Sequential([core.Dense(2,)])

    # The checkpoint and expected values were obtained from the program in
    # testdata/BUILD.
    ckpt_dir = test.test_src_dir_path(
        'python/keras/mixed_precision/experimental/testdata/lso_ckpt_tf2.2')
    model.load_weights(os.path.join(ckpt_dir, 'ckpt'))
    model.compile(opt, 'mse', run_eagerly=testing_utils.should_run_eagerly())
    model(np.zeros((2, 2)))  # Create model weights
    opt._create_all_weights(model.weights)
    expected_kernel = np.array([[9.229685, 10.901115], [10.370763, 9.757362]])
    expected_slot = np.array([[10.049943, 9.917691], [10.049943, 9.917691]])
    self.assertAllClose(self.evaluate(model.weights[0]), expected_kernel)
    self.assertAllClose(
        self.evaluate(opt.get_slot(model.weights[0], 'momentum')),
        expected_slot)
    self.assertEqual(self.evaluate(opt.loss_scale()), 32768)
    self.assertEqual(self.evaluate(opt.loss_scale._num_good_steps), 1)

    # Check restoring works even after the model is compiled and the weights
    # have been created.
    model.fit(np.random.normal(size=(2, 2)), np.random.normal(size=(2, 2)))
    self.assertNotAllClose(self.evaluate(model.weights[0]), expected_kernel)
    self.assertNotAllClose(
        self.evaluate(opt.get_slot(model.weights[0], 'momentum')),
        expected_slot)
    model.load_weights(os.path.join(ckpt_dir, 'ckpt'))
    self.assertAllClose(self.evaluate(model.weights[0]), expected_kernel)
    self.assertAllClose(
        self.evaluate(opt.get_slot(model.weights[0], 'momentum')),
        expected_slot)
    self.assertEqual(self.evaluate(opt.loss_scale()), 32768)
    self.assertEqual(self.evaluate(opt.loss_scale._num_good_steps), 1)
Пример #15
0
 def model_fn():
     """Mnist model with synthetic input."""
     data_format = 'channels_last'
     input_shape = [28, 28, 1]
     l = layers
     max_pool = l.MaxPooling2D((2, 2), (2, 2),
                               padding='same',
                               data_format=data_format)
     model = sequential.Sequential([
         l.Reshape(target_shape=input_shape, input_shape=(28 * 28, )),
         l.Conv2D(32,
                  5,
                  padding='same',
                  data_format=data_format,
                  activation=nn.relu), max_pool,
         l.Conv2D(64,
                  5,
                  padding='same',
                  data_format=data_format,
                  activation=nn.relu), max_pool,
         l.Flatten(),
         l.Dense(1024, activation=nn.relu),
         l.Dropout(0.4),
         l.Dense(10)
     ])
     image = random_ops.random_uniform([2, 28, 28])
     label = random_ops.random_uniform([2, 1],
                                       maxval=10,
                                       dtype=dtypes.int32)
     logits = model(image, training=True)
     # TODO(yuefengz): make loss a callable for eager mode.
     loss = losses.sparse_softmax_cross_entropy(labels=label,
                                                logits=logits)
     optimizer = adam.AdamOptimizer(learning_rate=1e-4)
     train_op = optimizer.minimize(
         loss, training_util.get_or_create_global_step())
     return train_op
Пример #16
0
    def test_Tensorboard_histogram_summaries_in_test_function(self):
        class FileWriterStub(object):
            def __init__(self, logdir, graph=None):
                self.logdir = logdir
                self.graph = graph
                self.steps_seen = []

            def add_summary(self, summary, global_step):
                summary_obj = summary_pb2.Summary()

                # ensure a valid Summary proto is being sent
                if isinstance(summary, bytes):
                    summary_obj.ParseFromString(summary)
                else:
                    assert isinstance(summary, summary_pb2.Summary)
                    summary_obj = summary

                # keep track of steps seen for the merged_summary op,
                # which contains the histogram summaries
                if len(summary_obj.value) > 1:
                    self.steps_seen.append(global_step)

            def flush(self):
                pass

            def close(self):
                pass

        def _init_writer(obj, _):
            obj.writer = FileWriterStub(obj.log_dir)

        np.random.seed(1337)
        tmpdir = self.get_temp_dir()
        self.addCleanup(shutil.rmtree, tmpdir, ignore_errors=True)
        (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
            train_samples=TRAIN_SAMPLES,
            test_samples=TEST_SAMPLES,
            input_shape=(INPUT_DIM, ),
            num_classes=NUM_CLASSES)
        y_test = np_utils.to_categorical(y_test)
        y_train = np_utils.to_categorical(y_train)

        with ops.Graph().as_default(), self.cached_session():
            model = sequential.Sequential()
            model.add(
                layers.Dense(NUM_HIDDEN,
                             input_dim=INPUT_DIM,
                             activation='relu'))
            # non_trainable_weights: moving_variance, moving_mean
            model.add(layers.BatchNormalization())
            model.add(layers.Dense(NUM_CLASSES, activation='softmax'))
            model.compile(loss='categorical_crossentropy',
                          optimizer='sgd',
                          metrics=['accuracy'])
            callbacks_v1.TensorBoard._init_writer = _init_writer
            tsb = callbacks_v1.TensorBoard(log_dir=tmpdir,
                                           histogram_freq=1,
                                           write_images=True,
                                           write_grads=True,
                                           batch_size=5)
            cbks = [tsb]

            # fit with validation data
            model.fit(x_train,
                      y_train,
                      batch_size=BATCH_SIZE,
                      validation_data=(x_test, y_test),
                      callbacks=cbks,
                      epochs=3,
                      verbose=0)

            self.assertAllEqual(tsb.writer.steps_seen, [0, 1, 2, 3, 4, 5])
Пример #17
0
 def test_unbuilt_model_does_not_prevent_saving(self):
     root = util.Checkpoint(model=sequential.Sequential([core.Dense(2)]))
     save.save(root, os.path.join(self.get_temp_dir(), "saved_model"))
Пример #18
0
    def directory_iterator_with_validation_split_test_helper(
            self, validation_split):
        if PIL is None:
            return  # Skip test if PIL is not available.

        num_classes = 2
        tmp_folder = tempfile.mkdtemp(prefix='test_images')

        # create folders and subfolders
        paths = []
        for cl in range(num_classes):
            class_directory = 'class-{}'.format(cl)
            classpaths = [
                class_directory,
                os.path.join(class_directory, 'subfolder-1'),
                os.path.join(class_directory, 'subfolder-2'),
                os.path.join(class_directory, 'subfolder-1', 'sub-subfolder')
            ]
            for path in classpaths:
                os.mkdir(os.path.join(tmp_folder, path))
            paths.append(classpaths)

        # save the images in the paths
        count = 0
        filenames = []
        for test_images in _generate_test_images():
            for im in test_images:
                # rotate image class
                im_class = count % num_classes
                # rotate subfolders
                classpaths = paths[im_class]
                filename = os.path.join(classpaths[count % len(classpaths)],
                                        'image-{}.jpg'.format(count))
                filenames.append(filename)
                im.save(os.path.join(tmp_folder, filename))
                count += 1

        # create iterator
        generator = preprocessing_image.ImageDataGenerator(
            validation_split=validation_split)

        with self.assertRaises(ValueError):
            generator.flow_from_directory(tmp_folder, subset='foo')

        num_validation = int(count * validation_split)
        num_training = count - num_validation
        train_iterator = generator.flow_from_directory(tmp_folder,
                                                       subset='training')
        self.assertEqual(train_iterator.samples, num_training)

        valid_iterator = generator.flow_from_directory(tmp_folder,
                                                       subset='validation')
        self.assertEqual(valid_iterator.samples, num_validation)

        # check number of classes and images
        self.assertEqual(len(train_iterator.class_indices), num_classes)
        self.assertEqual(len(train_iterator.classes), num_training)
        self.assertEqual(len(set(train_iterator.filenames) & set(filenames)),
                         num_training)

        model = sequential.Sequential([layers.Flatten(), layers.Dense(2)])
        model.compile(optimizer='sgd', loss='mse')
        model.fit(train_iterator, epochs=1)

        shutil.rmtree(tmp_folder)
Пример #19
0
    def _model_compile(self,
                       strategy,
                       steps_per_execution=1,
                       run_eagerly=False,
                       with_normalization_layer=False):
        class ResultAssertingCallback(callbacks_lib.Callback):
            def __init__(self):
                self._prev_epoch = -1
                self._loss_to_compare_against = 2  # Empirical initial value

            def on_epoch_end(self, epoch, logs=None):
                logging.info("testModelFit: epoch=%r, logs=%r", epoch, logs)
                if epoch <= self._prev_epoch:
                    raise RuntimeError(
                        "Epoch is supposed to be larger than previous.")
                self._prev_epoch = epoch
                is_loss_float = (logs.get("loss", None) is not None
                                 and isinstance(logs["loss"],
                                                (float, np.floating)))
                if not is_loss_float:
                    raise RuntimeError(
                        "loss is supposed to be in the logs and float.")
                if epoch == 0 or epoch == 9:
                    # Making sure the loss of first epoch is below 1, and that of last
                    # epoch is smaller than the first epoch.
                    if logs["loss"] > self._loss_to_compare_against:
                        raise RuntimeError(
                            "loss at epoch {} is larger than previous.".format(
                                epoch))
                    self._loss_to_compare_against = logs["loss"]

            def on_train_end(self, logs=None):
                if self._prev_epoch != 9:
                    raise RuntimeError("Unexpected last epoch: {}".format(
                        self._prev_epoch))

        # TODO(b/182193218): Use ParameterServerStrategy as a proper strategy
        # combination.
        if strategy == "ParameterServerStrategy":
            gpu_devices = config.list_physical_devices("GPU")
            if len(gpu_devices) > 1:
                self.skipTest("b/178452835: Multi-GPUs not supported in "
                              "ParameterServerStrategy.")
            strategy = parameter_server_strategy_v2.ParameterServerStrategyV2(
                multi_worker_testing_utils.make_parameter_server_cluster(3, 2),
                variable_partitioner=sharded_variable.FixedShardsPartitioner(
                    2))

        with strategy.scope():
            model = sequential.Sequential([core_layers.Dense(10)])
            if with_normalization_layer:
                norm = keras.layers.BatchNormalization(axis=-1,
                                                       input_shape=(4, 4, 3),
                                                       momentum=0.8)
                model.add(norm)

        model.compile(gradient_descent.SGD(),
                      loss="mse",
                      steps_per_execution=steps_per_execution,
                      run_eagerly=run_eagerly)
        return model, [ResultAssertingCallback()]
Пример #20
0
    def _test_mixed_precision(self, task_type, task_id, num_gpus):
        """Tests mixed precision works with the CollectiveAllReduceStrategy.

    This tests:
      1. Variables are in float32, by running with a small enough learning rate
         that if the variables are float16, their values wouldn't change when
         gradients are applied.
      2. The loss scale is doubled if there are no NaNs.
      3. The loss scale is halved if the first worker has a NaN, even if the
         other works do not have NaNs.

    Args:
      task_type: A string, such as "worker", indicating the type of the replica.
      task_id: Zero-indexed ID of the task.
      num_gpus: The number of GPUs to use.
    """
        d, master_target, config = self._get_test_object(
            task_type, task_id, num_gpus)
        # Should be set to mixed_float16 by caller.
        self.assertEqual(policy.global_policy().name, 'mixed_float16')

        with ops.Graph().as_default(), \
             self.cached_session(config=config,
                                 target=master_target) as sess:
            # The loss on the first worker is multiplied by this value. Allows
            # testing the first worker having NaN loss and gradients while keeping the
            # other workers' losses and gradients finite.
            loss_multiplier_for_first_worker = variables.Variable(
                1., dtype='float16', trainable=False)
            with d.scope():
                model = sequential.Sequential([
                    mp_test_util.MultiplyLayer(assert_type=dtypes.float16,
                                               input_shape=(1, )),
                ])
                loss_scale = loss_scale_module.DynamicLossScale(
                    2**10, increment_period=1)

                def model_fn():
                    """Simple model to test mixed precision."""
                    x = np.ones((1, 1))
                    loss = model(x, training=True)

                    if ((task_type == 'worker' and task_id == 0)
                            or task_type is task_id is None):
                        loss *= loss_multiplier_for_first_worker
                    # Learning rate is small enough that if applied to a float16 variable,
                    # the variable will not change. So this tests the learning rate is not
                    # applied to a float16 value, but instead the float32 variable.
                    optimizer = gradient_descent.GradientDescentOptimizer(
                        2**-14)
                    optimizer = loss_scale_optimizer.MixedPrecisionLossScaleOptimizer(
                        optimizer, loss_scale)
                    train_op = optimizer.minimize(
                        loss, training_util.get_or_create_global_step())
                    return train_op

                train_op = d.extended.call_for_each_replica(model_fn)
                train_op = d.group(d.experimental_local_results(train_op))

            sess.run(variables.global_variables_initializer())
            sess.run(train_op)

            (var, ) = model.trainable_weights
            # Variable starts at 1. Each worker's gradient is 2 ** -14, the learning
            # rate, and each worker's gradient will be subtracted from the variable.
            expected = 1 - d.num_replicas_in_sync * 2**-14
            self.assertEqual(sess.run(var), expected)
            # Loss scale should double, as are gradients are finite.
            self.assertEqual(sess.run(loss_scale()), 2**11)

            # Set the first worker to have NaN loss and gradients.
            sess.run(loss_multiplier_for_first_worker.assign(float('NaN')))
            sess.run(train_op)
            # Variable should not change, since first worker had NaN
            self.assertEqual(sess.run(var), expected)
            # Loss scale should halve due to NaN
            self.assertEqual(sess.run(loss_scale()), 2**10)
Пример #21
0
    def test_TensorBoard(self):
        np.random.seed(1337)

        temp_dir = self.get_temp_dir()
        self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True)

        (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
            train_samples=TRAIN_SAMPLES,
            test_samples=TEST_SAMPLES,
            input_shape=(INPUT_DIM, ),
            num_classes=NUM_CLASSES)
        y_test = np_utils.to_categorical(y_test)
        y_train = np_utils.to_categorical(y_train)

        def data_generator(train):
            if train:
                max_batch_index = len(x_train) // BATCH_SIZE
            else:
                max_batch_index = len(x_test) // BATCH_SIZE
            i = 0
            while 1:
                if train:
                    yield (x_train[i * BATCH_SIZE:(i + 1) * BATCH_SIZE],
                           y_train[i * BATCH_SIZE:(i + 1) * BATCH_SIZE])
                else:
                    yield (x_test[i * BATCH_SIZE:(i + 1) * BATCH_SIZE],
                           y_test[i * BATCH_SIZE:(i + 1) * BATCH_SIZE])
                i += 1
                i %= max_batch_index

        # case: Sequential
        with ops.Graph().as_default(), self.cached_session():
            model = sequential.Sequential()
            model.add(
                layers.Dense(NUM_HIDDEN,
                             input_dim=INPUT_DIM,
                             activation='relu'))
            # non_trainable_weights: moving_variance, moving_mean
            model.add(layers.BatchNormalization())
            model.add(layers.Dense(NUM_CLASSES, activation='softmax'))
            model.compile(loss='categorical_crossentropy',
                          optimizer='sgd',
                          metrics=['accuracy'])
            tsb = callbacks_v1.TensorBoard(log_dir=temp_dir,
                                           histogram_freq=1,
                                           write_images=True,
                                           write_grads=True,
                                           batch_size=5)
            cbks = [tsb]

            # fit with validation data
            model.fit(x_train,
                      y_train,
                      batch_size=BATCH_SIZE,
                      validation_data=(x_test, y_test),
                      callbacks=cbks,
                      epochs=3,
                      verbose=0)

            # fit with validation data and accuracy
            model.fit(x_train,
                      y_train,
                      batch_size=BATCH_SIZE,
                      validation_data=(x_test, y_test),
                      callbacks=cbks,
                      epochs=2,
                      verbose=0)

            # fit generator with validation data
            model.fit_generator(data_generator(True),
                                len(x_train),
                                epochs=2,
                                validation_data=(x_test, y_test),
                                callbacks=cbks,
                                verbose=0)

            # fit generator without validation data
            # histogram_freq must be zero
            tsb.histogram_freq = 0
            model.fit_generator(data_generator(True),
                                len(x_train),
                                epochs=2,
                                callbacks=cbks,
                                verbose=0)

            # fit generator with validation data and accuracy
            tsb.histogram_freq = 1
            model.fit_generator(data_generator(True),
                                len(x_train),
                                epochs=2,
                                validation_data=(x_test, y_test),
                                callbacks=cbks,
                                verbose=0)

            # fit generator without validation data and accuracy
            tsb.histogram_freq = 0
            model.fit_generator(data_generator(True),
                                len(x_train),
                                epochs=2,
                                callbacks=cbks)
            assert os.path.exists(temp_dir)