[PYTHON] [Classification de texte] J'ai essayé d'implémenter des réseaux de neurones convolutifs pour la classification des phrases avec Chainer

Grosso modo

--Classification de texte à l'aide de réseaux de neurones convolutionnels (CNN).

introduction

Poursuite de la classification des documents [Chainer] précédemment publiée par les réseaux de neurones convolutifs, [Réseaux de neurones convolutifs pour la classification des phrases](http: / /emnlp2014.org/papers/pdf/EMNLP2014181.pdf) a été implémenté dans Chainer.

GitHub de l'auteur publie également une implémentation utilisant Theano.

Le code source développé cette fois-ci est disponible ici: chainer-cnnsc

Données utilisées

-Les données peuvent être trouvées à ici. J'ai utilisé "jeu de données de polarité de phrase v1.0".

Préparation préalable

--Installation de Chainer, scikit-learn, gensim

environnement

Données d'entraînement

Utilisez des données textuelles en anglais. Veuillez obtenir les données textuelles de la destination de téléchargement ci-dessus. Chaque ligne correspond à un document. La première colonne est le libellé et la deuxième colonne et les suivantes sont le texte. Les étiquettes 0 sont des documents négatifs et 1 sont des documents positifs.

[étiquette] [texte(Délimiteur d'espace demi-largeur)]
0 it just didn't mean much to me and played too skewed to ever get a hold on ( or be entertained by ) .
1 culkin , who's in virtually every scene , shines as a young man who uses sarcastic lies like a shield .
...

modèle

Cette fois, j'ai utilisé le modèle proposé dans cet article (Convolutional Neural Networks for Sentence Classification). Vous pouvez trouver une description du modèle dans cet article.

CNNMODEL

Programme (partie réseau)

Dans le programme, plusieurs tailles de filtre pour la convolution sont définies et la convolution est effectuée pour chaque filtre. La taille de filtre définie est stockée dans filter_height au format liste. Pour la propagation directe, la boucle est tournée pour chaque taille de filtre pour effectuer la convolution comme indiqué ci-dessous.

 #Tournez la boucle pour chaque type de filtre
 for i, filter_size in enumerate(self.filter_height):
     #À travers la couche de convolution
     h_conv[i] = F.relu(self[i](x))
     #À travers la couche Pooling
     h_pool[i] = F.max_pooling_2d(h_conv[i], (self.max_sentence_len+1-filter_size))

Le code source de la partie réseau est indiqué ci-dessous.

#Je veux rendre le nombre de liens variable, donc j'utilise ChainList
class CNNSC(ChainList):
    def __init__(self,
                 input_channel,
                 output_channel,
                 filter_height,
                 filter_width,
                 n_label,
                 max_sentence_len):
        #Le nombre de filtres, la hauteur des filtres utilisés et la longueur maximale de la phrase seront utilisés ultérieurement.
        self.cnv_num = len(filter_height)
        self.filter_height = filter_height
        self.max_sentence_len = max_sentence_len
        
        #Ajout d'un lien pour la couche de convolution pour chaque filtre
        # Convolution2D(Nombre de canaux d'entrée,Nombre de canaux de sortie (nombre de filtres pour chaque forme),Forme du filtre (au format tapple),Taille du rembourrage)
        link_list = [L.Convolution2D(input_channel, output_channel, (i, filter_width), pad=0) for i in filter_height]
        #Lien ajouté pour le dépôt
        link_list += [L.Linear(output_channel * self.cnv_num, output_channel * self.cnv_num)]
        #Lien ajouté à la couche de sortie
        link_list += [L.Linear(output_channel * self.cnv_num, n_label)]

        #Initialisez la classe en utilisant la liste des liens définis jusqu'à présent
        super(CNNSC, self).__init__(*link_list)
        
        #Au fait
        # self.add_link(link)
        #Il est normal d'énumérer les liens et de les ajouter un par un comme

    def __call__(self, x, train=True):
        #Préparez la couche intermédiaire filtrée
        h_conv = [None for _ in self.filter_height]
        h_pool = [None for _ in self.filter_height]
        
        #Tournez la boucle pour chaque type de filtre
        for i, filter_size in enumerate(self.filter_height):
            #À travers la couche de convolution
            h_conv[i] = F.relu(self[i](x))
            #À travers la couche Pooling
            h_pool[i] = F.max_pooling_2d(h_conv[i], (self.max_sentence_len+1-filter_size))
        # Convolution+Combinez les résultats de la mise en commun
        concat = F.concat(h_pool, axis=2)
        #Supprimer le résultat combiné
        h_l1 = F.dropout(F.tanh(self[self.cnv_num+0](concat)),ratio=0.5,train=train)
        #Compresser le résultat de la suppression dans la couche de sortie
        y = self[self.cnv_num+1](h_l1)

        return y

Résultat expérimental

Dans l'expérience, l'ensemble de données a été divisé en données de formation et données de test, et 50 époques ont été tournées pour la formation. Le taux de réponse correct pour les données de test était la 50e époque et «précision = 0,799437701702».

Cet article lors de la classification de documents avec un modèle utilisant un CNN plus simple, c'était ʻexactitude = 0.775624996424`, donc le taux de réponse correct est légèrement A été trouvé pour s'améliorer.

input file name: dataset/mr_input.dat
loading word2vec model...
height (max length of sentences): 59
width (size of wordembedding vecteor ): 300
epoch 1 / 50
train mean loss=0.568159639835, accuracy=0.707838237286
 test mean loss=0.449375987053, accuracy=0.788191199303
epoch 2 / 50
train mean loss=0.422049582005, accuracy=0.806962668896
 test mean loss=0.4778624475, accuracy=0.777881920338
epoch 3 / 50
train mean loss=0.329617649317, accuracy=0.859808206558
 test mean loss=0.458206892014, accuracy=0.792877197266
epoch 4 / 50
train mean loss=0.240891501307, accuracy=0.90389829874
 test mean loss=0.642955899239, accuracy=0.769447028637
 ...
epoch 47 / 50
train mean loss=0.000715514877811, accuracy=0.999791562557
 test mean loss=0.910120248795, accuracy=0.799437701702
epoch 48 / 50
train mean loss=0.000716249051038, accuracy=0.999791562557
 test mean loss=0.904825389385, accuracy=0.801312088966
epoch 49 / 50
train mean loss=0.000753249507397, accuracy=0.999791562557
 test mean loss=0.900236129761, accuracy=0.799437701702
epoch 50 / 50
train mean loss=0.000729961204343, accuracy=0.999791562557
 test mean loss=0.892229259014, accuracy=0.799437701702

en conclusion

Cet article présente également la mise en œuvre de la classification de texte à l'aide de CNN.

URL de référence

Recommended Posts

[Classification de texte] J'ai essayé d'implémenter des réseaux de neurones convolutifs pour la classification des phrases avec Chainer
[Classification de texte] J'ai essayé d'utiliser le mécanisme d'attention pour les réseaux de neurones convolutifs.
[Classification des phrases] J'ai essayé différentes méthodes de mise en commun des réseaux de neurones convolutifs
[Chainer] Classification des documents par réseau de neurones convolutifs
J'ai écrit le code pour la génération de phrases japonaises avec DeZero
[Enquête] MobileNets: Réseaux de neurones à convolution efficaces pour les applications de vision mobile
[Apprentissage en profondeur] Classification d'images avec un réseau neuronal convolutif [DW jour 4]
Classification des documents avec une phrase
J'ai essayé d'implémenter VQE avec Blueqat
Réseau de neurones commençant par Chainer
Implémentation du GAN conditionnel avec chainer
Implémentation de SmoothGrad avec Chainer v2
J'ai essayé d'implémenter la classification des phrases par Self Attention avec PyTorch
Apprenez avec les réseaux convolutifs PyTorch Graph
Modèle de classification simple avec réseau neuronal
J'ai essayé d'implémenter Attention Seq2Seq avec PyTorch
J'ai essayé de mettre en œuvre un réseau de neurones à deux couches
J'ai essayé la génération de phrases avec GPT-2
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer Chapitre 13 Bases du réseau neuronal