Open BastinFlorian opened 11 months ago
Any idea ? @TobyRoseman
Thanks @BastinFlorian for providing the reproduce script. I confirmed that I can reproduce this error on my side.
It's an issue in CoreML, and I have filed an internal ticket to track it. Will keep you updated when it's fixed. Thanks!
Hey @BastinFlorian, if you want to try some quick workarounds on your side: This bug is introduced by indexing assignment, so you might be able to work it around if you could try to replace it with scatter op. Thanks!
Hey @junpeiz , if I understand well, the following lines are the reason for the bug:
# KO
# Compute vertical line
x = (landmarks[:, 9, 0] + landmarks[:, 13, 0]) / 2
y = (landmarks[:, 9, 1] + landmarks[:, 13, 1]) / 2
It WORKS if I remove them and replace x, y (faking it) with:
# OK
# Compute vertical line
x = tf.constant(np.random.rand(1, 1, 1), dtype=tf.float32)
y = tf.constant(np.random.rand(1, 1, 1), dtype=tf.float32)
But it FAILS if i try to use tf.gather to select specific indexes like this:
# KO
# Compute vertical line
xy = (tf.gather(landmarks, 9, axis=1) + tf.gather(landmarks, 13, axis=1)) / 2
x = tf.gather(xy, 0, axis=1)
y = tf.gather(xy, 1, axis=1)
or
# KO
# Compute vertical line
line_vec_indexes = [9, 13]
x = tf.math.reduce_mean(tf.gather(landmarks, line_vec_indexes, axis=1)[:, :, 0], axis=(1,))
y = tf.math.reduce_mean(tf.gather(landmarks, line_vec_indexes, axis=1)[:, :, 1], axis=(1,))
Am I misunderstanding your advice ? Can you please give me more details about the quick workaround I can do ? Thank you.
Thank you for trying it! You understood my advice correctly. Looks like the workaround doesn't work in your case. So we need to wait for CoreML to fix it. Thanks!
🐞Describing the bug
Stack Trace
To Reproduce
@tf.function def tf_rotate_vertically(landmarks):
Compute vertical line
@tf.function def tf_atan2(y, x): angle = tf.where(tf.less(x, 0.0), tf.atan(y / x) + np.pi, tf.atan(y / (x + 1e-12))) angle = tf.where(tf.less(y, 0.0), angle - (2.0 * np.pi), angle) angle = tf.where(tf.logical_and(tf.equal(x, 0.0), tf.equal(y, 0.0)), tf.zeros_like(x), angle) return angle
Keras model
Model inputs
input_scalar = tf.keras.layers.Input(shape=(1), dtype=tf.float32, name='handedness') input_matrix = tf.keras.layers.Input(shape=(21, 2), dtype=tf.float32, name='landmarks')
Keep first idx of each sample
first_element = tf.gather(input_matrix, 0, axis=1, name='first_element')
Substract by first element
x = tf.keras.layers.subtract([input_matrix, first_element], name='substract', input_shape=(21, 2))
Rotation
x = tf.keras.layers.Lambda(tf_rotate_vertically, name='rotate_vertically', input_shape=(21, 2))(x)
preprocessing_model = tf.keras.Model(inputs=input_matrix, outputs=x)
preprocessing_model.predict(tf.reshape(np.random.rand(10, 21, 2), [10, 21, 2])) # OK
Save model
Convert the model to Core ML
input_matrix_shape = ct.Shape(shape=(1, 21, 2))
coreml_model = ct.convert( preprocessing_model, inputs=[ ct.TensorType(name='landmarks', shape=input_matrix_shape), ], source='tensorflow', convert_to="mlprogram" )
coreml_preprocess_path = '../model/IOS/preprocess_model.mlpackage'
Save the model
coreml_model.save(coreml_preprocess_path)
System environment (please complete the following information):