2017-07-18 2 views
2

Vous pouvez fournir le paramètre mean_file à une couche Input dans le cadre du bloc transform_param, tels que:Pouvez-vous définir une couche Caffe pour faire une soustraction à une couche d'entrée pour un modèle déployé?

layer { 
    name: "data" 
    type: "Input" 
    top: "data" 
    input_param { shape: { dim: 1 dim: 3 dim: 224 dim: 224 } } 
    transform_param { 
    mean_file: "imagenet_mean.binaryproto" 
    } 
} 

mais pour une couche Input il semble que cette transformation est juste ignored without warning.

Lors de l'inspection de l'autre data layer types, il semble qu'aucun d'entre eux sont capables d'utiliser une couche couche Input plaine comme en bas (entrée), et si aucune de ces couches peut être utilisée pour appliquer une soustraction moyenne après le fait.

Il existe également un Bias layer, mais je ne comprends pas sa documentation et il ne semble pas accepter un fichier binaryproto. Supposons que je sois contraint, donc je ne peux exprimer que la soustraction moyenne dans le fichier proto. Je ne peux pas le faire en C++ ou en Python à l'avance avant de passer l'entrée, et je ne peux pas l'écrire comme un calque personnalisé ou un calque Python.

Étant donné cette contrainte, comment puis-je obtenir une soustraction moyenne par un fichier binaryproto dans la couche d'entrée - soit en définissant une autre couche après ou après, ou d'autres moyens?

+0

Je pense que caffe a une couche de normalisation par lots, si vous voulez une soustraction moyenne appropriée, vous pouvez l'utiliser et définir la taille de lot à une qui serait lente mais je pense que la normalisation sera généralement utile, https: //stackoverflow.com/questions/41222815/image-moyenne-soustraction-vs-batchnormalization-caffe – Eliethesaiyan

+0

'La couche" Input "' est généralement utilisée dans 'deploy.prototxt', ce qui signifie que vous allez fournir manuellement et indirectement au réseau des données d'entrée. Comment nourrissez-vous ce filet particulier? Dans la plupart des cas, le processus alimentant le filet en temps de test gère également les différentes transformations requises. – Shai

+0

@Shai Oui, comme je l'ai mentionné dans la question, cette opération est destinée à se produire dans un modèle déployé. Dans ce cas, il s'agit d'un système dans lequel vous pouvez soumettre le fichier de poids de modèle formé, le fichier de proto de couche et les fichiers * data *, mais vous ne pouvez pas soumettre de code supplémentaire. Vous ne pouvez donc pas ajouter une nouvelle couche Python ni contrôler aucun prétraitement avant que l'image ne soit transmise au réseau. Je voudrais également faire une opération de redimensionnement dans le calque d'entrée de Caffe, mais il existe une solution de contournement différente dans ce cas pour cela. – ely

Répondre

0

En supposant que vous pouvez avoir une couche d'entrée qui « top » est le moins de 'imagenet_mean.binaryproto', vous pouvez utiliser "Bias" couche pour soustraire la moyenne:

layer { 
    name: "mean_subtract" 
    type: "Bias" 
    bottom: "raw_data" # shape 1-by-3-by-224-by-224 
    bottom: "minus_imagenet_mean" # assuming shape 3-by-224-by-224 
    top: "data" 
    bias_param { axis: 1 } 
} 

Travailler avec batch_size: 1, vous pouvez aussi faire la même soustraction en utilisant la couche "Eltwise".


Mise à jour:
D'accord, il semble que votre question est « où diable vais-je faire "minus_imagenet_mean" blob ?! »
Avez-vous envisagé d'utiliser "Parameter" pour stocker "minus_imagenet_mean"?

layer { 
    name: "minus_imagenet_mean" 
    type: "Parameter" 
    top: "minus_imagenet_mean" 
    parameter_param { shape { dim: 3 dim: 224 dim: 224 } } 
    param { lr_mult: 0 decay_mult: 0 } 
} 

Une fois que vous définissez cette couche, vous pouvez utiliser net surgery pour initialiser ce paramètre. Puis le stocker à caffemodel à côté de tous les autres paramètres du net et vous devriez aller bien.

+0

Cela n'explique pas comment utiliser 'imagenet_mean.binaryproto' pour effectuer la soustraction moyenne. De la documentation, il semble que la couche 'Bias' nécessite de fournir un tableau moyen (avec une forme conforme à la diffusion) en entrée, mais encore une fois, je ne peux pas le faire dans ce cas. Vous devez supposer que je n'ai rien d'autre que le binaryproto, et je ne peux rien faire avec, sauf le mentionner dans un type de calque. – ely

+0

Après les mises à jour, il n'est toujours pas clair comment une couche supérieure nommée "minus_imagenet_mean" pourrait être utilisée. Les couches de données ne peuvent pas recevoir d'entrée d'une couche 'Input', et il n'est pas clair comment passer le binaryproto comme argument de soustraction à une autre couche de soustraction personnalisée. La «chirurgie du net» est également complètement indisponible compte tenu des contraintes de mon problème mentionné dans la question: juste pouvoir passer le proto, caffemodel, et les fichiers de données à un autre système qui peut consommer et exécuter des modèles. Je ne peux pas manipuler ce que le code Python est appelé à l'avance (sinon je voudrais juste dire soustraction en Python). – ely

+0

@ely ** stage offline ** (à porter une fois par vous * avant * en passant 'caffemodel'): dans cette étape, vous devriez ouvrir le net en python, lire le' 'imagenet_mean.binaryproto'' et utiliser net surgery , définissez 'net.layer [minus_imagenet_mean] .blobs [0] .data [...] = -imagenet_mean'. Vous sauvegardez maintenant le caffemodel résultant. ** Suivant ** vous téléchargez le caffemodel enregistré qui a '-imagenet_mean' stocké dans le fichier comme l'un des paramètres des couches de votre système. ** étape en ligne ** le caffemodel mis à jour lit le -imagenet_mean' stocké dans le caffemodel téléchargé et soustrait la moyenne comme vous l'attendiez. – Shai