2017-09-29 22 views
0

Je m'adresse à une tâche de classification binaire phrase-niveau. Mes données se composent de 3 sous-groupes de jetons: le contexte de gauche, le noyau et le contexte de droite.Pourquoi 2 presque égales Keras CNN renvoie 2 résultats tout à fait différents

J'utilisé Keras pour concevoir plusieurs alternatives de convolutifs Neural Networks et valider lequel répondent le mieux à mon problème. Je suis un novice en Python et Keras et j'ai décidé de commencer par des solutions plus simples afin de tester quels changements améliorent mes métriques (précision, précision, rappel, f1 et auc-roc). La première simplification est en ce qui concerne les données d'entrée: j'ai décidé de ne pas tenir compte des contextes pour créer un modèle séquentiel de Keras:

_________________________________________________________________ 
Layer (type)     Output Shape    Param # 
================================================================= 
input_1 (InputLayer)   (None, 500)    0   
_________________________________________________________________ 
masking_1 (Masking)   (None, 500)    0   
_________________________________________________________________ 
embedding_1 (Embedding)  (None, 500, 100)   64025600 
_________________________________________________________________ 
conv1d_1 (Conv1D)   (None, 497, 128)   51328  
_________________________________________________________________ 
average_pooling1d_1 (Average (None, 62, 128)   0   
_________________________________________________________________ 
dropout_1 (Dropout)   (None, 62, 128)   0   
_________________________________________________________________ 
conv1d_2 (Conv1D)   (None, 61, 256)   65792  
_________________________________________________________________ 
dropout_2 (Dropout)   (None, 61, 256)   0   
_________________________________________________________________ 
conv1d_3 (Conv1D)   (None, 54, 32)   65568  
_________________________________________________________________ 
global_max_pooling1d_1 (Glob (None, 32)    0   
_________________________________________________________________ 
dense_1 (Dense)    (None, 16)    528  
_________________________________________________________________ 
dropout_3 (Dropout)   (None, 16)    0   
_________________________________________________________________ 
dense_2 (Dense)    (None, 2)     34   
================================================================= 

Comme vous pouvez le voir, j'utiliser une taille fixe d'entrées, donc j'appliqué un pré-traitement de rembourrage. J'ai également utilisé une couche d'intégration avec un modèle Word2Vec.

Ce modèle renvoie les résultats suivants:

P  0.875457875 
R  0.878676471 
F1  0.87706422 
AUC-ROC 0.906102654 

que je voulais mettre en œuvre comment sélectionner un sous-tableau de données d'entrée à l'intérieur de mon CNN au moyen de couches Lambda. J'utilise la définition suivante de ma couche Lambda:

Lambda(lambda x: x[:, 1], output_shape=(500,))(input) 

Et Voici le résumé de mon nouveau CNN (comme vous pouvez le voir est presque la même que la précédente):

_________________________________________________________________ 
Layer (type)     Output Shape    Param # 
================================================================= 
input_1 (InputLayer)   (None, 3, 500)   0   
_________________________________________________________________ 
lambda_1 (Lambda)   (None, 500)    0   
_________________________________________________________________ 
masking_1 (Masking)   (None, 500)    0   
_________________________________________________________________ 
embedding_1 (Embedding)  (None, 500, 100)   64025600 
_________________________________________________________________ 
conv1d_1 (Conv1D)   (None, 497, 128)   51328  
_________________________________________________________________ 
average_pooling1d_1 (Average (None, 62, 128)   0   
_________________________________________________________________ 
dropout_1 (Dropout)   (None, 62, 128)   0   
_________________________________________________________________ 
conv1d_2 (Conv1D)   (None, 61, 256)   65792  
_________________________________________________________________ 
dropout_2 (Dropout)   (None, 61, 256)   0   
_________________________________________________________________ 
conv1d_3 (Conv1D)   (None, 54, 32)   65568  
_________________________________________________________________ 
global_max_pooling1d_1 (Glob (None, 32)    0   
_________________________________________________________________ 
dense_1 (Dense)    (None, 16)    528  
_________________________________________________________________ 
dropout_3 (Dropout)   (None, 16)    0   
_________________________________________________________________ 
dense_2 (Dense)    (None, 2)     34   
================================================================= 

Mais les résultats étaient dégoûtant parce que la précision s'arrête à 60% et, évidemment, la précision, le rappel et F1 étaient trop faibles (< 0,10) en ce qui concerne les résultats du premier modèle.

Je ne sais pas ce qui se passe et je ne sais pas si ces réseaux sont plus différents que je pensais.

Des indices sur ce problème?

Répondre

0

Deux questions initiales (mais je ne commenter pas encore suffisamment rep):

(1) Quelle est la motivation pour utiliser un CNN? Ils permettent de sélectionner des entités locales dans un tableau à deux dimensions de valeurs d'entrée. Par exemple, si vous imaginez une image en noir et blanc sous la forme d'un tableau d'entiers à deux dimensions où les entiers représentent l'échelle de gris, pixels qui représentaient des choses comme des bords, des coins ou des lignes blanches diagonales. A moins que vous ayez une raison de vous attendre à ce que vos données, comme une image, possèdent de telles fonctionnalités groupées localement, et que les points les plus proches horizontalement et verticalement dans vos tableaux d'entrée soient plus pertinents, vous pouvez être mieux avec des couches denses Il n'y a pas d'hypothèses quant aux caractéristiques d'entrée qui sont pertinentes pour les autres. Commencez par dire 2 couches, et voyez où cela vous mène. (2) En supposant que vous êtes confiant sur la forme de votre architecture, avez-vous essayé d'abaisser le taux d'apprentissage? C'est la première chose à essayer dans n'importe quel NN qui ne converge pas bien.

(3) Selon la tâche, il vaut peut-être mieux utiliser un dictionnaire et un codage à chaud pour vos mots, surtout si la classification est relativement simple et que le contexte n'est pas très compliqué. Word2Vec signifie que vous codez les mots en tant que nombres, ce qui a des implications pour la descente de gradient.Difficile de dire sans savoir ce que vous essayez d'atteindre, mais si vous n'avez pas une idée raisonnable pourquoi utiliser word2vec est une bonne idée, il peut ne pas être ...

This link explique la différence entre les CNN et les couches denses bien , peut donc vous aider à juger.

+0

J'ai reformulé ma question pour la clarifier. Parce que je ne pense pas que tu l'aies compris. Néanmoins, je vais répondre à vos questions. –

+0

1.- Dans ma tâche, les fonctionnalités locales concernant les proches proches sont assez importantes, donc CNN fonctionne bien pour ce genre de tâche. Vous pouvez trouver plusieurs exemples de CNN pour NLP dans la littérature: https://dl.acm.org/citation.cfm?id=2969342, http://www.anthology.aclweb.org/N/N15/N15-1011 .pdf, http://anthology.aclweb.org/C/C14/C14-1008.pdf, http://emnlp2014.org/papers/pdf/EMNLP2014181.pdf. Cependant, je vais essayer seulement des couches Dense afin de comparer les résultats. –

+0

2.- Je compare deux architectures exactement égales de CNN avec la différence de la couche de Labmda (couches de conv. Égales, couches égales et denses, mise en commun égale, chute égale, taux d'apprentissage égal). L'un d'eux se comporte plutôt bien et l'autre se comporte plutôt mal. 3.- Je dois prendre en compte les caractéristiques sémantiques. C'est la principale raison d'utiliser une solution d'incorporation de mots pour vectoriser les jetons. Un des vecteurs chauds ne m'aide pas trop avec ce problème. J'apprécie vraiment votre réponse. –