Ejemplo n.º 1
0
    def test_hash_ragged_string_input_farmhash(self):
        layer = hashing.Hashing(num_bins=2)
        inp_data = tf.ragged.constant([['omar', 'stringer', 'marlo', 'wire'],
                                       ['marlo', 'skywalker', 'wire']],
                                      dtype=tf.string)
        out_data = layer(inp_data)
        # Same hashed output as test_hash_sparse_input_farmhash
        expected_output = [[0, 0, 1, 0], [1, 0, 0]]
        self.assertAllEqual(expected_output, out_data)

        inp_t = input_layer.Input(shape=(None, ), ragged=True, dtype=tf.string)
        out_t = layer(inp_t)
        model = training.Model(inputs=inp_t, outputs=out_t)
        self.assertAllClose(out_data, model.predict(inp_data))
Ejemplo n.º 2
0
    def test_from_row_starts(self):
        inp = layers.Input(shape=[None])
        out = tf.RaggedTensor.from_row_starts(inp, row_starts=[0, 4, 4, 7, 8])
        model = training.Model(inp, out)

        x = tf.constant([3, 1, 4, 1, 5, 9, 2, 6])
        expected = tf.RaggedTensor.from_row_starts(x,
                                                   row_starts=[0, 4, 4, 7, 8])
        self.assertAllEqual(model(x), expected)

        # Test that the model can serialize and deserialize as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(x), expected)
Ejemplo n.º 3
0
 def testIter(self):
   model = training.Model()
   model.d = {1: 3}
   model.d[1] = 3
   self.assertEqual([1], list(model.d))
   new_dict = {}
   # This update() is super tricky. If the dict wrapper subclasses dict,
   # CPython will access its storage directly instead of calling any
   # methods/properties on the object. So the options are either not to
   # subclass dict (in which case update will call normal iter methods, but the
   # object won't pass isinstance checks) or to subclass dict and keep that
   # storage updated (no shadowing all its methods like ListWrapper).
   new_dict.update(model.d)
   self.assertEqual({1: 3}, new_dict)
Ejemplo n.º 4
0
    def test_from_uniform_row_length(self):
        inp = layers.Input(shape=[None])
        out = tf.RaggedTensor.from_uniform_row_length(inp, 2, 8)
        model = training.Model(inp, out)

        x = tf.constant(
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
        expected = tf.RaggedTensor.from_uniform_row_length(x, 2, 8)
        self.assertAllEqual(model(x), expected)

        # Test that the model can serialize and deserialize as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(x), expected)
Ejemplo n.º 5
0
    def test_sparse_instance_property(self, property_name):
        inp = layers.Input(shape=[3], sparse=True)
        out = getattr(inp, property_name)
        model = training.Model(inp, out)

        x = tf.SparseTensor([[0, 0], [0, 1], [1, 1], [1, 2]], [1, 2, 3, 4],
                            [2, 3])
        expected_property = getattr(x, property_name)
        self.assertAllEqual(model(x), expected_property)

        # Test that it works with serialization and deserialization as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(x), expected_property)
Ejemplo n.º 6
0
  def test_crossing_ragged_inputs(self):
    inputs_0 = tf.ragged.constant(
        [['omar', 'skywalker'], ['marlo']],
        dtype=tf.string)
    inputs_1 = tf.ragged.constant(
        [['a'], ['b']],
        dtype=tf.string)
    inp_0_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)
    inp_1_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)

    non_hashed_layer = category_crossing.CategoryCrossing()
    out_t = non_hashed_layer([inp_0_t, inp_1_t])
    model = training.Model(inputs=[inp_0_t, inp_1_t], outputs=out_t)
    expected_output = [[b'omar_X_a', b'skywalker_X_a'], [b'marlo_X_b']]
    self.assertAllEqual(expected_output, model.predict([inputs_0, inputs_1]))
Ejemplo n.º 7
0
    def test_invalid_custom_metric_class_error_msg(self):
        x = layers.Input(shape=(2, ))
        y = layers.Dense(3)(x)
        model = training_module.Model(x, y)

        class BadMetric(metrics.Metric):
            def update_state(self, y_true, y_pred, sample_weight=None):
                return

            def result(self):
                return

        with self.assertRaisesRegex(RuntimeError, "can only be a single"):
            model.compile("sgd", "mse", metrics=[BadMetric()])
            model.fit(np.ones((10, 2)), np.ones((10, 3)))
Ejemplo n.º 8
0
 def test_state_saving_and_loading(self):
   with self.cached_session():
     input_data = np.random.random((1, 2))
     rff_layer = kernel_layers.RandomFourierFeatures(output_dim=10, scale=3.0)
     inputs = input_layer.Input((2,))
     outputs = rff_layer(inputs)
     model = training.Model(inputs, outputs)
     output_data = model.predict(input_data)
     temp_dir = self.get_temp_dir()
     self.addCleanup(shutil.rmtree, temp_dir)
     saved_model_dir = os.path.join(temp_dir, 'rff_model')
     model.save(saved_model_dir)
     new_model = save.load_model(saved_model_dir)
     new_output_data = new_model.predict(input_data)
     self.assertAllClose(output_data, new_output_data, atol=1e-4)
Ejemplo n.º 9
0
    def test_wide_deep_model_with_multi_outputs(self):
        inp = input_layer.Input(shape=(1, ), name='linear')
        l = linear.LinearModel(units=2, use_bias=False)(inp)
        l1, l2 = tf.split(l, num_or_size_splits=2, axis=1)
        linear_model = training.Model(inp, [l1, l2])
        linear_model.set_weights([np.asarray([[0.5, 0.3]])])
        h = core.Dense(units=2, use_bias=False)(inp)
        h1, h2 = tf.split(h, num_or_size_splits=2, axis=1)
        dnn_model = training.Model(inp, [h1, h2])
        dnn_model.set_weights([np.asarray([[0.1, -0.5]])])
        wide_deep_model = wide_deep.WideDeepModel(linear_model, dnn_model)
        inp_np = np.asarray([[1.]])
        out1, out2 = wide_deep_model(inp_np)
        # output should be (0.5 + 0.1), and (0.3 - 0.5)
        self.assertAllClose([[0.6]], out1)
        self.assertAllClose([[-0.2]], out2)

        wide_deep_model = wide_deep.WideDeepModel(linear_model,
                                                  dnn_model,
                                                  activation='relu')
        out1, out2 = wide_deep_model(inp_np)
        # output should be relu((0.5 + 0.1)), and relu((0.3 - 0.5))
        self.assertAllClose([[0.6]], out1)
        self.assertAllClose([[0.]], out2)
Ejemplo n.º 10
0
 def test_crossing_ragged_inputs_depth_tuple(self):
   layer = category_crossing.CategoryCrossing(depth=[2, 3])
   inputs_0 = tf.ragged.constant([['a'], ['b'], ['c']])
   inputs_1 = tf.ragged.constant([['d'], ['e'], ['f']])
   inputs_2 = tf.ragged.constant([['g'], ['h'], ['i']])
   inp_0_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)
   inp_1_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)
   inp_2_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)
   out_t = layer([inp_0_t, inp_1_t, inp_2_t])
   model = training.Model([inp_0_t, inp_1_t, inp_2_t], out_t)
   expected_output = [[b'a_X_d', b'a_X_g', b'd_X_g', b'a_X_d_X_g'],
                      [b'b_X_e', b'b_X_h', b'e_X_h', b'b_X_e_X_h'],
                      [b'c_X_f', b'c_X_i', b'f_X_i', b'c_X_f_X_i']]
   output = model.predict([inputs_0, inputs_1, inputs_2])
   self.assertIsInstance(output, tf.RaggedTensor)
   self.assertAllEqual(expected_output, output)
Ejemplo n.º 11
0
 def test_crossing_dense_inputs_depth_tuple(self):
   layer = category_crossing.CategoryCrossing(depth=[2, 3])
   inputs_0 = tf.constant([['a'], ['b'], ['c']])
   inputs_1 = tf.constant([['d'], ['e'], ['f']])
   inputs_2 = tf.constant([['g'], ['h'], ['i']])
   inp_0_t = input_layer.Input(shape=(1,), dtype=tf.string)
   inp_1_t = input_layer.Input(shape=(1,), dtype=tf.string)
   inp_2_t = input_layer.Input(shape=(1,), dtype=tf.string)
   out_t = layer([inp_0_t, inp_1_t, inp_2_t])
   model = training.Model([inp_0_t, inp_1_t, inp_2_t], out_t)
   expected_outputs_0 = [[b'a_X_d', b'a_X_g', b'd_X_g', b'a_X_d_X_g']]
   expected_outputs_1 = [[b'b_X_e', b'b_X_h', b'e_X_h', b'b_X_e_X_h']]
   expected_outputs_2 = [[b'c_X_f', b'c_X_i', b'f_X_i', b'c_X_f_X_i']]
   expected_output = tf.concat(
       [expected_outputs_0, expected_outputs_1, expected_outputs_2], axis=0)
   self.assertAllEqual(expected_output,
                       model.predict([inputs_0, inputs_1, inputs_2]))
Ejemplo n.º 12
0
    def test_from_nested_row_splits(self):
        nested_row_splits = [
            tf.constant([0, 2, 3, 3, 5], tf.int64),
            tf.constant([0, 2, 2, 5, 6, 7], tf.int64)
        ]
        inp = layers.Input(shape=[None], dtype=tf.string)
        out = tf.RaggedTensor.from_nested_row_splits(inp, nested_row_splits)
        model = training.Model(inp, out)

        x = tf.constant(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
        expected = tf.RaggedTensor.from_nested_row_splits(x, nested_row_splits)
        self.assertAllEqual(model(x), expected)

        # Test that the model can serialize and deserialize as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(x), expected)
Ejemplo n.º 13
0
  def test_crossing_ragged_inputs_depth_int(self):
    layer = category_crossing.CategoryCrossing(depth=1)
    inputs_0 = tf.ragged.constant([['a'], ['b'], ['c']])
    inputs_1 = tf.ragged.constant([['d'], ['e'], ['f']])
    output = layer([inputs_0, inputs_1])
    expected_output = [[b'a', b'd'], [b'b', b'e'], [b'c', b'f']]
    self.assertIsInstance(output, tf.RaggedTensor)
    self.assertAllEqual(expected_output, output)

    layer = category_crossing.CategoryCrossing(depth=2)
    inp_0_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)
    inp_1_t = input_layer.Input(shape=(None,), ragged=True, dtype=tf.string)
    out_t = layer([inp_0_t, inp_1_t])
    model = training.Model([inp_0_t, inp_1_t], out_t)
    expected_output = [[b'a', b'd', b'a_X_d'], [b'b', b'e', b'b_X_e'],
                       [b'c', b'f', b'c_X_f']]
    self.assertAllEqual(expected_output, model.predict([inputs_0, inputs_1]))
Ejemplo n.º 14
0
    def test_from_sparse(self):
        inp = layers.Input(shape=[None], sparse=True, dtype=tf.string)
        out = tf.RaggedTensor.from_sparse(inp)
        model = training.Model(inp, out)

        indices = [[0, 0], [1, 0], [1, 1], [2, 0]]
        values = [b'a', b'b', b'c', b'd']
        shape = [4, 5]
        sp_value = tf.SparseTensor(indices, values, shape)

        expected = tf.RaggedTensor.from_sparse(sp_value)
        self.assertAllEqual(model(sp_value), expected)

        # Test that the model can serialize and deserialize as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(sp_value), expected)
Ejemplo n.º 15
0
    def test_crossing_dense_inputs_depth_int(self):
        layer = category_crossing.CategoryCrossing(depth=1)
        inputs_0 = tf.constant([['a'], ['b'], ['c']])
        inputs_1 = tf.constant([['d'], ['e'], ['f']])
        output = layer([inputs_0, inputs_1])
        expected_output = [[b'a', b'd'], [b'b', b'e'], [b'c', b'f']]
        self.assertAllEqual(expected_output, output)

        layer = category_crossing.CategoryCrossing(depth=2)
        inp_0_t = input_layer.Input(shape=(1, ), dtype=tf.string)
        inp_1_t = input_layer.Input(shape=(1, ), dtype=tf.string)
        out_t = layer([inp_0_t, inp_1_t])
        model = training.Model([inp_0_t, inp_1_t], out_t)
        crossed_output = [[b'a_X_d'], [b'b_X_e'], [b'c_X_f']]
        expected_output = tf.concat([expected_output, crossed_output], axis=1)
        self.assertAllEqual(expected_output,
                            model.predict([inputs_0, inputs_1]))
Ejemplo n.º 16
0
    def test_from_row_limits(self):
        row_limits = tf.constant([2, 2, 5, 6, 7], tf.int64)

        inp = layers.Input(shape=[None], dtype=tf.string)
        out = tf.RaggedTensor.from_row_limits(inp, row_limits, validate=False)
        model = training.Model(inp, out)

        x = tf.constant(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
        expected = tf.RaggedTensor.from_row_limits(x,
                                                   row_limits,
                                                   validate=False)
        self.assertAllEqual(model(x), expected)

        # Test that the model can serialize and deserialize as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(x), expected)
Ejemplo n.º 17
0
    def test_getitem(self):
        # Test slicing / getitem
        inp = layers.Input(shape=(None, 2), ragged=True)
        out = inp[:, :2]
        model = training.Model(inp, out)

        x = tf.RaggedTensor.from_row_lengths(
            tf.cast(np.random.randn(6, 2), dtype=tf.float32), [3, 1, 2])
        expected = x[:, :2]

        self.assertAllEqual(model(x), expected)

        # Test that models w/ slicing are correctly serialized/deserialized
        config = model.get_config()
        model = training.Model.from_config(config)

        self.assertAllEqual(model(x), expected)
Ejemplo n.º 18
0
    def test_from_nested_row_lengths(self):
        nested_row_lengths = [
            tf.constant([2, 1, 0, 2], tf.int64),
            tf.constant([2, 0, 3, 1, 1], tf.int64),
        ]
        inp = layers.Input(shape=[None], dtype=tf.string)
        out = tf.RaggedTensor.from_nested_row_lengths(inp, nested_row_lengths)
        model = training.Model(inp, out)

        x = tf.constant(["a", "b", "c", "d", "e", "f", "g"])
        expected = tf.RaggedTensor.from_nested_row_lengths(
            x, nested_row_lengths)
        self.assertAllEqual(model(x), expected)

        # Test that the model can serialize and deserialize as well
        model_config = model.get_config()
        model2 = training.Model.from_config(model_config)
        self.assertAllEqual(model2(x), expected)
Ejemplo n.º 19
0
    def test_invalid_custom_metric_fn_error_msg(self):
        x = layers.Input(shape=(2, ))
        y = layers.Dense(3)(x)
        model = training_module.Model(x, y)

        def bad_metric(y_true, y_pred, sample_weight=None):  # pylint: disable=unused-argument
            return None

        def dict_metric(y_true, y_pred, sample_weight=None):  # pylint: disable=unused-argument
            return {'value': 0.}

        with self.assertRaisesRegex(
                RuntimeError, 'The output of a metric function can only be'):
            model.compile('sgd', 'mse', metrics=[bad_metric])
            model.fit(np.ones((10, 2)), np.ones((10, 3)))
        with self.assertRaisesRegex(RuntimeError,
                                    'To return a dict of values, implement'):
            model.compile('sgd', 'mse', metrics=[dict_metric])
            model.fit(np.ones((10, 2)), np.ones((10, 3)))
Ejemplo n.º 20
0
    def test_invalid_custom_metric_fn_error_msg(self):
        x = layers.Input(shape=(2, ))
        y = layers.Dense(3)(x)
        model = training_module.Model(x, y)

        def bad_metric(y_true, y_pred, sample_weight=None):
            return None

        def dict_metric(y_true, y_pred, sample_weight=None):
            return {"value": 0.0}

        with self.assertRaisesRegex(
                RuntimeError, "The output of a metric function can only be"):
            model.compile("sgd", "mse", metrics=[bad_metric])
            model.fit(np.ones((10, 2)), np.ones((10, 3)))
        with self.assertRaisesRegex(RuntimeError,
                                    "To return a dict of values, implement"):
            model.compile("sgd", "mse", metrics=[dict_metric])
            model.fit(np.ones((10, 2)), np.ones((10, 3)))
Ejemplo n.º 21
0
 def testNonAppendNotTrackable(self):
   # Non-append mutations (deleting or overwriting values) are OK when the
   # values aren't tracked.
   a = tf.Module()
   a.d = {}
   a.d["a"] = [3]
   a.d[1] = 3
   a.d[1] = 2
   self.assertEqual(2, a.d[1])
   del a.d[1]
   a.d[2] = data_structures.NoDependency(tf.Module())
   second = tf.Module()
   a.d[2] = data_structures.NoDependency(second)
   self.assertIs(second, a.d[2])
   self.assertEqual([a, a.d, a.d["a"]], util.list_objects(a))
   model = training.Model()
   model.sub = a
   save_path = os.path.join(self.get_temp_dir(), "ckpt")
   model.save_weights(save_path)
   model.load_weights(save_path)
Ejemplo n.º 22
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)
Ejemplo n.º 23
0
    def test_sequence_on_epoch_end(self):
        class MySequence(data_utils.Sequence):
            def __init__(self):
                self.epochs = 0

            def __getitem__(self, idx):
                return np.ones([10, 10], np.float32), np.ones([10, 1],
                                                              np.float32)

            def __len__(self):
                return 2

            def on_epoch_end(self):
                self.epochs += 1

        inputs = input_layer.Input(10)
        outputs = layers_module.Dense(1)(inputs)
        model = training.Model(inputs, outputs)
        model.compile('sgd', 'mse')
        my_seq = MySequence()
        model.fit(my_seq, epochs=2)
        self.assertEqual(my_seq.epochs, 2)
Ejemplo n.º 24
0
        def prepare_simple_model(input_tensor, loss_name, target):
            axis = 1 if backend.image_data_format() == "channels_first" else -1
            loss = None
            num_channels = None
            activation = None
            if loss_name == "sparse_categorical_crossentropy":
                loss = lambda y_true, y_pred: backend.sparse_categorical_crossentropy(  # pylint: disable=g-long-lambda
                    y_true,
                    y_pred,
                    axis=axis)
                num_channels = int(np.amax(target) + 1)
                activation = "softmax"
            elif loss_name == "categorical_crossentropy":
                loss = lambda y_true, y_pred: backend.categorical_crossentropy(  # pylint: disable=g-long-lambda
                    y_true,
                    y_pred,
                    axis=axis)
                num_channels = target.shape[axis]
                activation = "softmax"
            elif loss_name == "binary_crossentropy":
                loss = lambda y_true, y_pred: backend.binary_crossentropy(  # pylint: disable=g-long-lambda, unnecessary-lambda
                    y_true, y_pred)
                num_channels = target.shape[axis]
                activation = "sigmoid"

            predictions = Conv2D(
                num_channels,
                1,
                activation=activation,
                kernel_initializer="ones",
                bias_initializer="ones",
            )(input_tensor)
            simple_model = training.Model(inputs=input_tensor,
                                          outputs=predictions)
            simple_model.compile(optimizer="rmsprop", loss=loss)
            return simple_model
Ejemplo n.º 25
0
  def testOptimizerWithKerasModel(self):
    a = input_layer.Input(shape=(3,), name='input_a')
    b = input_layer.Input(shape=(3,), name='input_b')

    dense = core.Dense(4, name='dense')
    c = dense(a)
    d = dense(b)
    e = core.Dropout(0.5, name='dropout')(c)

    model = training.Model([a, b], [d, e])

    optimizer = gradient_descent.SGD(learning_rate=0.001)
    loss = 'mse'
    model.compile(optimizer, loss, metrics=['mae'])

    input_a_np = np.random.random((10, 3))
    input_b_np = np.random.random((10, 3))

    output_d_np = np.random.random((10, 4))
    output_e_np = np.random.random((10, 4))

    model.fit([input_a_np, input_b_np], [output_d_np, output_e_np],
              epochs=1,
              batch_size=5)
Ejemplo n.º 26
0
    def test_TensorBoard_multi_input_output(self):
        np.random.seed(1337)
        tmpdir = self.get_temp_dir()
        self.addCleanup(shutil.rmtree, tmpdir, ignore_errors=True)

        with tf.Graph().as_default(), self.cached_session():
            filepath = os.path.join(tmpdir, "logs")

            (x_train, y_train), (x_test, y_test) = test_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:
                        # simulate multi-input/output models
                        yield (
                            [x_train[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]] * 2,
                            [y_train[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]] * 2,
                        )
                    else:
                        yield (
                            [x_test[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]] * 2,
                            [y_test[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]] * 2,
                        )
                    i += 1
                    i %= max_batch_index

            inp1 = input_layer.Input((INPUT_DIM, ))
            inp2 = input_layer.Input((INPUT_DIM, ))
            inp = layers.add([inp1, inp2])
            hidden = layers.Dense(2, activation="relu")(inp)
            hidden = layers.Dropout(0.1)(hidden)
            output1 = layers.Dense(NUM_CLASSES, activation="softmax")(hidden)
            output2 = layers.Dense(NUM_CLASSES, activation="softmax")(hidden)
            model = training.Model([inp1, inp2], [output1, output2])
            model.compile(
                loss="categorical_crossentropy",
                optimizer="sgd",
                metrics=["accuracy"],
            )

            # we must generate new callbacks for each test, as they aren't stateless
            def callbacks_factory(histogram_freq):
                return [
                    callbacks_v1.TensorBoard(
                        log_dir=filepath,
                        histogram_freq=histogram_freq,
                        write_images=True,
                        write_grads=True,
                        batch_size=5,
                    )
                ]

            # fit without validation data
            model.fit(
                [x_train] * 2,
                [y_train] * 2,
                batch_size=BATCH_SIZE,
                callbacks=callbacks_factory(histogram_freq=0),
                epochs=3,
            )

            # fit with validation data and accuracy
            model.fit(
                [x_train] * 2,
                [y_train] * 2,
                batch_size=BATCH_SIZE,
                validation_data=([x_test] * 2, [y_test] * 2),
                callbacks=callbacks_factory(histogram_freq=1),
                epochs=2,
            )

            # fit generator without validation data
            model.fit_generator(
                data_generator(True),
                len(x_train),
                epochs=2,
                callbacks=callbacks_factory(histogram_freq=0),
            )

            # fit generator with validation data and accuracy
            model.fit_generator(
                data_generator(True),
                len(x_train),
                epochs=2,
                validation_data=([x_test] * 2, [y_test] * 2),
                callbacks=callbacks_factory(histogram_freq=1),
            )
            assert os.path.isdir(filepath)
Ejemplo n.º 27
0
def VGG19(include_top=True,
          weights='imagenet',
          input_tensor=None,
          input_shape=None,
          pooling=None,
          classes=1000,
          classifier_activation='softmax'):
    """Instantiates the VGG19 architecture.

  Reference:
  - [Very Deep Convolutional Networks for Large-Scale Image Recognition](
      https://arxiv.org/abs/1409.1556) (ICLR 2015)

  For image classification use cases, see
  [this page for detailed examples](
    https://keras.io/api/applications/#usage-examples-for-image-classification-models).

  For transfer learning use cases, make sure to read the
  [guide to transfer learning & fine-tuning](
    https://keras.io/guides/transfer_learning/).

  The default input size for this model is 224x224.

  Note: each Keras Application expects a specific kind of input preprocessing.
  For VGG19, call `tf.keras.applications.vgg19.preprocess_input` on your
  inputs before passing them to the model.
  `vgg19.preprocess_input` will convert the input images from RGB to BGR,
  then will zero-center each color channel with respect to the ImageNet dataset,
  without scaling.

  Args:
    include_top: whether to include the 3 fully-connected
      layers at the top of the network.
    weights: one of `None` (random initialization),
        'imagenet' (pre-training on ImageNet),
        or the path to the weights file to be loaded.
    input_tensor: optional Keras tensor
      (i.e. output of `layers.Input()`)
      to use as image input for the model.
    input_shape: optional shape tuple, only to be specified
      if `include_top` is False (otherwise the input shape
      has to be `(224, 224, 3)`
      (with `channels_last` data format)
      or `(3, 224, 224)` (with `channels_first` data format).
      It should have exactly 3 inputs channels,
      and width and height should be no smaller than 32.
      E.g. `(200, 200, 3)` would be one valid value.
    pooling: Optional pooling mode for feature extraction
      when `include_top` is `False`.
      - `None` means that the output of the model will be
          the 4D tensor output of the
          last convolutional block.
      - `avg` means that global average pooling
          will be applied to the output of the
          last convolutional block, and thus
          the output of the model will be a 2D tensor.
      - `max` means that global max pooling will
          be applied.
    classes: optional number of classes to classify images
      into, only to be specified if `include_top` is True, and
      if no `weights` argument is specified.
    classifier_activation: A `str` or callable. The activation function to use
      on the "top" layer. Ignored unless `include_top=True`. Set
      `classifier_activation=None` to return the logits of the "top" layer.
      When loading pretrained weights, `classifier_activation` can only
      be `None` or `"softmax"`.

  Returns:
    A `keras.Model` instance.
  """
    if not (weights in {'imagenet', None} or tf.io.gfile.exists(weights)):
        raise ValueError('The `weights` argument should be either '
                         '`None` (random initialization), `imagenet` '
                         '(pre-training on ImageNet), '
                         'or the path to the weights file to be loaded.')

    if weights == 'imagenet' and include_top and classes != 1000:
        raise ValueError(
            'If using `weights` as `"imagenet"` with `include_top`'
            ' as true, `classes` should be 1000')
    # Determine proper input shape
    input_shape = imagenet_utils.obtain_input_shape(
        input_shape,
        default_size=224,
        min_size=32,
        data_format=backend.image_data_format(),
        require_flatten=include_top,
        weights=weights)

    if input_tensor is None:
        img_input = layers.Input(shape=input_shape)
    else:
        if not backend.is_keras_tensor(input_tensor):
            img_input = layers.Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor
    # Block 1
    x = layers.Conv2D(64, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block1_conv1')(img_input)
    x = layers.Conv2D(64, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block1_conv2')(x)
    x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)

    # Block 2
    x = layers.Conv2D(128, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block2_conv1')(x)
    x = layers.Conv2D(128, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block2_conv2')(x)
    x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)

    # Block 3
    x = layers.Conv2D(256, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block3_conv1')(x)
    x = layers.Conv2D(256, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block3_conv2')(x)
    x = layers.Conv2D(256, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block3_conv3')(x)
    x = layers.Conv2D(256, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block3_conv4')(x)
    x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)

    # Block 4
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block4_conv1')(x)
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block4_conv2')(x)
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block4_conv3')(x)
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block4_conv4')(x)
    x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)

    # Block 5
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block5_conv1')(x)
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block5_conv2')(x)
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block5_conv3')(x)
    x = layers.Conv2D(512, (3, 3),
                      activation='relu',
                      padding='same',
                      name='block5_conv4')(x)
    x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)

    if include_top:
        # Classification block
        x = layers.Flatten(name='flatten')(x)
        x = layers.Dense(4096, activation='relu', name='fc1')(x)
        x = layers.Dense(4096, activation='relu', name='fc2')(x)
        imagenet_utils.validate_activation(classifier_activation, weights)
        x = layers.Dense(classes,
                         activation=classifier_activation,
                         name='predictions')(x)
    else:
        if pooling == 'avg':
            x = layers.GlobalAveragePooling2D()(x)
        elif pooling == 'max':
            x = layers.GlobalMaxPooling2D()(x)

    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = layer_utils.get_source_inputs(input_tensor)
    else:
        inputs = img_input
    # Create model.
    model = training.Model(inputs, x, name='vgg19')

    # Load weights.
    if weights == 'imagenet':
        if include_top:
            weights_path = data_utils.get_file(
                'vgg19_weights_tf_dim_ordering_tf_kernels.h5',
                WEIGHTS_PATH,
                cache_subdir='models',
                file_hash='cbe5617147190e668d6c5d5026f83318')
        else:
            weights_path = data_utils.get_file(
                'vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5',
                WEIGHTS_PATH_NO_TOP,
                cache_subdir='models',
                file_hash='253f8cb515780f3b799900260a226db6')
        model.load_weights(weights_path)
    elif weights is not None:
        model.load_weights(weights)

    return model
Ejemplo n.º 28
0
def ResNetRS(
    depth: int,
    input_shape=None,
    bn_momentum=0.0,
    bn_epsilon=1e-5,
    activation: str = "relu",
    se_ratio=0.25,
    dropout_rate=0.25,
    drop_connect_rate=0.2,
    include_top=True,
    block_args: List[Dict[str, int]] = None,
    model_name="resnet-rs",
    pooling=None,
    weights="imagenet",
    input_tensor=None,
    classes=1000,
    classifier_activation: Union[str, Callable] = "softmax",
    include_preprocessing=True,
):
    """Build Resnet-RS model, given provided parameters.

    Args:
        depth: Depth of ResNet network.
        input_shape: optional shape tuple. It should have exactly 3 inputs
          channels, and width and height should be no smaller than 32. E.g.
          (200, 200, 3) would be one valid value.
        bn_momentum: Momentum parameter for Batch Normalization layers.
        bn_epsilon: Epsilon parameter for Batch Normalization layers.
        activation: activation function.
        se_ratio: Squeeze and Excitation layer ratio.
        dropout_rate: dropout rate before final classifier layer.
        drop_connect_rate: dropout rate at skip connections.
        include_top: whether to include the fully-connected layer at the top of
          the network.
        block_args: list of dicts, parameters to construct block modules.
        model_name: name of the model.
        pooling: optional pooling mode for feature extraction when `include_top`
          is `False`.
          - `None` means that the output of the model will be the 4D tensor
            output of the last convolutional layer.
          - `avg` means that global average pooling will be applied to the
            output of the last convolutional layer, and thus the output of the
            model will be a 2D tensor.
          - `max` means that global max pooling will be applied.
        weights: one of `None` (random initialization), `'imagenet'`
          (pre-training on ImageNet), or the path to the weights file to be
          loaded. Note- one model can have multiple imagenet variants depending
          on input shape it was trained with. For input_shape 224x224 pass
          `imagenet-i224` as argument. By default, highest input shape weights
          are downloaded.
        input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to
          use as image input for the model.
        classes: optional number of classes to classify images into, only to be
          specified if `include_top` is True, and if no `weights` argument is
          specified.
        classifier_activation: A `str` or callable. The activation function to
          use on the "top" layer. Ignored unless `include_top=True`. Set
          `classifier_activation=None` to return the logits of the "top" layer.
        include_preprocessing: Boolean, whether to include the preprocessing
          layer (`Rescaling`) at the bottom of the network. Defaults to `True`.
          Note- Input image is normalized by ImageNet mean and standard
          deviation.

    Returns:
        A `tf.keras.Model` instance.

    Raises:
        ValueError: in case of invalid argument for `weights`, or invalid input
            shape.
        ValueError: if `classifier_activation` is not `softmax` or `None` when
            using a pretrained top layer.
    """
    # Validate parameters
    available_weight_variants = DEPTH_TO_WEIGHT_VARIANTS[depth]
    if weights == "imagenet":
        max_input_shape = max(available_weight_variants)
        # `imagenet` argument without explicit weights input size.
        # Picking weights trained with biggest available shape
        weights = f"{weights}-i{max_input_shape}"

    weights_allow_list = [f"imagenet-i{x}" for x in available_weight_variants]
    if not (weights in {*weights_allow_list, None}
            or tf.io.gfile.exists(weights)):
        raise ValueError(
            "The `weights` argument should be either "
            "`None` (random initialization), `'imagenet'` "
            "(pre-training on ImageNet, with highest available input shape),"
            " or the path to the weights file to be loaded. "
            f"For ResNetRS{depth} the following weight variants are "
            f"available {weights_allow_list} (default=highest)."
            f" Received weights={weights}")

    if weights in weights_allow_list and include_top and classes != 1000:
        raise ValueError(
            f"If using `weights` as `'imagenet'` or any "
            f"of {weights_allow_list} "
            f"with `include_top` as true, `classes` should be 1000. "
            f"Received classes={classes}")

    input_shape = imagenet_utils.obtain_input_shape(
        input_shape,
        default_size=224,
        min_size=32,
        data_format=backend.image_data_format(),
        require_flatten=include_top,
        weights=weights,
    )
    # Define input tensor
    if input_tensor is None:
        img_input = layers.Input(shape=input_shape)
    else:
        if not backend.is_keras_tensor(input_tensor):
            img_input = layers.Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    bn_axis = 3 if backend.image_data_format() == "channels_last" else 1

    x = img_input

    if include_preprocessing:
        num_channels = input_shape[bn_axis - 1]
        x = layers.Rescaling(scale=1.0 / 255)(x)
        if num_channels == 3:
            x = layers.Normalization(
                mean=[0.485, 0.456, 0.406],
                variance=[0.229**2, 0.224**2, 0.225**2],
                axis=bn_axis,
            )(x)

    # Build stem
    x = STEM(bn_momentum=bn_momentum,
             bn_epsilon=bn_epsilon,
             activation=activation)(x)

    # Build blocks
    if block_args is None:
        block_args = BLOCK_ARGS[depth]

    for i, args in enumerate(block_args):
        survival_probability = get_survival_probability(
            init_rate=drop_connect_rate,
            block_num=i + 2,
            total_blocks=len(block_args) + 1,
        )

        x = BlockGroup(
            filters=args["input_filters"],
            activation=activation,
            strides=(1 if i == 0 else 2),
            num_repeats=args["num_repeats"],
            se_ratio=se_ratio,
            bn_momentum=bn_momentum,
            bn_epsilon=bn_epsilon,
            survival_probability=survival_probability,
            name=f"BlockGroup{i + 2}_",
        )(x)

    # Build head:
    if include_top:
        x = layers.GlobalAveragePooling2D(name="avg_pool")(x)
        if dropout_rate > 0:
            x = layers.Dropout(dropout_rate, name="top_dropout")(x)

        imagenet_utils.validate_activation(classifier_activation, weights)
        x = layers.Dense(classes,
                         activation=classifier_activation,
                         name="predictions")(x)
    else:
        if pooling == "avg":
            x = layers.GlobalAveragePooling2D(name="avg_pool")(x)
        elif pooling == "max":
            x = layers.GlobalMaxPooling2D(name="max_pool")(x)

    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = layer_utils.get_source_inputs(input_tensor)
    else:
        inputs = img_input

    # Create model.
    model = training.Model(inputs, x, name=model_name)

    # Download weights
    if weights in weights_allow_list:
        weights_input_shape = weights.split("-")[-1]  # e. g. "i160"
        weights_name = f"{model_name}-{weights_input_shape}"
        if not include_top:
            weights_name += "_notop"

        filename = f"{weights_name}.h5"
        download_url = BASE_WEIGHTS_URL + filename
        weights_path = data_utils.get_file(
            fname=filename,
            origin=download_url,
            cache_subdir="models",
            file_hash=WEIGHT_HASHES[filename],
        )
        model.load_weights(weights_path)

    elif weights is not None:
        model.load_weights(weights)

    return model
Ejemplo n.º 29
0
def MobileNet(
    input_shape=None,
    alpha=1.0,
    depth_multiplier=1,
    dropout=1e-3,
    include_top=True,
    weights="imagenet",
    input_tensor=None,
    pooling=None,
    classes=1000,
    classifier_activation="softmax",
    **kwargs,
):
    """Instantiates the MobileNet architecture.

    Reference:
    - [MobileNets: Efficient Convolutional Neural Networks
       for Mobile Vision Applications](
        https://arxiv.org/abs/1704.04861)

    This function returns a Keras image classification model,
    optionally loaded with weights pre-trained on ImageNet.

    For image classification use cases, see
    [this page for detailed examples](
      https://keras.io/api/applications/#usage-examples-for-image-classification-models).

    For transfer learning use cases, make sure to read the
    [guide to transfer learning & fine-tuning](
      https://keras.io/guides/transfer_learning/).

    Note: each Keras Application expects a specific kind of input preprocessing.
    For MobileNet, call `tf.keras.applications.mobilenet.preprocess_input`
    on your inputs before passing them to the model.
    `mobilenet.preprocess_input` will scale input pixels between -1 and 1.

    Args:
      input_shape: Optional shape tuple, only to be specified if `include_top`
        is False (otherwise the input shape has to be `(224, 224, 3)` (with
        `channels_last` data format) or (3, 224, 224) (with `channels_first`
        data format). It should have exactly 3 inputs channels, and width and
        height should be no smaller than 32. E.g. `(200, 200, 3)` would be one
        valid value. Default to `None`.
        `input_shape` will be ignored if the `input_tensor` is provided.
      alpha: Controls the width of the network. This is known as the width
        multiplier in the MobileNet paper. - If `alpha` < 1.0, proportionally
        decreases the number of filters in each layer. - If `alpha` > 1.0,
        proportionally increases the number of filters in each layer. - If
        `alpha` = 1, default number of filters from the paper are used at each
        layer. Default to 1.0.
      depth_multiplier: Depth multiplier for depthwise convolution. This is
        called the resolution multiplier in the MobileNet paper. Default to 1.0.
      dropout: Dropout rate. Default to 0.001.
      include_top: Boolean, whether to include the fully-connected layer at the
        top of the network. Default to `True`.
      weights: One of `None` (random initialization), 'imagenet' (pre-training
        on ImageNet), or the path to the weights file to be loaded. Default to
        `imagenet`.
      input_tensor: Optional Keras tensor (i.e. output of `layers.Input()`) to
        use as image input for the model. `input_tensor` is useful for sharing
        inputs between multiple different networks. Default to None.
      pooling: Optional pooling mode for feature extraction when `include_top`
        is `False`.
        - `None` (default) means that the output of the model will be
            the 4D tensor output of the last convolutional block.
        - `avg` means that global average pooling
            will be applied to the output of the
            last convolutional block, and thus
            the output of the model will be a 2D tensor.
        - `max` means that global max pooling will be applied.
      classes: Optional number of classes to classify images into, only to be
        specified if `include_top` is True, and if no `weights` argument is
        specified. Defaults to 1000.
      classifier_activation: A `str` or callable. The activation function to use
        on the "top" layer. Ignored unless `include_top=True`. Set
        `classifier_activation=None` to return the logits of the "top" layer.
        When loading pretrained weights, `classifier_activation` can only
        be `None` or `"softmax"`.
      **kwargs: For backwards compatibility only.
    Returns:
      A `keras.Model` instance.
    """
    global layers
    if "layers" in kwargs:
        layers = kwargs.pop("layers")
    else:
        layers = VersionAwareLayers()
    if kwargs:
        raise ValueError(f"Unknown argument(s): {(kwargs,)}")
    if not (weights in {"imagenet", None} or tf.io.gfile.exists(weights)):
        raise ValueError(
            "The `weights` argument should be either "
            "`None` (random initialization), `imagenet` "
            "(pre-training on ImageNet), "
            "or the path to the weights file to be loaded.  "
            f"Received weights={weights}"
        )

    if weights == "imagenet" and include_top and classes != 1000:
        raise ValueError(
            'If using `weights` as `"imagenet"` with `include_top` '
            "as true, `classes` should be 1000.  "
            f"Received classes={classes}"
        )

    # Determine proper input shape and default size.
    if input_shape is None:
        default_size = 224
    else:
        if backend.image_data_format() == "channels_first":
            rows = input_shape[1]
            cols = input_shape[2]
        else:
            rows = input_shape[0]
            cols = input_shape[1]

        if rows == cols and rows in [128, 160, 192, 224]:
            default_size = rows
        else:
            default_size = 224

    input_shape = imagenet_utils.obtain_input_shape(
        input_shape,
        default_size=default_size,
        min_size=32,
        data_format=backend.image_data_format(),
        require_flatten=include_top,
        weights=weights,
    )

    if backend.image_data_format() == "channels_last":
        row_axis, col_axis = (0, 1)
    else:
        row_axis, col_axis = (1, 2)
    rows = input_shape[row_axis]
    cols = input_shape[col_axis]

    if weights == "imagenet":
        if depth_multiplier != 1:
            raise ValueError(
                "If imagenet weights are being loaded, "
                "depth multiplier must be 1.  "
                f"Received depth_multiplier={depth_multiplier}"
            )

        if alpha not in [0.25, 0.50, 0.75, 1.0]:
            raise ValueError(
                "If imagenet weights are being loaded, "
                "alpha can be one of"
                "`0.25`, `0.50`, `0.75` or `1.0` only.  "
                f"Received alpha={alpha}"
            )

        if rows != cols or rows not in [128, 160, 192, 224]:
            rows = 224
            logging.warning(
                "`input_shape` is undefined or non-square, "
                "or `rows` is not in [128, 160, 192, 224]. "
                "Weights for input shape (224, 224) will be "
                "loaded as the default."
            )

    if input_tensor is None:
        img_input = layers.Input(shape=input_shape)
    else:
        if not backend.is_keras_tensor(input_tensor):
            img_input = layers.Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    x = _conv_block(img_input, 32, alpha, strides=(2, 2))
    x = _depthwise_conv_block(x, 64, alpha, depth_multiplier, block_id=1)

    x = _depthwise_conv_block(
        x, 128, alpha, depth_multiplier, strides=(2, 2), block_id=2
    )
    x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, block_id=3)

    x = _depthwise_conv_block(
        x, 256, alpha, depth_multiplier, strides=(2, 2), block_id=4
    )
    x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, block_id=5)

    x = _depthwise_conv_block(
        x, 512, alpha, depth_multiplier, strides=(2, 2), block_id=6
    )
    x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=7)
    x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=8)
    x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=9)
    x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=10)
    x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=11)

    x = _depthwise_conv_block(
        x, 1024, alpha, depth_multiplier, strides=(2, 2), block_id=12
    )
    x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, block_id=13)

    if include_top:
        x = layers.GlobalAveragePooling2D(keepdims=True)(x)
        x = layers.Dropout(dropout, name="dropout")(x)
        x = layers.Conv2D(classes, (1, 1), padding="same", name="conv_preds")(x)
        x = layers.Reshape((classes,), name="reshape_2")(x)
        imagenet_utils.validate_activation(classifier_activation, weights)
        x = layers.Activation(
            activation=classifier_activation, name="predictions"
        )(x)
    else:
        if pooling == "avg":
            x = layers.GlobalAveragePooling2D()(x)
        elif pooling == "max":
            x = layers.GlobalMaxPooling2D()(x)

    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = layer_utils.get_source_inputs(input_tensor)
    else:
        inputs = img_input

    # Create model.
    model = training.Model(inputs, x, name="mobilenet_%0.2f_%s" % (alpha, rows))

    # Load weights.
    if weights == "imagenet":
        if alpha == 1.0:
            alpha_text = "1_0"
        elif alpha == 0.75:
            alpha_text = "7_5"
        elif alpha == 0.50:
            alpha_text = "5_0"
        else:
            alpha_text = "2_5"

        if include_top:
            model_name = "mobilenet_%s_%d_tf.h5" % (alpha_text, rows)
            weight_path = BASE_WEIGHT_PATH + model_name
            weights_path = data_utils.get_file(
                model_name, weight_path, cache_subdir="models"
            )
        else:
            model_name = "mobilenet_%s_%d_tf_no_top.h5" % (alpha_text, rows)
            weight_path = BASE_WEIGHT_PATH + model_name
            weights_path = data_utils.get_file(
                model_name, weight_path, cache_subdir="models"
            )
        model.load_weights(weights_path)
    elif weights is not None:
        model.load_weights(weights)

    return model
Ejemplo n.º 30
0
def EfficientNetV2(
    width_coefficient,
    depth_coefficient,
    default_size,
    dropout_rate=0.2,
    drop_connect_rate=0.2,
    depth_divisor=8,
    min_depth=8,
    bn_momentum=0.9,
    activation="swish",
    blocks_args="default",
    model_name="efficientnetv2",
    include_top=True,
    weights="imagenet",
    input_tensor=None,
    input_shape=None,
    pooling=None,
    classes=1000,
    classifier_activation="softmax",
    include_preprocessing=True,
):
    """Instantiates the EfficientNetV2 architecture using given scaling coefficients.

  Args:
    width_coefficient: float, scaling coefficient for network width.
    depth_coefficient: float, scaling coefficient for network depth.
    default_size: integer, default input image size.
    dropout_rate: float, dropout rate before final classifier layer.
    drop_connect_rate: float, dropout rate at skip connections.
    depth_divisor: integer, a unit of network width.
    min_depth: integer, minimum number of filters.
    bn_momentum: float. Momentum parameter for Batch Normalization layers.
    activation: activation function.
    blocks_args: list of dicts, parameters to construct block modules.
    model_name: string, model name.
    include_top: whether to include the fully-connected layer at the top of the
      network.
    weights: one of `None` (random initialization), `"imagenet"` (pre-training
      on ImageNet), or the path to the weights file to be loaded.
    input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) or
      numpy array to use as image input for the model.
    input_shape: optional shape tuple, only to be specified if `include_top` is
      False. It should have exactly 3 inputs channels.
    pooling: optional pooling mode for feature extraction when `include_top` is
      `False`. - `None` means that the output of the model will be the 4D tensor
      output of the last convolutional layer. - "avg" means that global average
      pooling will be applied to the output of the last convolutional layer, and
      thus the output of the model will be a 2D tensor. - `"max"` means that
      global max pooling will be applied.
    classes: optional number of classes to classify images into, only to be
      specified if `include_top` is True, and if no `weights` argument is
      specified.
    classifier_activation: A string or callable. The activation function to use
      on the `"top"` layer. Ignored unless `include_top=True`. Set
      `classifier_activation=None` to return the logits of the `"top"` layer.
    include_preprocessing: Boolean, whether to include the preprocessing layer
      (`Rescaling`) at the bottom of the network. Defaults to `True`.

  Returns:
    A `keras.Model` instance.

  Raises:
    ValueError: in case of invalid argument for `weights`,
      or invalid input shape.
    ValueError: if `classifier_activation` is not `"softmax"` or `None` when
      using a pretrained top layer.
  """

    if blocks_args == "default":
        blocks_args = DEFAULT_BLOCKS_ARGS[model_name]

    if not (weights in {"imagenet", None} or tf.io.gfile.exists(weights)):
        raise ValueError("The `weights` argument should be either "
                         "`None` (random initialization), `imagenet` "
                         "(pre-training on ImageNet), "
                         "or the path to the weights file to be loaded."
                         f"Received: weights={weights}")

    if weights == "imagenet" and include_top and classes != 1000:
        raise ValueError(
            "If using `weights` as `'imagenet'` with `include_top`"
            " as true, `classes` should be 1000"
            f"Received: classes={classes}")

    # Determine proper input shape
    input_shape = imagenet_utils.obtain_input_shape(
        input_shape,
        default_size=default_size,
        min_size=32,
        data_format=backend.image_data_format(),
        require_flatten=include_top,
        weights=weights)

    if input_tensor is None:
        img_input = layers.Input(shape=input_shape)
    else:
        if not backend.is_keras_tensor(input_tensor):
            img_input = layers.Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor

    bn_axis = 3 if backend.image_data_format() == "channels_last" else 1

    x = img_input

    if include_preprocessing:
        # Apply original V1 preprocessing for Bx variants
        # if number of channels allows it
        num_channels = input_shape[bn_axis - 1]
        if model_name.split("-")[-1].startswith("b") and num_channels == 3:
            x = layers.Rescaling(scale=1. / 255)(x)
            x = layers.Normalization(
                mean=[0.485, 0.456, 0.406],
                variance=[0.229**2, 0.224**2, 0.225**2],
                axis=bn_axis,
            )(x)
        else:
            x = layers.Rescaling(scale=1. / 128.0, offset=-1)(x)

    # Build stem
    stem_filters = round_filters(
        filters=blocks_args[0]["input_filters"],
        width_coefficient=width_coefficient,
        min_depth=min_depth,
        depth_divisor=depth_divisor,
    )
    x = layers.Conv2D(
        filters=stem_filters,
        kernel_size=3,
        strides=2,
        kernel_initializer=CONV_KERNEL_INITIALIZER,
        padding="same",
        use_bias=False,
        name="stem_conv",
    )(x)
    x = layers.BatchNormalization(
        axis=bn_axis,
        momentum=bn_momentum,
        name="stem_bn",
    )(x)
    x = layers.Activation(activation, name="stem_activation")(x)

    # Build blocks
    blocks_args = copy.deepcopy(blocks_args)
    b = 0
    blocks = float(sum(args["num_repeat"] for args in blocks_args))

    for (i, args) in enumerate(blocks_args):
        assert args["num_repeat"] > 0

        # Update block input and output filters based on depth multiplier.
        args["input_filters"] = round_filters(
            filters=args["input_filters"],
            width_coefficient=width_coefficient,
            min_depth=min_depth,
            depth_divisor=depth_divisor)
        args["output_filters"] = round_filters(
            filters=args["output_filters"],
            width_coefficient=width_coefficient,
            min_depth=min_depth,
            depth_divisor=depth_divisor)

        # Determine which conv type to use:
        block = {0: MBConvBlock, 1: FusedMBConvBlock}[args.pop("conv_type")]
        repeats = round_repeats(repeats=args.pop("num_repeat"),
                                depth_coefficient=depth_coefficient)
        for j in range(repeats):
            # The first block needs to take care of stride and filter size increase.
            if j > 0:
                args["strides"] = 1
                args["input_filters"] = args["output_filters"]

            x = block(
                activation=activation,
                bn_momentum=bn_momentum,
                survival_probability=drop_connect_rate * b / blocks,
                name="block{}{}_".format(i + 1, chr(j + 97)),
                **args,
            )(x)
            b += 1

    # Build top
    top_filters = round_filters(filters=1280,
                                width_coefficient=width_coefficient,
                                min_depth=min_depth,
                                depth_divisor=depth_divisor)
    x = layers.Conv2D(
        filters=top_filters,
        kernel_size=1,
        strides=1,
        kernel_initializer=CONV_KERNEL_INITIALIZER,
        padding="same",
        data_format="channels_last",
        use_bias=False,
        name="top_conv",
    )(x)
    x = layers.BatchNormalization(
        axis=bn_axis,
        momentum=bn_momentum,
        name="top_bn",
    )(x)
    x = layers.Activation(activation=activation, name="top_activation")(x)

    if include_top:
        x = layers.GlobalAveragePooling2D(name="avg_pool")(x)
        if dropout_rate > 0:
            x = layers.Dropout(dropout_rate, name="top_dropout")(x)
        imagenet_utils.validate_activation(classifier_activation, weights)
        x = layers.Dense(classes,
                         activation=classifier_activation,
                         kernel_initializer=DENSE_KERNEL_INITIALIZER,
                         bias_initializer=tf.constant_initializer(0),
                         name="predictions")(x)
    else:
        if pooling == "avg":
            x = layers.GlobalAveragePooling2D(name="avg_pool")(x)
        elif pooling == "max":
            x = layers.GlobalMaxPooling2D(name="max_pool")(x)

    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = layer_utils.get_source_inputs(input_tensor)
    else:
        inputs = img_input

    # Create model.
    model = training.Model(inputs, x, name=model_name)

    # Load weights.
    if weights == "imagenet":
        if include_top:
            file_suffix = ".h5"
            file_hash = WEIGHTS_HASHES[model_name[-2:]][0]
        else:
            file_suffix = "_notop.h5"
            file_hash = WEIGHTS_HASHES[model_name[-2:]][1]
        file_name = model_name + file_suffix
        weights_path = data_utils.get_file(file_name,
                                           BASE_WEIGHTS_PATH + file_name,
                                           cache_subdir="models",
                                           file_hash=file_hash)
        model.load_weights(weights_path)
    elif weights is not None:
        model.load_weights(weights)

    return model