Je lisais ceci article de blog dans Hackernoon expliquant comment la fonction Tensorflow tf.image.resize_area () n'est pas une équivariante de réflexion. Donc, si j'allais redimensionner une image dans une étape d'augmentation des données, cela pourrait vraiment gâcher la formation du modèle.
L'auteur poursuit en disant que les utilisateurs ne devraient utiliser aucune des fonctions tf.image.resize , en raison d'un comportement potentiellement imprévisible. L'article date de janvier 2018, il n'y a donc pas si longtemps. J'ai en fait vérifié la section des commentaires de l'article, et personne n'a mentionné que les problèmes avaient été résolus.
Je me demandais simplement si ces problèmes sont toujours vrais et quelle est la solution de contournement? Tout changement dans les versions ultérieures de tensorflow . Par exemple, puis-je utiliser les fonctions d’augmentation de tf.keras à la place pour éviter ces problèmes?
3 Réponses :
Après avoir lu l'article Hackernoon auquel vous avez fait référence, je suis également tombé sur cet article qui fournit un joli résumé des différentes implémentations de l'interpolation bilinéaire à travers OpenCV, TF 1.X et quelques autres frameworks DL.
Je n'ai rien trouvé à ce sujet dans TF 2.0 docs, j'ai donc reproduit l'exemple donné dans cet article pour tester l'interpolation bilinéaire en 2.0. Lorsque j'exécute le code suivant en utilisant TensorFlow 2.0, le test réussit, il semble donc que le passage à TF2.0 vous fournira une implémentation de l'interpolation bilinéaire qui correspond à l'implémentation d'OpenCV (et résout donc les problèmes soulevés dans l'article Hackernoon):
def test_tf2_resample_upsample_matches_opencv_methodology():
"""
According to the article below, the Tensorflow 1.x implementation of bilinear interpolation for resizing images did
not reproduce the pixel-area-based approach adopted by OpenCV. The `align_corners` option was set to False by
default due to some questionable legacy reasons but users were advised to set it to True in order to get a
'reasonable' output: https://jricheimer.github.io/tensorflow/2019/02/11/resize-confusion/
This appears to have been fixed in TF 2.0 and this test confirms that we get the results one would expect from a
pixel-area-based technique.
We start with an input array whose values are equivalent to their column indices:
input_arr = np.array([
[[0], [1], [2], [3], [4], [5]],
[[0], [1], [2], [3], [4], [5]],
])
And then resize this (holding the rows dimension constant in size, but increasing the column dimnesion to 12) to
reproduce the OpenCV example from the article. We expect this to produce the following output:
expected_output = np.array([
[[0], [0.25], [0.75], [1.25], [1.75], [2.25], [2.75], [3.25], [3.75], [4.25], [4.75], [5]],
[[0], [0.25], [0.75], [1.25], [1.75], [2.25], [2.75], [3.25], [3.75], [4.25], [4.75], [5]],
])
"""
input_tensor = tf.convert_to_tensor(
np.array([
[[0], [1], [2], [3], [4], [5]],
[[0], [1], [2], [3], [4], [5]],
]),
dtype=tf.float32,
)
output_arr = tf.image.resize(
images=input_tensor,
size=(2,12),
method=tf.image.ResizeMethod.BILINEAR).numpy()
expected_output = np.array([
[[0], [0.25], [0.75], [1.25], [1.75], [2.25], [2.75], [3.25], [3.75], [4.25], [4.75], [5]],
[[0], [0.25], [0.75], [1.25], [1.75], [2.25], [2.75], [3.25], [3.75], [4.25], [4.75], [5]],
])
np.testing.assert_almost_equal(output_arr, expected_output, decimal=2)
Ahh très bien que vous ayez pu vérifier cela. Heureux que cela semble être corrigé dans Tensorflow 2.0. Je vais essayer votre code pour voir s'il fonctionne également pour moi.
Eh bien, j'ai testé tf.resize sur une image réelle et je ne peux pas obtenir la même image. Soyez donc prêt à essayer différentes bibliothèques en fonction des résultats de votre formation. Consultez les détails ici .
# we may get the same image image_tf = tf.io.read_file(str(image_path)) image_tf = tf.image.decode_jpeg(image_tf, channels=3, dct_method='INTEGER_ACCURATE') image_cv = cv2.imread(str(image_path)) image_cv = cv2.cvtColor(image_cv, cv2.COLOR_BGR2RGB) np.sum(np.abs(image_cv - image_tf)) # 0 # but not the same resized image image_tf_res = tf.image.resize(image_tf, IMAGE_SIZE, method='bilinear') image_cv_res = cv2.resize(image_cv, tuple(IMAGE_SIZE), interpolation=cv2.INTER_LINEAR) # this is NOT 0 np.sum(np.abs(image_pil_res - image_tf_res)), np.sum(np.abs(image_cv_res - image_tf_res))
p>
oh pour de vrai. Mec, je pensais que c'était résolu. Je vais essayer votre code et voir ce que j'obtiens. Merci d'avoir publié vos résultats.
Je viens de rencontrer cette question et j'ai fait quelques tests moi-même en utilisant une image similaire à celle utilisée dans le article Hackernoon . Vous pouvez trouver un petit cahier ici avec mes résultats. Depuis TF v2.3.1, il semble que le décalage des pixels ait été corrigé, mais l'interpolation est toujours assez différente (par exemple, la coloration) par rapport à PIL ou scikit-image . p>