[PYTHON] [Textklassifizierung] Ich habe versucht, den Aufmerksamkeitsmechanismus für Faltungs-Neuronale Netze zu verwenden.

Einführung

Convolutional Neural Networks (CNN) werden auch für die Bildverarbeitung und die Verarbeitung natürlicher Sprache verwendet. Warum jedoch nicht mit einem Aufmerksamkeitsmechanismus kombinieren? Also habe ich es versucht.

Aufmerksamkeitsmechanismus

Einfach ausgedrückt, ist es eine Funktion, mit der Sie sich mehr auf die wichtigen Teile Ihrer Eingabe konzentrieren können (hier der Satz).

Sie ist schön und hat einen guten Stil, aber sie hat die schlechteste Persönlichkeit.

Wenn Sie beispielsweise die Bewertungspolarität (positiv oder negativ) dieses Satzes bestimmen möchten, beurteilen Menschen ihn als negativ, indem sie sich den folgenden Abschnitt ansehen, der "das Schlimmste" enthält. In ähnlicher Weise kann der Aufmerksamkeitsmechanismus den "schlimmsten" Teil mehr betonen als die "Schönheit", "(Stil) gut".

Ursprünglich in maschineller Übersetzung veröffentlicht. Neuronale maschinelle Übersetzung durch gemeinsames Lernen des Ausrichtens und Übersetzens [Bahdanau et al., ICLR2015] Für diejenigen, die mehr Details wissen möchten, ist der Artikel hier leicht zu verstehen.

Aufmerksamkeitsmechanismus in CNN

Der Aufmerksamkeitsmechanismus wurde bei verschiedenen Aufgaben der Verarbeitung natürlicher Sprache verwendet, seit er in der maschinellen Übersetzung angekündigt wurde. Bei den meisten handelt es sich jedoch um RNN-Methoden, die LSTM und GRU anwenden. Dieses Mal habe ich versucht, den Aufmerksamkeitsmechanismus für CNN in der Aufgabe zur Klassifizierung der Bewertungspolarität zu verwenden. Die Klassifizierung der Bewertungspolarität ist die Aufgabe, vorherzusagen, ob ein Eingabesatz eine positive oder negative Bedeutung hat, wenn er gegeben wird, wie im obigen Beispiel.

Netzwerkmodell

Es basiert auf Convolutional Neural Networks for Satzklassifikation [Kim, EMNLP2014]. スクリーンショット 2016-12-20 13.20.27(2).jpg

Aufmerksamkeitsberechnung

Einführung des Aufmerksamkeitsmechanismus für RNN unter Verwendung von GRU zur Klassifizierung von Dokumenten [Hierarchical Attention Networks for Document Classification] (https://www.cs.cmu.edu/~diyiy/docs/naacl16.pdf) [Yang et al., NAACL2016] Ich bezog mich auf. Feature-Map $ \ boldsymbol {c} \ in \ mathcal {R} ^ {l-k + 1} $

\boldsymbol{c} = [c_1, c_2,\cdots,c_{l-k+1}]

$ l $ ist die Satzlänge und $ k $ ist die Fenstergröße. Berechnet die Wichtigkeit in dieser Feature-Map $ \ boldsymbol {c} $. Dieser Teil ist der Aufmerksamkeitsmechanismus.

\begin{align}
p & = \sum_{i} a_i \odot c_i \\
a_i & = \frac{\exp(W^{(C2)} \tanh(W^{(C1)} c_i))} {\sum_{j} \exp(W^{(C2)} \tanh(W^{(C1)} c_j))}
\end{align}

$ \ Odot $ ist das Produkt von Elementen. $ W ^ {(C1)} \ in \ mathcal {R} ^ {{d} \ times 1} $, $ W ^ {(C2)} \ in \ mathcal {R} ^ {1 \ times {d}} $ D $ in $ ist ein Hyperparameter. Wie ist dieser Name? .. $ a_i $ hat reelle Werte von 0 bis 1, und je näher $ a_i $ an 1 liegt, desto wichtiger ist das entsprechende $ c_i $. Ein Pooling-Ergebnis $ p $ wird von einer Feature-Map ausgegeben. Ab hier ist es dasselbe wie das oben eingeführte Kim CNN-Modell. Kombinieren Sie mehrere $ p $, komprimieren Sie den resultierenden Vektor $ v $ dimensional und klassifizieren Sie ihn mit einem Softmax-Klassifikator.

v = p^1\oplus p^2\oplus \cdots p^m

$ m $ ist die Anzahl der Feature-Maps. Hier ist es wie bei Kim auf 100 gesetzt.

Es fühlt sich so an, als hätte ich versucht, Attention anstelle von Max Pooling in der Pooling-Schicht von CNN zu verwenden. In der Abbildung sieht es so aus.

スクリーンショット 2017-02-03 15.07.49.jpg

Bei Verwendung von Attention in RNN berechnen wir die Wichtigkeit des Vektors der verborgenen Schicht. Dies ist eine Form, die die Wichtigkeit des durch Falten erhaltenen Skalars berechnet (haben Sie Ngram-Informationen?). Ob es also funktioniert oder nicht. .. ..

Daten

Code (Netzwerkteil)

cnn_attention.py


class CNN_attention(Chain):
    def __init__(self, vocab_size, embedding_size, input_channel, output_channel_1, output_channel_2, output_channel_3, k1size, k2size, k3size, pooling_units, atten_size=20, output_size=args.classtype, train=True):
        super(CNN_attention, self).__init__(
            w2e = L.EmbedID(vocab_size, embedding_size),
            conv1 = L.Convolution2D(input_channel, output_channel_1, (k1size, embedding_size)),
            conv2 = L.Convolution2D(input_channel, output_channel_2, (k2size, embedding_size)),
            conv3 = L.Convolution2D(input_channel, output_channel_3, (k3size, embedding_size)),

            l1 = L.Linear(pooling_units, output_size),
            #Attention
            a1 = L.Linear(1, atten_size),
            a2 = L.Linear(atten_size, 1),
        )
        self.output_size = output_size
        self.train = train
        self.embedding_size = embedding_size
        self.ignore_label = 0
        self.w2e.W.data[self.ignore_label] = 0
        self.w2e.W.data[1] = 0  #Nicht-Charakter
        self.input_channel = input_channel

    def initialize_embeddings(self, word2id):
        #w_vector = word2vec.Word2Vec.load_word2vec_format('./vector/glove.840B.300d.txt', binary=False)  # GloVe
        w_vector = word2vec.Word2Vec.load_word2vec_format('./vector/GoogleNews-vectors-negative300.bin', binary=True)  # word2vec
        for word, id in sorted(word2id.items(), key=lambda x:x[1])[1:]:
            if word in w_vector:
                self.w2e.W.data[id] = w_vector[word]
            else:
                self.w2e.W.data[id] = np.reshape(np.random.uniform(-0.25,0.25,self.embedding_size),(self.embedding_size,))
    
    def __call__(self, x):
        h_list = list()
        ox = copy.copy(x)
        if args.gpu != -1:
            ox.to_gpu()
        
        x = xp.array(x.data)
        x = F.tanh(self.w2e(x))
        b, max_len, w = x.shape  # batch_size, max_len, embedding_size
        x = F.reshape(x, (b, self.input_channel, max_len, w))

        c1 = self.conv1(x)
        b, outputC, fixed_len, _ = c1.shape
        tf = self.set_tfs(ox, b, outputC, fixed_len)  # true&flase
        h1 = self.attention_pooling(F.relu(c1), b, outputC, fixed_len, tf)
        h1 = F.reshape(h1, (b, outputC))
        h_list.append(h1)

        c2 = self.conv2(x)
        b, outputC, fixed_len, _ = c2.shape
        tf = self.set_tfs(ox, b, outputC, fixed_len)  # true&flase
        h2 = self.attention_pooling(F.relu(c2), b, outputC, fixed_len, tf)
        h2 = F.reshape(h2, (b, outputC))
        h_list.append(h2)

        c3 = self.conv3(x)
        b, outputC, fixed_len, _ = c3.shape
        tf = self.set_tfs(ox, b, outputC, fixed_len)  # true&flase
        h3 = self.attention_pooling(F.relu(c3), b, outputC, fixed_len, tf)
        h3 = F.reshape(h3, (b, outputC))
        h_list.append(h3)

        h4 = F.concat(h_list)
        y = self.l1(F.dropout(h4, train=self.train))
        return y

    def set_tfs(self, x, b, outputC, fixed_len):
        TF = Variable(x[:,:fixed_len].data != 0, volatile='auto')
        TF = F.reshape(TF, (b, 1, fixed_len, 1))
        TF = F.broadcast_to(TF, (b, outputC, fixed_len, 1))
        return TF

    def attention_pooling(self, c, b, outputC, fixed_len, tf):
        reshaped_c = F.reshape(c, (b*outputC*fixed_len, 1))
        scala = self.a2(F.tanh(self.a1(reshaped_c)))
        reshaped_scala = F.reshape(scala, (b, outputC, fixed_len, 1)) 
        reshaped_scala = F.where(tf, reshaped_scala, Variable(-10*xp.ones((b, outputC, fixed_len, 1)).astype(xp.float32), volatile='auto'))  
        rereshaped_scala = F.reshape(reshaped_scala, (b*outputC, fixed_len))  # reshape for F.softmax
        softmax_scala = F.softmax(rereshaped_scala)
        atten = F.reshape(softmax_scala, (b*outputC*fixed_len, 1))
        a_h = F.scale(reshaped_c, atten, axis=0)
        reshaped_a_h = F.reshape(a_h, (b, outputC, fixed_len, 1))
        p = F.sum(reshaped_a_h, axis=2)
        return p

Versuchsinhalt

Wir haben SST verwendet, um die Genauigkeitsrate der Klassifizierung mit dem maximalen Pooling zu vergleichen. Wir haben mit zwei Aufgaben experimentiert: SST-5, das die fünf Werte sehr negativ, negativ, neutral, positiv und sehr positiv klassifiziert, und SST-2, das positiv und negativ ohne neutral klassifiziert.

Versuchsergebnis

method SST-2 SST-5
max 86.3 (0.27) 46.5 (1.13)
attention 86.0 (0.20) 47.2 (0.37)

Der Wert ist der Durchschnittswert, der fünfmal versucht wurde, und der Wert in Klammern ist die Standardabweichung. Die 5-Wert-Klassifizierung sollte beachtet werden, aber das Ergebnis ist, dass sich der 2-Wert nicht so stark ändert. Übrigens betrug der Maximalwert (SST-5) von 5 mal 48,2% für maximales Pooling und 47,7% für Aufmerksamkeit, was besser für maximales Pooling ist. Es ist einfach zu schütteln. .. ..

Erwägung

Wenn Sie sich die Aufmerksamkeit in der Feature-Map genauer ansehen, Es stellte sich heraus, dass einer von ihnen mit etwa 0,9 stark betont wurde und die anderen fast 0 waren, was dem maximalen Pooling ähnlich war. Im Gegensatz zum maximalen Pooling wird jedoch der Wert der gesamten Feature-Map berücksichtigt, sodass ich mich frage, ob es schwierig ist, einen Fehler zu machen. .. ..

abschließend

Intuitiv war ich der Meinung, dass Aufmerksamkeit, die die allgemeine Bedeutung betrachtet, besser ist als maximales Pooling, bei dem nur der maximale Wert verwendet wird. Es ist nicht schlecht, weil die Genauigkeit der 5-Wert-Klassifizierung höher ist als die der 2-Wert-Klassifizierung. .. Ich denke, es hängt von der Aufgabe ab, deshalb möchte ich auch andere Aufgaben ausprobieren.

Der Artikel hier führt auch die Textklassifizierung mit CNN auf leicht verständliche Weise ein.

Recommended Posts

[Textklassifizierung] Ich habe versucht, den Aufmerksamkeitsmechanismus für Faltungs-Neuronale Netze zu verwenden.
[Textklassifizierung] Ich habe versucht, Faltungsneurale Netze für die Satzklassifizierung mit Chainer zu implementieren
[Satzklassifikation] Ich habe verschiedene Pooling-Methoden von Convolutional Neural Networks ausprobiert
vprof - Ich habe versucht, den Profiler für Python zu verwenden
Verschiedene Hinweise zur Verwendung von Python für Projekte
[Für Anfänger] Ich habe versucht, die Tensorflow-Objekterkennungs-API zu verwenden
Ich habe versucht, die checkio-API zu verwenden
Ich habe versucht, Kwant zu verwenden, ein Python-Modul für die Quantentransportberechnung
Ich habe versucht, Azure Speech to Text zu verwenden.
Ich habe zum ersten Mal Tensorflow ausprobiert
Ich habe versucht, die BigQuery-Speicher-API zu verwenden
Ich habe in der Bibliothek nach der Verwendung der Gracenote-API gesucht
Ich habe versucht, PyCaret mit der schnellsten Geschwindigkeit zu verwenden
Ich habe versucht, die Google Cloud Vision-API zu verwenden
Ich habe zum ersten Mal versucht, Python zu programmieren.
Ich habe versucht, das Datetime-Modul von Python zu verwenden
Ich habe Mind Meld zum ersten Mal ausprobiert
Ich habe das TensorFlow-Tutorial mit Kommentaren ausgeführt (Textklassifizierung von Filmkritiken).
Ich habe versucht, die Lernfunktion im neuronalen Netzwerk sorgfältig zu verstehen, ohne die Bibliothek für maschinelles Lernen zu verwenden (erste Hälfte).
Ich habe versucht, Firebase für Djangos Cache-Server zu verwenden
Ich habe versucht, den Bildfilter von OpenCV zu verwenden
Ich habe versucht, die funktionale Programmierbibliothek toolz zu verwenden
Ich habe versucht, den Text in der Bilddatei mit Tesseract der OCR-Engine zu extrahieren
Ich habe Python zum ersten Mal auf dem Mac ausprobiert.
Ich habe Python zum ersten Mal mit Heroku ausprobiert
[Linux] Ich habe versucht, die genetische Statistiksoftware PLINK zu verwenden
Ich habe versucht, EKG-Daten mit der K-Shape-Methode zu gruppieren
Ich habe versucht, die Sündenfunktion mit Chainer zu approximieren
AI Gaming Ich habe es zum ersten Mal versucht
Ich habe die einfachste Methode zur Klassifizierung von Dokumenten mit mehreren Etiketten ausprobiert
Ich habe versucht, die Sprache mit CNN + Melspectogram zu identifizieren
Ich habe versucht, das Wissensdiagramm mit OpenKE zu ergänzen
Ich habe versucht, das Bild mithilfe von maschinellem Lernen zu komprimieren
Ich habe versucht, Argparse zu verwenden
Ich habe versucht, anytree zu verwenden
Ich habe versucht, aiomysql zu verwenden
Ich habe versucht, Summpy zu verwenden
Ich habe versucht, Coturn zu verwenden
Ich habe versucht, "Anvil" zu verwenden.
Ich habe versucht, Hubot zu verwenden
Ich habe versucht, ESPCN zu verwenden
Ich habe versucht, PyCaret zu verwenden
Ich habe versucht, Cron zu verwenden
Ich habe versucht, ngrok zu verwenden
Ich habe versucht, face_recognition zu verwenden
Ich habe versucht, Jupyter zu verwenden
Ich habe versucht, doctest zu verwenden
Ich habe versucht, Folium zu verwenden
Ich habe versucht, jinja2 zu verwenden
Ich habe versucht, Folium zu verwenden
Ich habe versucht, das Zeitfenster zu verwenden
Ich habe versucht, die häufig verwendete Seaborn-Methode mit so wenig Argumenten wie möglich anzuwenden [für Anfänger]
[Für diejenigen, die TPU verwenden möchten] Ich habe versucht, die Tensorflow Object Detection API 2 zu verwenden
Ich habe versucht, den für TensorFlow geschriebenen Code nach Theano zu portieren
Textklassifizierung mit Convolution (CNN) und Spatial Pyramid Pooling (SPP-net)
Ich habe versucht, die Python-Bibliothek von Ruby mit PyCall zu verwenden