2017-09-11 3 views
0

J'aime calculer l'erreur pondérée ci-dessous:perte pondérée sur mesure dans cntk

def calc_err(pred, targets, weights) : 
    nClass = np.size(pred, axis=0) 

    Is = [1.0 for i in range(nClass)] 
    nonTargets = C.minus(Is, targets) 
    wrongPred = C.minus(Is, pred) 
    wColumn = C.times(targets, weights) 
    wTarget = C.element_times(wColumn, targets) 
    wNonTarget = C.element_times(wColumn, nonTargets) 
    c1 = C.negate(C.reduce_sum(C.element_times(wTarget, C.log(pred)), axis = -1)) 
    c2 = C.negate(C.reduce_sum(C.element_times(wNonTarget, C.log(wrongPred)), axis = -1)) 
    ce = c1 + c2 

    return ce.eval() 

où pred est probabilités de prédiction, les cibles devraient tableau à une chaude, et le poids est un tableau 2D. J'ai créé une perte personnalisée correspondante ci-dessous:

def WeightedCrossEntropy(z, targets): 
    pred = C.softmax(z) 
    nClass = np.size(pred, axis=0) 
    Is = [1 for i in range(nClass)] 

    nonTargets = C.minus(Is, targets) 
    wrongPred = C.minus(Is, pred) 
    wColumn = C.times(targets, weights) 
    wTarget = C.element_times(wColumn, targets) 
    wNonTarget = C.element_times(wColumn, nonTargets) 
    c1 = C.negate(C.reduce_sum(C.element_times(wTarget, C.log(pred)), axis=-1)) 
    c2 = C.negate(C.reduce_sum(C.element_times(wNonTarget, C.log(wrongPred)), axis=-1)) 
    ce = c1 + c2 

    return ce 

Quand j'ai essayé de former, je l'ai remarqué que si la perte personnalisée diminue en effet, mais l'erreur de test de calc_err (pred, cibles, poids) ne diminuer une ou deux époques ou pas du tout. Est-ce que mon WeightedCrossEntropy (z, cibles) est correct ou qu'est-ce que j'ai fait de mal?

Répondre

0

Les poids sont-ils une constante ou un paramètre? Veuillez vous assurer que ces deux fonctions prennent les mêmes entrées, paramètres et constantes.

+0

Les poids sont précalculés comme ci-dessus. Comment puis-je vérifier que ces deux fonctions prennent les mêmes entrées, paramètres et constantes? J'ai révisé le code en tant que def WeightedCrossEntropy (z, targets): return calc_err (z, targets, weight) donc la fonction de test et de perte appelle calc_err, mais obtient toujours les mêmes résultats. S'il vous plaît donnez votre avis. Merci! –

+0

Si les entrées sont les mêmes, la différence entre les données d'entraînement et les données de test peut provenir de [surapprentissage] (https://en.wikipedia.org/wiki/Overfitting). Vous devez vérifier si calc_err génère la même mesure pour les données d'entraînement que pour l'entraînement en premier, et si c'est le cas, il s'agit d'un problème typique de sur-apprentissage. Il y a plusieurs façons d'aborder le surapprentissage, y compris, mais sans s'y limiter, l'ajout de décrochage dans le modèle, l'utilisation de la régularisation L1/L2 dans l'apprenant, etc. – KeD

+0

Vous avez raison, KeD. Il semble en effet provoqué par le surajustement. J'ai augmenté la régularisation de L2 de 0,0001 à 1,0, l'erreur de test continuera à diminuer jusqu'à 10 époques. J'ai essayé avec plusieurs autres valeurs, mais toutes moins de 10 époques. Nous utilisons des couches ResNet 20 et avons 14000 échantillons avec des entrées 64x64x3, que pouvons-nous faire d'autre pour réduire le surapprentissage? –

0

Le dessous est comment les poids sont pré-calculés:

def ColBasedCustomWeight(nClass) : 
    ratio = 1.0 
    pfSum = [0] * nClass 
    pWs = [[0 for x in range(nClass)] for y in range(nClass)] 
    for j in range(nClass): 
     for i in range(nClass): 
      n = i - j 
      if n > 0: 
       # false negative if j = 0 
       pWs[j][i] = math.pow(1.5,ratio*n) if j == 0 else math.pow(1.2,ratio*n) 
      elif n < 0: 
       # false positive if i = 0 
       pWs[j][i] = math.pow(1.5, -ratio*n) if i == 0 else math.pow(1.2, -ratio*n) 
      else: 
       pWs[j][i] = 1.0 
      pfSum[i] += pWs[j][i] 

    #normalize the weights to nClass 
    for j in range(nClass): 
     for i in range(nClass): 
      pWs[j][i] *= nClass/pfSum[i] 

    return pWs 

Tout problème avec la définition de poids ou calcul?