Python >> Tutoriel Python >  >> Python Tag >> Keras

Maximiser le MSE d'un modèle keras

MISE À JOUR :

L'implémentation MSE d'origine ressemble à ceci :

def mean_squared_error(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return K.mean(K.square(y_pred - y_true), axis=-1)

Je pense que la fonction de perte de maximisation correcte :

def mean_squared_error_max(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return K.mean(K.square(1 / (y_pred - y_true)), axis=-1)

De cette façon, nous obtenons toujours une valeur de perte positive, comme dans le cas de la fonction MSE, mais avec un effet inversé.

MISE À JOUR 2 : Au départ, j'ai écrit que la première pensée intuitive de simplement nier la perte ne sera PAS donner le résultat que nous attendions en raison du concept de base des méthodes d'optimisation (vous pouvez lire une discussion intéressante ici). Après avoir vérifié les deux méthodes tête à tête, le résultat dans une tâche d'apprentissage particulière (Remarque :je n'ai pas fait de test complet) était que les deux méthodes donnaient la maximisation des pertes, bien que le -loss l'approche a convergé un peu plus vite. Je ne sais pas si cela donne toujours la meilleure solution ou n'importe quelle solution en raison du problème possible décrit ici. Si quelqu'un a une autre expérience, veuillez me le faire savoir.

Donc, si quelqu'un veut essayer -loss aussi :

def mean_squared_error(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return - K.mean(K.square(y_pred - y_true), axis=-1)


Détails supplémentaires :

OP a écrit :

J'ai des réseaux antagonistes génératifs, où le discriminateur est minimisé avec le MSE et le générateur doit être maximisé. Parce que les deux sont des adversaires qui poursuivent le but opposé.

À partir du lien fourni par Ibragil :

Pendant ce temps, le générateur crée de nouvelles images synthétiques qu'il transmet au discriminateur. Il le fait dans l'espoir qu'eux aussi seront considérés comme authentiques, même s'ils sont faux. Le but du générateur est de générer des chiffres manuscrits passables :mentir sans se faire prendre. Le but du discriminateur est d'identifier les images provenant du générateur comme fausses.


C'est donc un problème mal posé :

Dans GAN notre objectif final de former nos deux contreparties le discriminateur et le générateur pour jouer aussi bien que possible les uns contre les autres. Cela signifie que les deux algorithmes d'apprentissage de base ont des tâches différentes mais la fonction de perte avec lequel ils peuvent atteindre la solution optimale est le même c'est-à-dire binary_crossentropy , donc les tâches des modèles sont de minimiser cette perte.

Un discriminateur méthode de compilation du modèle :

self.discriminator.compile(loss='binary_crossentropy', optimizer=optimizer)

Un générateur méthode de compilation du modèle :

self.generator.compile(loss='binary_crossentropy', optimizer=optimizer)

C'est la même chose que l'objectif de deux coureurs de minimiser leur temps d'arrivée même s'ils sont concurrents dans cette tâche.

Ainsi, "l'objectif opposé" ne signifie pas une tâche opposée, c'est-à-dire minimiser la perte (c'est-à-dire minimiser le temps dans l'exemple du coureur).

J'espère que ça aide.


La question n'est pas très claire pour moi. Je suppose que vous voulez maximiser au lieu de minimiser, tout en utilisant le critère de l'EQM.

Vous pouvez implémenter votre propre fonction de perte personnalisée, qui calcule le -MSE; en inversant le signe de la perte, et en réalisant ainsi un retournement dans la direction de descente du gradient.

def negative_mse(y,yhat): 
    return - K.mean(K.sum(K.square(y-yhat)))

model.compile(loss=negative_mse, optimizer='adam')

Une autre option consiste simplement à fournir une étape d'apprentissage négative - mais je ne suis pas sûr que Keras vous permette de le faire. Ça vaut le coup d'essayer.