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))
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)
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)
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)
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)
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]))
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)))
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)
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)
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)
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]))
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)
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]))
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)
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]))
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)
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)
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)
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)))
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)))
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)
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)
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)
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
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)
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)
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
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
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
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