fix for keras applications preprocessing with channels_first symbolic tensors
The scaling by std deviation was not taking into account the channel order and caused an error when a symbolic tensor was provided with mode='torch' (e.g. for tf.keras.applications.densenet.preprocess_input). This commit corrects that, and runs the tests for all modes instead of just the default.
This commit is contained in:
parent
796af3d216
commit
0376b33c9e
@ -289,7 +289,10 @@ def _preprocess_symbolic_input(x, data_format, mode):
|
|||||||
else:
|
else:
|
||||||
x = backend.bias_add(x, mean_tensor, data_format)
|
x = backend.bias_add(x, mean_tensor, data_format)
|
||||||
if std is not None:
|
if std is not None:
|
||||||
x /= std
|
std_tensor = backend.constant(np.array(std))
|
||||||
|
if data_format == "channels_first":
|
||||||
|
std_tensor = backend.reshape(std_tensor, (-1, 1, 1))
|
||||||
|
x /= std_tensor
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,19 +79,28 @@ class TestImageNetUtils(keras_parameterized.TestCase):
|
|||||||
xint2 = utils.preprocess_input(xint)
|
xint2 = utils.preprocess_input(xint)
|
||||||
self.assertAllClose(x, x2[..., ::-1])
|
self.assertAllClose(x, x2[..., ::-1])
|
||||||
self.assertNotEqual(xint.astype('float').max(), xint2.max())
|
self.assertNotEqual(xint.astype('float').max(), xint2.max())
|
||||||
|
|
||||||
def test_preprocess_input_symbolic(self):
|
@parameterized.named_parameters([
|
||||||
|
{'testcase_name': 'mode_torch',
|
||||||
|
'mode': 'torch'},
|
||||||
|
{'testcase_name': 'mode_tf',
|
||||||
|
'mode': 'tf'},
|
||||||
|
{'testcase_name': 'mode_caffe',
|
||||||
|
'mode': 'caffe'},
|
||||||
|
])
|
||||||
|
def test_preprocess_input_symbolic(self, mode):
|
||||||
# Test image batch
|
# Test image batch
|
||||||
x = np.random.uniform(0, 255, (2, 10, 10, 3))
|
x = np.random.uniform(0, 255, (2, 10, 10, 3))
|
||||||
inputs = keras.layers.Input(shape=x.shape[1:])
|
inputs = keras.layers.Input(shape=x.shape[1:])
|
||||||
outputs = keras.layers.Lambda(
|
outputs = keras.layers.Lambda(
|
||||||
utils.preprocess_input, output_shape=x.shape[1:])(
|
lambda x: utils.preprocess_input(x, mode=mode),
|
||||||
|
output_shape=x.shape[1:])(
|
||||||
inputs)
|
inputs)
|
||||||
model = keras.Model(inputs, outputs)
|
model = keras.Model(inputs, outputs)
|
||||||
self.assertEqual(model.predict(x).shape, x.shape)
|
self.assertEqual(model.predict(x).shape, x.shape)
|
||||||
|
|
||||||
outputs1 = keras.layers.Lambda(
|
outputs1 = keras.layers.Lambda(
|
||||||
lambda x: utils.preprocess_input(x, 'channels_last'),
|
lambda x: utils.preprocess_input(x, 'channels_last', mode=mode),
|
||||||
output_shape=x.shape[1:])(
|
output_shape=x.shape[1:])(
|
||||||
inputs)
|
inputs)
|
||||||
model1 = keras.Model(inputs, outputs1)
|
model1 = keras.Model(inputs, outputs1)
|
||||||
@ -99,7 +108,7 @@ class TestImageNetUtils(keras_parameterized.TestCase):
|
|||||||
x2 = np.transpose(x, (0, 3, 1, 2))
|
x2 = np.transpose(x, (0, 3, 1, 2))
|
||||||
inputs2 = keras.layers.Input(shape=x2.shape[1:])
|
inputs2 = keras.layers.Input(shape=x2.shape[1:])
|
||||||
outputs2 = keras.layers.Lambda(
|
outputs2 = keras.layers.Lambda(
|
||||||
lambda x: utils.preprocess_input(x, 'channels_first'),
|
lambda x: utils.preprocess_input(x, 'channels_first', mode=mode),
|
||||||
output_shape=x2.shape[1:])(
|
output_shape=x2.shape[1:])(
|
||||||
inputs2)
|
inputs2)
|
||||||
model2 = keras.Model(inputs2, outputs2)
|
model2 = keras.Model(inputs2, outputs2)
|
||||||
@ -110,13 +119,14 @@ class TestImageNetUtils(keras_parameterized.TestCase):
|
|||||||
x = np.random.uniform(0, 255, (10, 10, 3))
|
x = np.random.uniform(0, 255, (10, 10, 3))
|
||||||
inputs = keras.layers.Input(shape=x.shape)
|
inputs = keras.layers.Input(shape=x.shape)
|
||||||
outputs = keras.layers.Lambda(
|
outputs = keras.layers.Lambda(
|
||||||
utils.preprocess_input, output_shape=x.shape)(
|
lambda x: utils.preprocess_input(x, mode=mode),
|
||||||
|
output_shape=x.shape)(
|
||||||
inputs)
|
inputs)
|
||||||
model = keras.Model(inputs, outputs)
|
model = keras.Model(inputs, outputs)
|
||||||
self.assertEqual(model.predict(x[np.newaxis])[0].shape, x.shape)
|
self.assertEqual(model.predict(x[np.newaxis])[0].shape, x.shape)
|
||||||
|
|
||||||
outputs1 = keras.layers.Lambda(
|
outputs1 = keras.layers.Lambda(
|
||||||
lambda x: utils.preprocess_input(x, 'channels_last'),
|
lambda x: utils.preprocess_input(x, 'channels_last', mode=mode),
|
||||||
output_shape=x.shape)(
|
output_shape=x.shape)(
|
||||||
inputs)
|
inputs)
|
||||||
model1 = keras.Model(inputs, outputs1)
|
model1 = keras.Model(inputs, outputs1)
|
||||||
@ -124,7 +134,7 @@ class TestImageNetUtils(keras_parameterized.TestCase):
|
|||||||
x2 = np.transpose(x, (2, 0, 1))
|
x2 = np.transpose(x, (2, 0, 1))
|
||||||
inputs2 = keras.layers.Input(shape=x2.shape)
|
inputs2 = keras.layers.Input(shape=x2.shape)
|
||||||
outputs2 = keras.layers.Lambda(
|
outputs2 = keras.layers.Lambda(
|
||||||
lambda x: utils.preprocess_input(x, 'channels_first'),
|
lambda x: utils.preprocess_input(x, 'channels_first', mode=mode),
|
||||||
output_shape=x2.shape)(
|
output_shape=x2.shape)(
|
||||||
inputs2)
|
inputs2)
|
||||||
model2 = keras.Model(inputs2, outputs2)
|
model2 = keras.Model(inputs2, outputs2)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user