[PYTHON] Implementieren Sie ein vorwärts gerichtetes neuronales Netzwerk in Chainer, um Dokumente zu klassifizieren

Einführung

Kürzlich habe ich versucht, einen binären Klassifikator zu implementieren, der das Positive und Negative eines Dokuments mit Chainer beurteilt, was ein heißes Thema ist. Da ich Chainer zum ersten Mal verwendet habe, ist es ein einfaches Modell, weil es zum Üben dient. Für diejenigen, die mit Chainer ein tiefes neuronales Netz implementieren und so etwas wie den Autor tun möchten.

Es wäre hilfreich, wenn Sie im Kommentarbereich auf Fehler hinweisen könnten.

Den vollständigen Code finden Sie unter hier.

Vorbereitungen

--Installation von Chainer, Gensim, Scikit-Learn

Umgebung

Beispiel für zu verwendende Daten

Die verwendeten Daten sind ein Dokument über eine Überprüfung von etwas in Englisch. Jede Zeile entspricht einem Dokument, und jedes Wort im Dokument ist durch ein Leerzeichen halber Breite getrennt. Die Nummer am Anfang jeder Zeile (z. B. 1, 0) ist die Bezeichnung.

0 each scene drags , underscoring the obvious , and sentiment is slathered on top . 0 afraid to pitch into farce , yet only half-hearted in its spy mechanics , all the queen's men is finally just one long drag . 1 clooney directs this film always keeping the balance between the fantastic and the believable . . . 1 just about the best straight-up , old-school horror film of the last 15 years .

Dokumentvektorisierung

Vektorisieren Sie mit einer Wortsammlung, um jedes Dokument als Eingabe in das neuronale Netzwerk zu behandeln. Für die Vektorisierung habe ich die Funktion von Gensim verwendet. Weitere Informationen finden Sie in diesem Artikel. → Klassifizieren Sie Nachrichtenartikel nach scikit-learn und gensim

Die Funktion load_data liest die Eingabedaten und teilt die Beschriftung und die Wortfolge jedes Dokuments durch l.strip (). Split (" ", 1). Die Dokumentbezeichnung wird in "Ziel" gespeichert, und der Dokumentvektor wird in "Quelle" gespeichert. Sie werden in "Datensatz" zusammengefasst und als Rückgabewert zurückgegeben.

corpora.Dictionary (document_list) erstellt ein Wortwörterbuch, indem eine Liste von Dokumentlisten (document_list) mit jedem Wort als Element übergeben wird. Ursprünglich musste ich ein Wortwörterbuch nur mit Trainingsdaten erstellen, aber ich wollte die unbekannte Textverarbeitung weglassen, also habe ich ein Wortwörterbuch mit allen Dokumenten erstellt.

Wobei vocab_size das Vokabular des gesamten Dokuments ist und der Anzahl der Dimensionen des Dokumentvektors entspricht. Daher ist die Anzahl der Einheiten in der Eingangsschicht des diesmal implementierten neuronalen Netzes gleich "vocab_size".

def load_data(fname):
    source = []
    target = []
    f = open(fname, "r")

    document_list = [] #Ein Dokument in jeder Zeile.Elemente im Dokument sind Wörter
    for l in f.readlines():
        sample = l.strip().split(" ", 1)        #Trennen Sie Beschriftungen und Wortketten
        label = int(sample[0])                  #Etikette
        target.append(label)
        document_list.append(sample[1].split()) #Wörter teilen und zur Dokumentenliste hinzufügen

    #Erstellen Sie ein Wortwörterbuch
    dictionary = corpora.Dictionary(document_list)
    dictionary.filter_extremes(no_below=5, no_above=0.8)
    # no_below:Das verwendete Dokument ist Nr_Ignoriere die folgenden Wörter
    # no_above:Der Prozentsatz der verwendeten Sätze ist nein_Oben ignorieren

    #Dokumentvektorisierung
    for document in document_list:
        tmp = dictionary.doc2bow(document) #BoW-Darstellung des Dokuments
        vec = list(matutils.corpus2dense([tmp], num_terms=len(dictionary)).T[0])
        source.append(vec)

    dataset = {}
    dataset['target'] = np.array(target)
    dataset['source'] = np.array(source)
    print "vocab size:", len(dictionary.items()) #Anzahl der Vokabeln=Anzahl der Einheiten in der Eingabeebene

    return dataset, dictionary

Modelldefinition

Diesmal war es zum Üben, also habe ich ein einfaches Modell implementiert. (Der von der vorherigen Funktion "load_data" empfangene "Datensatz" wird mithilfe der in scikit-learn enthaltenen Funktion "train_test_split" in Trainingsdaten und Testdaten unterteilt.)

Die Anzahl der Einheiten in der Eingabeebene "in_units" enthält die Anzahl der Dimensionen des Dokumentvektors ("x_train.shape [1]"). Die verborgene Ebene (Zwischenebene) kann entsprechend eingestellt werden. Dieses Mal versuche ich standardmäßig 500 zu übergeben. Da die Ausgabeebene die Softmax-Funktion verwendet, beträgt die Anzahl der Einheiten 2, dh die Anzahl der Etikettentypen.

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)

n_units = args.units #Anzahl der versteckten Ebeneneinheiten
n_label = 2          #Anzahl der Einheiten in der Ausgabeebene

#Modelldefinition
model = chainer.Chain(l1=L.Linear(in_units, n_units),
                      l2=L.Linear(n_units, n_units),
                      l3=L.Linear(n_units,  n_label))

Vorwärtsausbreitung

Die Funktion "vorwärts" führt eine Vorwärtsausbreitung durch. Eingabeebene-> versteckte Ebene, versteckte Ebene-> Aktivierungsfunktion für versteckte Ebene verwendete Sigmoid-Funktion.

def forward(x, t, train=True):
    h1 = F.sigmoid(model.l1(x))
    h2 = F.sigmoid(model.l2(h1))
    y = model.l3(h2)
    return F.softmax_cross_entropy(y, t), F.accuracy(y, t)

Lernen

Als Ganzes fließen

  1. Erstellen Sie einen Stapel aus Trainingsdaten
  2. Vorwärtsausbreitung
  3. Rückausbreitung des Fehlers
  4. Parameteraktualisierung Es ist wie es ist. (Ich bin nicht so zuversichtlich ...)

Jede Epoche berechnet den Fehler für Trainingsdaten und den Fehler für Testdaten. Da es sich um ein Klassifizierungsproblem handelt, wird auch die Klassifizierungsgenauigkeitsrate "Genauigkeit" berechnet.

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

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

    print 'epoch', 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

        model.zerograds()            #Nullinitialisierung des Gradienten
        loss, acc = forward(x, t)    #Vorwärtsausbreitung
        sum_train_loss      += float(cuda.to_cpu(loss.data)) * len(t)   #Zur durchschnittlichen Fehlerberechnung
        sum_train_accuracy  += float(cuda.to_cpu(acc.data )) * len(t)   #Zur Berechnung der durchschnittlichen Genauigkeitsrate
        loss.backward()              #Fehler bei der Weitergabe
        optimizer.update()           #Optimierung

    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, acc = forward(x, t, train=False)

        sum_test_loss     += float(cuda.to_cpu(loss.data)) * len(t)
        sum_test_accuracy += float(cuda.to_cpu(acc.data))  * len(t)

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

#Modell und Optimierer speichern
print 'save the model'
serializers.save_npz('pn_classifier_ffnn.model', model)
print 'save the optimizer'
serializers.save_npz('pn_classifier_ffnn.state', optimizer)

Ausführungsergebnis

Die Klassifizierungsgenauigkeitsrate für die endgültigen Testdaten betrug "Genauigkeit = 0,716875001788". Mit fortschreitendem Lernen nimmt jedoch der Testfehler zu und es kommt zu Überlernen ...

Wahrscheinlich wegen der Tatsache, dass das Modell endlich gebaut wurde.

>python train.py --gpu 1 --data input.dat --units 1000
vocab size: 4442
epoch 1
train mean loss=0.746377664579, accuracy=0.554684912523
 test mean loss=0.622971419245, accuracy=0.706875003874
epoch 2
train mean loss=0.50845754933, accuracy=0.759408453399
 test mean loss=0.503996372223, accuracy=0.761249992996
epoch 3
train mean loss=0.386604680468, accuracy=0.826067760105
 test mean loss=0.506066314876, accuracy=0.769374992698
epoch 4
train mean loss=0.301527346359, accuracy=0.870433726909
 test mean loss=0.553729468957, accuracy=0.774999994785
epoch 5
train mean loss=0.264981631757, accuracy=0.889085094432
 test mean loss=0.599407823756, accuracy=0.766874998808
epoch 6
train mean loss=0.231274759588, accuracy=0.901114668847
 test mean loss=0.68350501731, accuracy=0.755625002086

...

epoch 95
train mean loss=0.0158744356008, accuracy=0.993598945303
 test mean loss=5.08019682765, accuracy=0.717499997467
epoch 96
train mean loss=0.0149783944279, accuracy=0.994261124581
 test mean loss=5.30629962683, accuracy=0.723749995232
epoch 97
train mean loss=0.00772037562047, accuracy=0.997351288256
 test mean loss=5.49559159577, accuracy=0.720624998212
epoch 98
train mean loss=0.00569957431572, accuracy=0.99834455516
 test mean loss=5.67661693692, accuracy=0.716875001788
epoch 99
train mean loss=0.00772406136085, accuracy=0.997240925267
 test mean loss=5.63734056056, accuracy=0.720000002533
epoch 100
train mean loss=0.0125463016702, accuracy=0.995916569395
 test mean loss=5.23713605106, accuracy=0.716875001788
save the model
save the optimizer

abschließend

Ich habe Chainer verwendet, um ein Feedforward-Neuronales Netzwerk für die Klassifizierung von Dokumenten zu implementieren. Ich möchte das Modell verbessern, damit es nicht zu Übertraining kommt.

Wenn Sie den Code für das Studium von Chainer sehen möchten, lesen Sie bitte hier.

Referenzseite

Recommended Posts

Implementieren Sie ein vorwärts gerichtetes neuronales Netzwerk in Chainer, um Dokumente zu klassifizieren
Neuronales Netzwerk zum Verstehen und Implementieren in der Mathematik der High School
Implementieren Sie das Convolutional Neural Network
Implementieren Sie das neuronale Netzwerk von Grund auf neu
Implementieren Sie ein dreischichtiges neuronales Netzwerk
Neuronales Netz beginnend mit Chainer
Implementierung eines neuronalen Netzwerks in Python
Ich habe versucht, das grundlegende Modell des wiederkehrenden neuronalen Netzwerks zu implementieren
Ich habe versucht, Musik im Neural Network in Dur / Moll zu klassifizieren
Einfache Implementierung eines neuronalen Netzwerks mit Chainer
[Deep Learning von Grund auf neu] Informationen zu den Ebenen, die für die Implementierung der Backpropagation-Verarbeitung in einem neuronalen Netzwerk erforderlich sind
Ich habe versucht, PLSA in Python zu implementieren
Ich habe versucht, PLSA in Python 2 zu implementieren
So implementieren Sie einen verschachtelten Serializer mit drf-flex-Feldern
Ich habe versucht, ADALINE in Python zu implementieren
Ich habe versucht, PPO in Python zu implementieren
Implementierung von "verschwommenen" neuronalen Netzen mit Chainer
[Chainer] Dokumentklassifizierung nach Faltungsnetzwerk
Versuchen Sie, Oni Mai Tsuji Miserable mit Python zu implementieren
So implementieren Sie Rails-Helfer-ähnliche Funktionen in Django
So implementieren Sie Shared Memory in Python (mmap.mmap)
So implementieren Sie eine Verlaufsauswahl in Houdini
Ich habe versucht, TOPIC MODEL in Python zu implementieren
So erstellen Sie Daten für CNN (Chainer)
Ich habe versucht, eine selektive Sortierung in Python zu implementieren