[PYTHON] [Chainer] Dokumentklassifizierung nach Faltungsnetzwerk

Einführung

Convolutional Neural Networks (CNN), die häufig zur Bilderkennung usw. verwendet werden. In letzter Zeit wird es auch im Bereich der Verarbeitung natürlicher Sprache verwendet [Kim, EMNLP2014]. Dieses Mal habe ich mit CNN mit Chainer ein einfaches Netzwerk aufgebaut und es auf die Aufgabe der Dokumentklassifizierung angewendet.

Datenspeicher

--Quell Code diesmal implementiert - ichiroex@github

Vorbereitungen

--Installation von Chainer, Scikit-Learn, Gensim

Umgebung

Dokumentvektor erstellen

Dieses Mal wird das Eingabedokument mit word2vec vektorisiert und das vektorisierte Dokument wird gefaltet. Die Vektorisierung von Dokumenten erfolgt mit "def load_data (fname)", definiert in "uitl.py".

Als Bild eine Eingabewortzeichenfolge (Dokument) $ x_1 $, $ x_2 $, $ x_3 $, ...., $ x_n $ für jedes Wort $ x_i $ Konvertiert in einen festdimensionalen $ N $ -Vektor und erstellt nebeneinander einen zweidimensionalen Dokumentvektor.

[Beispiel] word_vector.png

Da die Satzlänge für jedes Dokument unterschiedlich ist, wird ein Auffüllen durchgeführt, um der maximalen Satzlänge $ maxlen $ im Eingabedokument zu entsprechen. Das heißt, die Dimension des erzeugten zweidimensionalen Dokumentvektors ist $ N * maxlen $.

Übrigens beträgt in dem diesmal von Google veröffentlichten word2vec-Modell die Dimension jedes Wortvektors 300.

util.py


def load_data(fname):
    #Laden Sie das trainierte word2vec-Modell
    model =  word2vec.Word2Vec.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)

    target = [] #Etikette
    source = [] #Dokumentvektor

    #Erstellen Sie eine Dokumentliste
    document_list = []
    for l in open(fname, 'r').readlines():
        sample = l.strip().split(' ',  1)
        label = sample[0]
        target.append(label) #Etikette
        document_list.append(sample[1].split()) #Wortliste für jedes Dokument
    
    max_len = 0
    rev_document_list = [] #Dokumentenliste nach unbekannter Textverarbeitung
    for doc in document_list:
        rev_doc = []
        for word in doc:
            try:
                word_vec = np.array(model[word]) #Bei unbekannten Wörtern,KeyError tritt auf
                rev_doc.append(word)
            except KeyError:
                rev_doc.append('<unk>') #Unbekanntes Wort
        rev_document_list.append(rev_doc)
        #Finden Sie die maximale Länge eines Dokuments(Zum Polstern)
        if len(rev_doc) > max_len:
            max_len = len(rev_doc)
    
    #Passen Sie die Dokumentlänge durch Auffüllen an
    rev_document_list = padding(rev_document_list, max_len)
    
    width = 0 #Anzahl der Dimensionen jedes Wortes
    #Vektorisierung von Dokumentmerkmalen
    for doc in rev_document_list:
        doc_vec = []
        for word in doc:
            try:
                vec = model[word.decode('utf-8')]
            except KeyError:
                vec = model.seeded_vector(word)
            doc_vec.extend(vec)
            width = len(vec)
        source.append(doc_vec)

    dataset = {}
    dataset['target'] = np.array(target)    
    dataset['source'] = np.array(source)    

    return dataset, max_len, width

Modelldefinition

Dieses Mal habe ich ein Modell mit einer Struktur aus Faltungsschicht -> Poolschicht -> vollständig verbundener Schicht definiert. Ich habe auch einen Ausfall auf dem Weg.

cnn_network_architecture.png

net.py


class SimpleCNN(Chain):
    
    def __init__(self, input_channel, output_channel, filter_height, filter_width, mid_units, n_units, n_label):
        super(SimpleCNN, self).__init__(
            conv1 = L.Convolution2D(input_channel, output_channel, (filter_height, filter_width)),
            l1    = L.Linear(mid_units, n_units),
            l2    = L.Linear(n_units,  n_label),
        )
    
    #Wird vom Klassifikator aufgerufen
    def __call__(self, x):
        h1 = F.max_pooling_2d(F.relu(self.conv1(x)), 3)
        h2 = F.dropout(F.relu(self.l1(h1)))
        y = self.l2(h2)
        return y

Lernen

Beim Lernen werden die richtige Antwortrate und der richtige Verlust für jede Epoche von Trainingsdaten und Testdaten berechnet und angezeigt. Der Code ist fast der gleiche wie bei Dokumentklassifizierung mithilfe eines vorwärtsgerichteten neuronalen Netzwerks.

Im gefalteten Zustand beträgt die Filtergröße 3 x 300 (die Anzahl der Dimensionen jedes Wortvektors).

train_cnn.py


# Prepare dataset
dataset, height, width = util.load_data(args.data)
print 'height:', height
print 'width:', width

dataset['source'] = dataset['source'].astype(np.float32) #Funktionswert
dataset['target'] = dataset['target'].astype(np.int32) #Etikette

x_train, x_test, y_train, y_test = train_test_split(dataset['source'], dataset['target'], test_size=0.15)
N_test = y_test.size         # test data size
N = len(x_train)             # train data size
in_units = x_train.shape[1]  #Anzahl der Einheiten in der Eingabeebene(Anzahl der Vokabeln)

# (nsample, channel, height, width)In einen 4-dimensionalen Tensor umgewandelt
input_channel = 1
x_train = x_train.reshape(len(x_train), input_channel, height, width) 
x_test  = x_test.reshape(len(x_test), input_channel, height, width)

#Anzahl der versteckten Ebeneneinheiten
n_units = args.nunits
n_label = 2
filter_height = 3
output_channel = 50

#Modelldefinition
model = L.Classifier( SimpleCNN(input_channel, output_channel, filter_height, width, 950, n_units, n_label))

#Gibt an, ob eine GPU verwendet werden soll
if args.gpu > 0:
    cuda.check_cuda_available()
    cuda.get_device(args.gpu).use()
    model.to_gpu()
    xp = np if args.gpu <= 0 else cuda.cupy #args.gpu <= 0: use cpu, otherwise: use gpu

batchsize = args.batchsize
n_epoch = args.epoch

# Setup optimizer
optimizer = optimizers.AdaGrad()
optimizer.setup(model)

# Learning loop
for epoch in six.moves.range(1, n_epoch + 1):

    print 'epoch', epoch, '/', n_epoch
    
    # training)
    perm = np.random.permutation(N) #Holen Sie sich eine zufällige Liste von Ganzzahlspalten
    sum_train_loss     = 0.0
    sum_train_accuracy = 0.0
    for i in six.moves.range(0, N, batchsize):

        #x mit perm_train, y_Wählen Sie einen Datensatz aus dem Zug(Die Zieldaten sind jedes Mal anders)
        x = chainer.Variable(xp.asarray(x_train[perm[i:i + batchsize]])) #source
        t = chainer.Variable(xp.asarray(y_train[perm[i:i + batchsize]])) #target
        
        optimizer.update(model, x, t)

        sum_train_loss      += float(model.loss.data) * len(t.data)   #Zur durchschnittlichen Fehlerberechnung
        sum_train_accuracy  += float(model.accuracy.data ) * len(t.data)   #Zur Berechnung der durchschnittlichen Genauigkeitsrate

    print('train mean loss={}, accuracy={}'.format(sum_train_loss / N, sum_train_accuracy / N)) #Durchschnittlicher Fehler

    # evaluation
    sum_test_loss     = 0.0
    sum_test_accuracy = 0.0
    for i in six.moves.range(0, N_test, batchsize):

        # all test data
        x = chainer.Variable(xp.asarray(x_test[i:i + batchsize]))
        t = chainer.Variable(xp.asarray(y_test[i:i + batchsize]))

        loss = model(x, t)

        sum_test_loss     += float(loss.data) * len(t.data)
        sum_test_accuracy += float(model.accuracy.data)  * len(t.data)

    print(' test mean loss={}, accuracy={}'.format(
        sum_test_loss / N_test, sum_test_accuracy / N_test)) #Durchschnittlicher Fehler

    if epoch > 10:
        optimizer.lr *= 0.97
        print 'learning rate: ', optimizer.lr

    sys.stdout.flush()

Versuchsergebnis

Die endgültige richtige Antwortrate war "Genauigkeit = 0,775624996424". Bei Klassifizierung nach einem vorwärtsgerichteten neuronalen Netzwerk betrug "Genauigkeit = 0,716875001788", sodass sich die Genauigkeitsrate erheblich verbesserte. (Im Fall eines neuronalen Feed-Forward-Netzes wurde word2vec nicht verwendet, und der Dokumentvektor wurde unter Verwendung eines heißen Wortvektors erstellt, sodass die experimentellen Bedingungen unterschiedlich sind.)

height: 59
width: 300
epoch 1 / 100
train mean loss=0.68654858897, accuracy=0.584814038988
 test mean loss=0.673290403187, accuracy=0.674374999106
epoch 2 / 100
train mean loss=0.653146019086, accuracy=0.678733030628
 test mean loss=0.626838338375, accuracy=0.695624998212
epoch 3 / 100
train mean loss=0.604344114544, accuracy=0.717580840894
 test mean loss=0.582373640686, accuracy=0.713124997914

...

epoch 98 / 100
train mean loss=0.399981137426, accuracy=0.826288489978
 test mean loss=0.460177404433, accuracy=0.775625003874
learning rate:  6.85350312961e-05
epoch 99 / 100
train mean loss=0.400466494895, accuracy=0.822536144887
 test mean loss=0.464013618231, accuracy=0.773749999702
learning rate:  6.64789803572e-05
epoch 100 / 100
train mean loss=0.399539747416, accuracy=0.824081227461
 test mean loss=0.466326575726, accuracy=0.775624996424
learning rate:  6.44846109465e-05
save the model
save the optimizer

abschließend

Ich habe versucht, Dokumente (positive / negative Klassifizierung) über ein Faltungsnetzwerk zu klassifizieren. Es war ein einfaches Modell, aber es scheint eine gewisse Genauigkeit zu haben.

Als nächstes habe ich auch das Modell von Yoon Kim mit chainer implementiert Ich werde einen Artikel posten.

References

Recommended Posts

[Chainer] Dokumentklassifizierung nach Faltungsnetzwerk
Implementieren Sie das Convolutional Neural Network
Erfahrung mit faltbaren neuronalen Netzen
Rank Learning über ein neuronales Netzwerk (RankNet-Implementierung von Chainer)
Bildklassifizierung mit selbst erstelltem neuronalen Netzwerk von Keras und PyTorch
[Deep Learning] Bildklassifizierung mit Faltungsnetz [DW Tag 4]
Einfache Implementierung eines neuronalen Netzwerks mit Chainer
Einfaches Klassifizierungsmodell mit neuronalem Netz
Was ist das Convolutional Neural Network?
[Textklassifizierung] Ich habe versucht, Faltungsneurale Netze für die Satzklassifizierung mit Chainer zu implementieren
Versuchen Sie es mit TensorFlow-Part 2-Convolution Neural Network (MNIST).
Implementierung von "verschwommenen" neuronalen Netzen mit Chainer
Eine andere Stilkonvertierungsmethode unter Verwendung des Convolutional Neural Network
Erkennung handgeschriebener Zahlen durch ein mehrschichtiges neuronales Netzwerk
Parametrisches neuronales Netzwerk
Übersicht über DNC (Differentiable Neural Computers) + Implementierung durch Chainer
Modell unter Verwendung eines Faltungsnetzwerks in der Verarbeitung natürlicher Sprache
Bayesianische Optimierungsimplementierung von Hyperparametern des neuronalen Netzwerks (Chainer + GPyOpt)
Implementieren Sie ein vorwärts gerichtetes neuronales Netzwerk in Chainer, um Dokumente zu klassifizieren
Implementierung eines Faltungs-Neuronalen Netzwerks mit nur Numpy
Stilkonvertierung durch neuronalen Stil
Implementieren Sie das neuronale Netzwerk von Grund auf neu
Aufbau eines neuronalen Netzwerks, das XOR durch Z3 reproduziert
CNN Acceleration Series ~ FCNN: Einführung des Fourier Convolutional Neural Network ~
Untersuchung des wiederkehrenden neuronalen Netzes (RNN) durch Chainer ~ Überprüfung der Genauigkeit von Zufallszahlen in Excel und R ~