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.
-
y a-t-il un tutoriel/exemple sur l'utilisation de la couche
INFOGAIN_LOSS
? -
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).
-
Comment puis-je convertir mon
numpy.array
en unbinproto
fichier qui peut être fourni comme uninfogain_loss_param { source }
au modèle? -
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" estH
? 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?
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 .
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).
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.
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"
}
}