Couche InfogainLoss

je souhaite utiliser une couche de perte de type InfogainLoss dans mon modèle. Mais je vais avoir des difficultés à le définir correctement.

  1. y a-t-il un tutoriel/exemple sur l'utilisation de la couche INFOGAIN_LOSS ?

  2. est-ce que l'entrée de cette couche, les probabilités de classe, doit être la sortie d'une couche SOFTMAX , ou est-ce qu'il suffit d'entrer le" haut " d'une couche entièrement connectée?

INFOGAIN_LOSS nécessite trois entrées: les probabilités de classe, les étiquettes et la matrice H . La matrice H peut être fournie sous forme de paramètres de couche infogain_loss_param { source: "fiename" } .

Supposons que j'ai un script python qui calcule H comme numpy.array de forme (L,L) avec dtype='f4' (où L est le nombre d'étiquettes dans mon modèle).

  1. Comment puis-je convertir mon numpy.array en un binproto fichier qui peut être fourni comme un infogain_loss_param { source } au modèle?

  2. Suppose que je veux que H soit fourni comme troisième entrée (en bas) à la couche de perte (plutôt que comme paramètre de modèle). Comment puis-je faire cela?

    Puis-je définir une nouvelle couche de données qui "top" est H ? Si c'est le cas, les données de cette couche ne seraient-elles pas incrémentées à chaque itération de formation? comme les données d'apprentissage est incrémenté? Comment puis-je définir plusieurs couches "données" d'entrée sans rapport, et comment caffe sait-il lire à partir de la formation/essai couche "Données" lot après lot, tandis que de la couche "Données" "151940920 il sait lire une seule fois pour tout le processus de formation?

14
demandé sur Shai 2014-12-24 09:20:31

3 réponses

je n'ai pas une réponse complète à ma question. Cette réponse ne couvre que mes troisième et quatrième parties:

3. Comment puis-je convertir un numpy.tableau dans un fichier binproto :

en python

H = np.eye( L, dtype = 'f4' ) 
import caffe
blob = caffe.io.array_to_blobproto( H.reshape( (1,1,L,L) ) )
with open( 'infogainH.binaryproto', 'wb' ) as f :
    f.write( blob.SerializeToString() )

Maintenant, vous pouvez ajouter au modèle prototext la couche INFOGAIN_LOSS avec H comme paramètre:

layer {
  bottom: "topOfPrevLayer"
  bottom: "label"
  top: "infoGainLoss"
  name: "infoGainLoss"
  type: "InfogainLoss"
  infogain_loss_param {
    source: "infogainH.binaryproto"
  }
}

4. Comment charger H dans une couche de données

, Citant Evan Shelhamer post :

il n'y a actuellement aucun moyen de charger les couches de données à des vitesses différentes. Chaque passe avant toutes les couches de données avanceront. Cependant, l'entrée constante H peut être faite en faisant un fichier lmdb / leveldb / hdf5 qui n'est que H puisque la couche de données va boucler et continuer à charger le même H. il est évident qu'il gaspille de l'IO disque.


comme pour les deux premières parties de ma question:

1. Y a-t-il un tutoriel/exemple sur l'utilisation de la couche InfogainLoss ? :

Un bel exemple peut être trouvé ici : en utilisant InfogainLoss pour s'attaquer au déséquilibre de classe.

2. L'entrée de cette couche, les probabilités de classe, doit-elle être la sortie d'une couche Softmax ?

Selon Yair la réponse de , la réponse est OUI , il devrait être la sortie de Softmax de la couche (ou n'importe quelle autre couche qui fait en sorte que les valeurs d'entrée sont dans l'intervalle [0..1]).


récemment, j'ai remarqué que l'utilisation "InfogainLoss" sur la couche supérieure de "Softmax" peut conduire à une instabilité numérique. Je suggère donc de combiner ces deux couches en une seule (un peu comme la couche "SoftmaxWithLoss" ). Les mathématiques de cette couche combinée sont donnés ici . Une implémentation de ce "combiné" infogainLoss + Softmax peut être trouvée dans cette demande de pull .

8
répondu Shai 2017-05-23 12:01:29

La couche est de résumer

-log(p_i)

et donc le p_i doit être dans (0, 1] pour avoir un sens comme une fonction de perte (autrement des scores de confiance plus élevés produiront une perte plus élevée). Voir la courbe ci-dessous pour les valeurs de log(p).

enter image description here

Je ne pense pas qu'ils doivent résumer jusqu'à 1, mais les passer à travers une couche Softmax permettra d'atteindre les deux propriétés.

2
répondu Yair 2015-05-05 13:31:25

depuis que j'ai dû chercher à travers de nombreux sites Web pour code, je pensais que je partageais mon implémentation:

Python couche pour le calcul de la H-matrice avec des poids pour chaque classe:

import numpy as np
import caffe


class ComputeH(caffe.Layer):
    def __init__(self, p_object, *args, **kwargs):
        super(ComputeH, self).__init__(p_object, *args, **kwargs)
        self.n_classes = -1

    def setup(self, bottom, top):
        if len(bottom) != 1:
            raise Exception("Need (only) one input to compute H matrix.")

        params = eval(self.param_str)
        if 'n_classes' in params:
            self.n_classes = int(params['n_classes'])
        else:
            raise Exception('The number of classes (n_classes) must be specified.')

    def reshape(self, bottom, top):
        top[0].reshape(1, 1, self.n_classes, self.n_classes)

    def forward(self, bottom, top):
        classes, cls_num = np.unique(bottom[0].data, return_counts=True)

        if np.size(classes) != self.n_classes or self.n_classes == -1:
            raise Exception("Invalid number of classes")

        cls_num = cls_num.astype(float)

        cls_num = cls_num.max() / cls_num
        weights = cls_num / np.sum(cls_num)

        top[0].data[...] = np.diag(weights)

    def backward(self, top, propagate_down, bottom):
        pass

et la partie correspondante de la val_train.prototxt:

layer {
    name: "computeH"
    bottom: "label"
    top: "H"
    type: "Python"
    python_param {
        module: "digits_python_layers"
        layer: "ComputeH"
        param_str: '{"n_classes": 7}'
    }
    exclude { stage: "deploy" }
}
layer {
  name: "loss"
  type: "InfogainLoss"
  bottom: "score"
  bottom: "label"
  bottom: "H"
  top: "loss"
  infogain_loss_param {
    axis: 1  # compute loss and probability along axis
  }
  loss_param {
      normalization: 0
  }
  exclude {
    stage: "deploy"
  }
}
1
répondu Torsten Straßer 2018-08-01 20:07:50