diff --git a/keras_rcnn/backend/tensorflow_backend.py b/keras_rcnn/backend/tensorflow_backend.py index 9fb41269..68d38336 100644 --- a/keras_rcnn/backend/tensorflow_backend.py +++ b/keras_rcnn/backend/tensorflow_backend.py @@ -56,7 +56,7 @@ def non_maximum_suppression(boxes, scores, maximum, threshold=0.5): ) -def propose(boxes, scores): +def propose(boxes, scores, maximum): shape = keras.backend.int_shape(boxes)[1:3] shifted = keras_rcnn.backend.shift(shape, 16) @@ -79,7 +79,7 @@ def propose(boxes, scores): proposals = keras.backend.cast(proposals, tensorflow.float32) scores = keras.backend.cast(scores, tensorflow.float32) - indicies = keras_rcnn.backend.non_maximum_suppression(proposals, scores, 100, 0.7) + indicies = keras_rcnn.backend.non_maximum_suppression(proposals, scores, maximum, 0.7) proposals = keras.backend.gather(proposals, indicies) diff --git a/keras_rcnn/layers/object_detection/_object_proposal.py b/keras_rcnn/layers/object_detection/_object_proposal.py index 16f61bd2..fe4946ec 100644 --- a/keras_rcnn/layers/object_detection/_object_proposal.py +++ b/keras_rcnn/layers/object_detection/_object_proposal.py @@ -19,7 +19,7 @@ def build(self, input_shape): super(ObjectProposal, self).build(input_shape) def call(self, inputs, **kwargs): - return keras_rcnn.backend.propose(inputs[0], inputs[1]) + return keras_rcnn.backend.propose(inputs[0], inputs[1], self.proposals) def compute_output_shape(self, input_shape): return self.output_dim diff --git a/tests/conftest.py b/tests/conftest.py index d180a2a4..8e6ef0be 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,49 @@ def anchor_layer(): return keras_rcnn.layers.object_detection.Anchor(features, shape) +@pytest.fixture() +def convolution_neural_network(): + options = { + "activation": "relu", + "kernel_size": (3, 3), + "padding": "same" + } + + shape = (224, 224, 3) + + x = keras.layers.Input(shape) + + y = keras.layers.Conv2D(64, **options)(x) + y = keras.layers.Conv2D(64, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(128, **options)(y) + y = keras.layers.Conv2D(128, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + + return keras.models.Model(x, y) + + @pytest.fixture() def feat_h(): return 14 @@ -72,6 +115,59 @@ def regional_proposal_network_layer(): return keras_rcnn.layers.object_detection.RegionProposalNetwork() +@pytest.fixture() +def region_proposal_network(): + options = { + "activation": "relu", + "kernel_size": (3, 3), + "padding": "same" + } + + shape = (224, 224, 3) + + x = keras.layers.Input(shape) + + y = keras.layers.Conv2D(64, **options)(x) + y = keras.layers.Conv2D(64, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(128, **options)(y) + y = keras.layers.Conv2D(128, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + + y = keras.layers.Conv2D(512, **options)(y) + + a = keras.layers.Conv2D(9 * 1, (1, 1), activation="sigmoid")(y) + + b = keras.layers.Conv2D(9 * 4, (1, 1))(y) + + y = keras_rcnn.layers.object_detection.ObjectProposal(300)([a, b]) + + model = keras.models.Model(x, y) + + model.compile("sgd", "mse") + + @pytest.fixture() def x(): return numpy.arange(2 * 9 * 14 * 14, dtype=numpy.float32).reshape(1, 18, 14, 14) diff --git a/tests/layers/object_detection/test_object_proposal.py b/tests/layers/object_detection/test_object_proposal.py index 0fdbbab6..45778e44 100644 --- a/tests/layers/object_detection/test_object_proposal.py +++ b/tests/layers/object_detection/test_object_proposal.py @@ -1,19 +1,70 @@ +import keras.layers +import keras.models import numpy +import keras_rcnn.layers.object_detection + class TestObjectProposal: def test_build(self): assert True - def test_call(self, object_proposal_model): - object_proposal_model.compile("sgd", "mse") + def test_call(self): + options = { + "activation": "relu", + "kernel_size": (3, 3), + "padding": "same" + } + + shape = (224, 224, 3) + + x = keras.layers.Input(shape) + + y = keras.layers.Conv2D(64, **options)(x) + y = keras.layers.Conv2D(64, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(128, **options)(y) + y = keras.layers.Conv2D(128, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + y = keras.layers.Conv2D(256, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + + y = keras.layers.MaxPooling2D(strides=(2, 2))(y) + + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + y = keras.layers.Conv2D(512, **options)(y) + + y = keras.layers.Conv2D(512, **options)(y) + + a = keras.layers.Conv2D(9 * 4, (1, 1))(y) + + b = keras.layers.Conv2D(9 * 2, (1, 1), activation="sigmoid")(y) + + y = keras_rcnn.layers.object_detection.ObjectProposal(300)([a, b]) + + model = keras.models.Model(x, y) + + model.compile("sgd", "mse") - a = numpy.random.rand(1, 14, 14, 4 * 9) - b = numpy.random.rand(1, 14, 14, 2 * 9) + image = numpy.random.rand(1, 224, 224, 3) - prediction = object_proposal_model.predict([a, b]) + prediction = model.predict(image) - assert prediction.shape == (1, 100, 4) + assert prediction.shape == (1, 300, 4) def test_compute_output_shape(self, object_proposal_layer): assert object_proposal_layer.compute_output_shape((14, 14)) == (None, 300, 4)