[PYTHON] Lassen Sie uns die Emotionen von Tweet mit Chainer (1.) analysieren.

Korrekturgeschichte

** 18.07.2016: Korrigiert, weil nach dem Filtern ein Fehler in der Größenberechnungsformel aufgetreten ist. ** ** **

Überblick

In den letzten Jahren haben KI, tiefes Lernen usw. an verschiedenen Orten Lärm gemacht. Ich denke, dass die Anzahl der Bibliotheken gestiegen ist und die Atmosphäre leichter zu testen ist. Daher werde ich versuchen, die Emotionen von Tweet mit Chainer zu analysieren. Machen wir etwas Ähnliches mit Chainer, während wir uns auf [Artikel über Theano] beziehen (http://qiita.com/hogefugabar/items/93fcb2bc27d7b268cbe6).

Wenn Sie jedoch an Bibliotheken für maschinelles Lernen wie sklearn gewöhnt sind, ist die Verwendung etwas schwierig. Wenn Sie dies also auch lösen können.

Da es mein eigenes Verständnis enthält, kann es Fehler geben, aber ich würde es begrüßen, wenn Sie darauf hinweisen könnten.

Inhalt des ersten

Umgebung

Mac OSX Yosemite 10.10.15 Python 2.7 CPU Intel Core i5 2.6GHz Speicher 8 GB

(Ist es mit solchen Geräten in Ordnung? → Ich weiß es nicht)

Vorbereitung

Installation der Kette

pip install chainer

sklearn und Chainer

In sklearn

model = (SVM oder Random Forest)
model.fit(x_train,y_train)
y_p = model.predict(x_test)

Es war einfach zu machen.

Wobei x_train eine Matrix der Größe $ N x M $ ist und y_train ein Lehrervektor der Länge $ N $ ist (wie z. B. 0,1). $ N $ ist die Stichprobengröße und $ M $ ist die Anzahl der Features. x_test sind die Testdaten mit der gleichen Anzahl von Spalten (dh der gleichen Größe von Features) wie x_train.

Auf der anderen Seite hat Chainer keine Methoden wie "fit" und "vorhersagen" wie diese, Sie müssen es selbst machen.

Beispielsweise scheint es in mehrschichtigem Perceptron (MLP) wie folgt [implementiert] zu werden (http://qiita.com/lucidfrontier45/items/0568d0d9e2c125e72734).

Basisklasse wie folgt

# -*- coding: utf-8 -*-

from chainer import FunctionSet, Variable, optimizers
from chainer import functions as F
from sklearn import base
from abc import ABCMeta, abstractmethod
import numpy as np
import six


class BaseChainerEstimator(base.BaseEstimator):
    __metaclass__= ABCMeta  # python 2.x
    def __init__(self, optimizer=optimizers.SGD(), n_iter=10000, eps=1e-5, report=100,
                 **params):
        self.network = self._setup_network(**params)
        self.optimizer = optimizer
        self.optimizer.setup(self.network.collect_parameters())
        self.n_iter = n_iter
        self.eps = eps
        self.report = report

    @abstractmethod
    def _setup_network(self, **params):
        return FunctionSet(l1=F.Linear(1, 1))

    @abstractmethod
    def forward(self, x, train=True):
        y = self.network.l1(x)
        return y

    @abstractmethod
    def loss_func(self, y, t):
        return F.mean_squared_error(y, t)

    @abstractmethod
    def output_func(self, h):
        return F.identity(h)

    def fit(self, x_data, y_data):
        batchsize = 100
        N = len(y_data)
        for loop in range(self.n_iter):
            perm = np.random.permutation(N)
            sum_accuracy = 0
            sum_loss = 0
            for i in six.moves.range(0, N, batchsize):
                x_batch = x_data[perm[i:i + batchsize]]
                y_batch = y_data[perm[i:i + batchsize]]
                x = Variable(x_batch)
                y = Variable(y_batch)
                self.optimizer.zero_grads()
                yp = self.forward(x)
                loss = self.loss_func(yp,y)
                loss.backward()
                self.optimizer.update()
                sum_loss += loss.data * len(y_batch)
                sum_accuracy += F.accuracy(yp,y).data * len(y_batch)
            if self.report > 0 and loop % self.report == 0:
                print('loop={}, train mean loss={} , train mean accuracy={}'.format(loop, sum_loss / N,sum_accuracy / N))

        return self

    def predict(self, x_data):
        x = Variable(x_data)
        y = self.forward(x,train=False)
        return self.output_func(y).data

class ChainerClassifier(BaseChainerEstimator, base.ClassifierMixin):
    def predict(self, x_data):
        return BaseChainerEstimator.predict(self, x_data).argmax(1) #argmax gibt den größten Index in der Zeile der Matrix zurück. Das heißt, die Klasse ist 0 zu 1,Muss 2 sein

    def predict_proba(self,x_data):
        return BaseChainerEstimator.predict(self, x_data)

Darüber hinaus werden MLP-Klassen von ChainerClassifier geerbt.

class MLP3L(ChainerClassifier):
    """
    3-Layer Perceptron
    """
    def _setup_network(self, **params):
        network = FunctionSet(
            l1=F.Linear(params["input_dim"], params["hidden_dim"]),
            l2=F.Linear(params["hidden_dim"], params["hidden_dim"]),
            l3=F.Linear(params["hidden_dim"], params["n_classes"]),
        )
        return network

    def forward(self, x, train=True):
        h1 = F.dropout(F.relu(self.network.l1(x)),train=train)
        h2 = F.dropout(F.relu(self.network.l2(h1)),train=train)
        y = self.network.l3(h2)
        return y

    def loss_func(self, y, t):
        return F.softmax_cross_entropy(y, t)

    def output_func(self, h):
        return F.softmax(h)

Implementieren.

Jetzt können Sie "fit" und "Predict (Predict_Proba)" genau wie sklearn verwenden.

Es scheint, dass x_data vom Typ numpy.float32 und y_data vom Typ numpy.int32 sein muss. (Auf die variable Innenanpassung von Chainer gegossen)

Im Fall des obigen MLP können die obigen x_data eine Matrix der Größe $ N × M $ wie sklearn sein. Wenn Sie jedoch versuchen, dies beispielsweise auf ein Faltungsnetzwerk (CNN) auszudehnen, treten plötzlich Probleme auf.

Da CNN hauptsächlich in der Bildverarbeitung verwendet wird, ist die Eingabe zweidimensional. Wenn Sie die Stapelgröße (Stichprobengröße) hinzufügen, müssen Sie sie dreidimensional x_data erstellen. (Es gibt ein Konzept von Kanal? Und es ist tatsächlich ein 4-dimensionaler Tensor)

Dekodieren Sie CNN-Samples in Chainer.

Ich habe den Code von hier als Beispiel verwendet.

Das von mir verwendete MNIST-Bild ist $ 28 x 28 $.

model = chainer.FunctionSet(conv1=F.Convolution2D(1, 20, 5),
								conv2=F.Convolution2D(20, 50, 5),  
                            l1=F.Linear(800, 500),
                            l2=F.Linear(500, 10))
                            
def forward(x_data, y_data, train=True):
    x, t = chainer.Variable(x_data), chainer.Variable(y_data)
    h = F.max_pooling_2d(F.relu(model.conv1(x)), 2)
    h = F.max_pooling_2d(F.relu(model.conv2(h)), 2)
    h = F.dropout(F.relu(model.l1(h)), train=train)
    y = model.l2(h)
    if train:
        return F.softmax_cross_entropy(y, t)
    else:
        return F.accuracy(y, t)                                                        

Mit Blick auf die Referenz von F.Convolution2D,

Kobito.SCEMO4.png

Das erste Argument ist in_channels, das zweite Argument ist out_channels und das dritte Argument ist ksize (Filtergröße). Es scheint, dass in_channels mit RGB auf 3 gesetzt ist, aber ich versuche es mit 1, und out_channels ist die Anzahl der Ausgabekanäle, aber vielleicht werden 20 Arten von Bildern mit verschiedenen Filtern erstellt? Ich verstehe es ohne Erlaubnis. Da ksize 5 ist, bedeutet dies, dass der Filter ein $ 5 x 5 $ Filter ist.

Feature-Größe nach dem Falten und Pooling

(Korrigiert am 18. Juli 2016 von hier)

~~ Wenn im Faltungsprozess die Filtergröße $ F $ und die Bildgröße $ S × S $ beträgt, beträgt die Bildgröße nach dem Filtern $ S_f × S_f $, wenn keine Auffüllung enthalten ist. Laut Artikel ~~

S_f = S - 2 × [F/2]

Es wird ~~. $ [] $ Wird nach dem Dezimalpunkt abgeschnitten. ~~

** Anscheinend sieht es anders aus, wenn ich es versuche, oder besser gesagt, es wurde in Chainers Dokument geschrieben. ** ** **

S_f = S - F + 1

Es ist in Ordnung. Es ist das gleiche wie der gleitende Durchschnitt, nicht wahr? Die vorherige Formel funktioniert gut für ungerade Filtergrößen, aber nicht für gerade.

Im Pooling-Prozess unterscheidet sich die Kantenverarbeitung je nachdem, ob Max Pooling oder Average Pooling verwendet wird. Wie ich versucht habe, kann das durchschnittliche Pooling nicht berechnen, ob nach dem Teilen der Zielgröße durch die Pooling-Größe ein Rest vorhanden ist, das maximale Pooling jedoch. Daher müssen Sie in diesem Bereich vorsichtig sein.

(Korrektur am 18.7.2016 bisher)

Mit anderen Worten, in diesem Beispiel

In der ersten Falte

S_{f1} = 28 - 2 × [5/2] = 24

Da das maximale Pooling in der Vorwärtsfunktion ausgeführt wird, wird die Größe nach dem Pooling auf $ S_ {p1} x S_ {p1} $ festgelegt.

S_{p1} = 24 / 2 = 12

Also in der zweiten Faltung

S_{f2} = 12 - 2 × [5/2] = 8

Das maximale Pooling wird also in der Vorwärtsfunktion durchgeführt, sodass die Größe nach dem Pooling $ S_ {p2} x S_ {p2} $ beträgt.

S_{p2} = 8 / 2 = 4

Es wird sein.

Mit anderen Worten, die Dimension des Merkmalsbetrags, der zur endgültigen Eingabe wird, besteht darin, dass die Anzahl der Ausgaben 50 beträgt

M = 50 × 4 × 4 = 800

Und die erste Schicht

l1=F.Linear(800, 500)

Entspricht dem ersten Argument von. (Chainer scheint Ihnen die richtige Antwort zu geben, wenn Sie einen Fehler machen)

Vorbereitung vor dem Vorwärtswerfen

Nun, nachdem ich das Modell definiert habe, werfe ich x_data in die Vorwärtsfunktion, aber es gibt immer noch ein Problem, und wenn ich Convolution mache, muss ich einen 4D-Tensor aus der folgenden Referenz werfen. (Siehe x in Parameter)

Kobito.sKeAcV.png

$ n $ ist die Stapelgröße (Stichprobengröße), $ c_I $ ist die Anzahl der Kanäle und $ h $ und $ w $ sind die vertikalen und horizontalen Größen des Bildes.

Mit Blick auf den obigen Beispielcode wird er unter Verwendung der unten gezeigten Umformung in einen 4-dimensionalen Tensor konvertiert.

X_train = X_train.reshape((len(X_train), 1, 28, 28))

Dieses Mal wollte ich den Status des Variablentyps ändern, und als ich ihn nachschlug, wurde dasselbe als Chainer-Funktion definiert.

Kobito.StweJ1.png

Benutze das.

nächstes Mal

Recommended Posts

Lassen Sie uns die Emotionen von Tweet mit Chainer (1.) analysieren.
Lassen Sie uns die Emotionen von Tweet mit Chainer (2.) analysieren.
Holen Sie sich den Titel der Yahoo News und analysieren Sie die Stimmung
Lassen Sie uns die Daten der Fragebogenumfrage analysieren [4 .: Emotionsanalyse]
Lassen Sie uns den Gewinner des Bingo bestimmen
Informationen zum Verhalten von enable_backprop von Chainer v2
Implementierung eines Dialogsystems mit Chainer [seq2seq]
Tweet mit der Twitter-API in Python
[Bash] Lassen Sie uns jetzt die Gabelbombe analysieren
Implementierung von "verschwommenen" neuronalen Netzen mit Chainer
Untersuchen wir den Mechanismus von Kaijis Chinchirorin
Verkürzung der Analysezeit von Openpose mithilfe von Sound
Abschätzung der Wirkung von Maßnahmen anhand von Neigungswerten
Überprüfen Sie den Typ der von Ihnen verwendeten Variablen
[Python] Lassen Sie uns das Modul regelmäßig nach Zeitplan ausführen
Exklusive Veröffentlichung der Django App mit ngrok
Signate_ Rückblick auf den 1. Beginner Limited Competition
Versuchen Sie es mit dem Sammlungsmodul (ChainMap) von python3
Emotionale Analyse umfangreicher Tweet-Daten durch NLTK
Bestimmen Sie die Anzahl der Klassen mithilfe der Starges-Formel
Überprüfen Sie den Status der Daten mit pandas_profiling
Scraping der Gewinndaten von Zahlen mit Docker
Erklären des auf der PyCon 2016 angekündigten Chat-Bots aus der Codebasis (Chat-Antwort mit Chainer)