2017-05-23 1 views
2

Essayez de personnaliser la fonction de perte (perte de L1 lisse) dans keras comme ci-dessouskeras: perte lisse L1

ValueError: Shape must be rank 0 but is rank 5 for 'cond/Switch' (op: 'Switch') with input shapes: [?,24,24,24,?], [?,24,24,24,?].

from keras import backend as K 
import numpy as np 


def smooth_L1_loss(y_true, y_pred): 
    THRESHOLD = K.variable(1.0) 
    mae = K.abs(y_true-y_pred) 
    flag = K.greater(mae, THRESHOLD) 
    loss = K.mean(K.switch(flag, (mae - 0.5), K.pow(mae, 2)), axis=-1) 
    return loss 

Répondre

3

Voici une implémentation de la perte lisse L1 en utilisant keras.backend:

HUBER_DELTA = 0.5 
def smoothL1(y_true, y_pred): 
    x = K.abs(y_true - y_pred) 
    x = K.switch(x < HUBER_DELTA, 0.5 * x ** 2, HUBER_DELTA * (x - 0.5 * HUBER_DELTA)) 
    return K.sum(x) 
+0

Merci beaucoup. Mais j'ai toujours l'erreur: ** ValueError: Shape doit être de rang 0 mais de rang 5 pour 'cond/Switch' (op: 'Switch') avec des formes d'entrée: [?, 24,24,24,?], [ ?, 24,24,24,?]. ** –

+0

@yuanzhou Cela signifie que la sortie réseau ou vos cibles ont des formes incorrectes/incompatibles. –

+0

Désolé, je ne pense pas que ce soit le problème avec la forme de sortie et les cibles, lorsque j'utilise d'autres fonctions de perte, cela fonctionne très bien. L'erreur s'est produite uniquement en utilisant le smoothL1 personnalisé. –

1
def smoothL1(y_true, y_pred): 
    x = K.abs(y_true - y_pred) 
    if K._BACKEND == 'tensorflow': 
     import tensorflow as tf 
     x = tf.where(x < HUBER_DELTA, 0.5 * x ** 2, HUBER_DELTA * (x - 0.5 * HUBER_DELTA)) 
     return K.sum(x) 
+0

si le backend est Tensorflow, vous devriez vous tf.where au lieu de K.switch – jasonYu