** 18.07.2016: Korrigiert, weil nach dem Filtern ein Fehler in der Größenberechnungsformel aufgetreten ist. ** ** **
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.
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)
pip install 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)
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,
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.
(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)
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)
$ 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.
Benutze das.
Recommended Posts