4 votes

Utiliser la fonction de perte SSIM avec Keras

J'ai besoin d'utiliser le SSIM de Sewar comme fonction de perte afin de comparer les images pour mon modèle.

J'obtiens des erreurs lorsque j'essaie de compiler mon modèle. J'importe la fonction et compile le modèle comme ceci :

from sewar.full_ref import ssim
...
model.compile('ssim', optimizer=my_optimizer, metrics=[ssim])

et je reçois ça :

File "/media/merry/merry32/train.py", line 19, in train
model.compile(loss='ssim', optimizer=opt, metrics=[ssim])
File "/home/merry/anaconda3/envs/merry_env/lib/python3.7/site-packages/keras/engine/training.py", line 451, in compile
handle_metrics(output_metrics)
File "/home/merry/anaconda3/envs/merry_env/lib/python3.7/site-packages/keras/engine/training.py", line 420, in handle_metrics
mask=masks[i])
File "/home/merry/anaconda3/envs/merry_env/lib/python3.7/site-packages/keras/engine/training_utils.py", line 404, in weighted
score_array = fn(y_true, y_pred)
File "/home/merry/anaconda3/envs/merry_env/lib/python3.7/site-packages/sewar/full_ref.py", line 143, in ssim
MAX = np.iinfo(GT.dtype).max
File "/home/merry/anaconda3/envs/merry_env/lib/python3.7/site-packages/numpy/core/getlimits.py", line 506, in __init__
raise ValueError("Invalid integer data type %r." % (self.kind,))
ValueError: Invalid integer data type 'O'.

Je pourrais aussi écrire quelque chose comme ça :

model.compile(ssim(), optimizer=my_optimizer, metrics=[ssim()])

Mais ensuite j'obtiens cette erreur (évidemment) :

TypeError: ssim() missing 2 required positional arguments: 'GT' and 'P'

Je voulais juste faire la même chose que je faisais avec mean_sqeared_error mais avec SSIM, comme ceci (qui fonctionne parfaitement sans avoir besoin de lui passer des paramètres) :

model.compile('mean_squared_error', optimizer=my_optimizer, metrics=['mse'])

Une idée sur la façon dont je dois utiliser cette fonction pour compiler ?

9voto

Sukanya Dasgupta Points 103

Keras possède une implémentation de SSIM. Vous pouvez l'utiliser comme ceci :

def SSIMLoss(y_true, y_pred):
  return 1 - tf.reduce_mean(tf.image.ssim(y_true, y_pred, 1.0))

self.model.compile(optimizer=sgd, loss=SSIMLoss)

6voto

mujjiga Points 49
  • Vous pouvez utiliser tf.image.ssim pour calculer l'indice SSIM entre deux images.
  • Comme l'entraînement se fait sur un lot d'images, nous utiliserons la moyenne des valeurs SSIM de toutes les images du lot comme valeur de perte.
  • Notre modèle renverra une image (d'une certaine taille en fonction des couches CNN utilisées, qui est à nouveau basée sur les dimensions de l'image d'entrée et de sortie attendue).

Exemple de code de travail

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten
import numpy as np
import tensorflow as tf

# Loss functtion
def ssim_loss(y_true, y_pred):
  return tf.reduce_mean(tf.image.ssim(y_true, y_pred, 2.0))

# Model: Input Image size: 32X32X1 output Image size: 28X28X1 
# check model.summary
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=(32,32,1)))
model.add(Conv2D(1, kernel_size=(3, 3),
                 activation='relu'))

model.compile(optimizer='adam', loss=ssim_loss, metrics=[ssim_loss, 'accuracy'])

# Train
model.fit(np.random.randn(10,32,32,1), np.random.randn(10,28,28,1))

2voto

Doch88 Points 623

Vous devez créer votre propre fonction de perte personnalisée afin d'utiliser les pertes externes. Toutefois, ces pertes doivent être adaptées pour utiliser les tenseurs de Tensorflow et les fonctions no des valeurs numériques ou des matrices, ce n'est donc pas si simple.

Je vous suggère de voir comment écrire une fonction de perte personnalisée, il y a beaucoup de bons tutoriels à ce sujet, comme par exemple celui-ci .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X