diff --git a/keras/layers/merge.py b/keras/layers/merge.py index 7d349625e11..f0b5a2a7374 100644 --- a/keras/layers/merge.py +++ b/keras/layers/merge.py @@ -290,6 +290,21 @@ def _merge_function(self, inputs): return output +class Minimum(_Merge): + """Layer that computes the minimum (element-wise) a list of inputs. + + It takes as input a list of tensors, + all of the same shape, and returns + a single tensor (also of the same shape). + """ + + def _merge_function(self, inputs): + output = inputs[0] + for i in range(1, len(inputs)): + output = K.minimum(output, inputs[i]) + return output + + class Concatenate(_Merge): """Layer that concatenates a list of inputs. @@ -586,6 +601,19 @@ def maximum(inputs, **kwargs): return Maximum(**kwargs)(inputs) +def minimum(inputs, **kwargs): + """Functional interface to the `Minimum` layer. + + # Arguments + inputs: A list of input tensors (at least 2). + **kwargs: Standard layer keyword arguments. + + # Returns + A tensor, the element-wise minimum of the inputs. + """ + return Minimum(**kwargs)(inputs) + + def concatenate(inputs, axis=-1, **kwargs): """Functional interface to the `Concatenate` layer. diff --git a/tests/keras/layers/merge_test.py b/tests/keras/layers/merge_test.py index 60f7827e707..44c97e3bbfd 100644 --- a/tests/keras/layers/merge_test.py +++ b/tests/keras/layers/merge_test.py @@ -138,6 +138,25 @@ def test_merge_maximum(): assert_allclose(out, np.maximum(x1, x2), atol=1e-4) +@keras_test +def test_merge_minimum(): + i1 = layers.Input(shape=(4, 5)) + i2 = layers.Input(shape=(4, 5)) + o = layers.minimum([i1, i2]) + assert o._keras_shape == (None, 4, 5) + model = models.Model([i1, i2], o) + + max_layer = layers.Minimum() + o2 = max_layer([i1, i2]) + assert max_layer.output_shape == (None, 4, 5) + + x1 = np.random.random((2, 4, 5)) + x2 = np.random.random((2, 4, 5)) + out = model.predict([x1, x2]) + assert out.shape == (2, 4, 5) + assert_allclose(out, np.minimum(x1, x2), atol=1e-4) + + @keras_test def test_merge_concatenate(): i1 = layers.Input(shape=(None, 5))