Ich möchte das Recurrent Neural Network (RNN) studieren, das ich mir nicht leisten konnte. Grundsätzlich handelt es sich um eine Form der Vorhersage mithilfe der rekursiven Verarbeitung mit LSTM. Einige Dinge stehen jedoch noch kurz vor dem Kopieren. Daher verstehe ich sie nicht vollständig. Bitte weisen Sie auf Fehler usw. hin. Ich möchte, dass.
Ein Beispiel für die Implementierung von RNN + LSTM in Chainer habe ich auf Chainers Beispiel verwiesen. Da es jedoch so ist, passt es nicht in das Framework, das ich bisher erstellt habe, also habe ich einige Verarbeitungen durchgeführt. Die Erklärung des obigen Codes wurde in hier detailliert beschrieben. Ich habe auch ein grobes Verständnis von RNN und LSTM in dem kürzlich erschienenen Buch.
Es ist nicht interessant, das Sample so zu verschieben, wie es ist. Stellen wir also das Problem ein.
Wie in der Praxis gesagt wurde, beträgt die Periode der Zufallszahlen, die mit der Rand () - Funktion von Excel erstellt wurden, $ 2 ^ {24} $, und es ist bekannt, dass die Periode kürzer ist als bei anderen Zufallszahlen. Wenn Sie in Monte Carlo Excel-Zufallszahlen verwenden, sind die Ergebnisse daher verzerrt. (Nun, es kann gut sein, wenn die Anzahl der Proben gering ist)
Andererseits ist die Zufallszahl von R eine Zufallszahl mit einer sehr langen Periode ($ 2 ^ {19937} $), die von einem Algorithmus namens [Mersenne Twister](https://ja.wikipedia.org/wiki/Mersenne Twister) erstellt wurde. Ich bin.
Mit anderen Worten, wenn es Periodizität gibt, kann es möglich sein, den nächsten Zufallszahlenwert vorherzusagen, indem sequentielles Lernen unter Verwendung von RNN durchgeführt wird. Das ist das Bewusstsein für das Problem.
Ich bin kein Experte für Zufallszahlen, daher bin ich mir nicht sicher, ob die Bewertungsmethode korrekt ist.
Zunächst werden Excel-Zufallszahlen mit der Rand-Funktion berechnet.
=ROUNDDOWN(RAND()*10,0)
Bereiten Sie 1001 Stück vor. Dann erhalten Sie 10 ganzzahlige Werte von 0-9.
Als nächstes erzeugt die Zufallszahl von R eine einheitliche Zufallszahl wie folgt.
x <- floor(runif(1001)*10);
(Der Wert 1001 ist ein Extra, um die Antwortdaten zum nächsten Wert zu machen.)
Die erklärende Variable ist der aktuelle Zufallswert (0-9) und die Lehrerdaten sind der nächste Zufallswert (0-9).
RNN wurde unter Verwendung von Chainer wie folgt implementiert. Da es sich um einen sequentiellen Prozess handelt, setzen wir die Chargengröße absichtlich auf 1 und verarbeiten sie von Anfang an in der richtigen Reihenfolge.
Erstens ist die Basisklasse wie folgt.
DL_chainer.py
# -*- coding: utf-8 -*-
from chainer import FunctionSet, Variable, optimizers,serializers
from chainer import functions as F
from chainer import links as L
from sklearn import base
from sklearn.cross_validation import train_test_split
from abc import ABCMeta, abstractmethod
import numpy as np
import six
import math
import cPickle as pickle
class BaseChainerEstimator(base.BaseEstimator):
__metaclass__= ABCMeta # python 2.x
def __init__(self, optimizer=optimizers.MomentumSGD(lr=0.01), n_iter=10000, eps=1e-5, report=100,
**params):
self.report = report
self.n_iter = n_iter
self.batch_size = params["batch_size"] if params.has_key("batch_size") else 100
self.network = self._setup_network(**params)
self.decay = 1.
self.optimizer = optimizer
self.optimizer.setup(self.network.collect_parameters())
self.eps = eps
np.random.seed(123)
@abstractmethod
def _setup_network(self, **params):
return FunctionSet(l1=F.Linear(1, 1))
@abstractmethod
def forward(self, x,train=True,state=None):
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)
@abstractmethod
def fit(self, x_data, y_data):
batchsize = self.batch_size
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 + 1) % self.report == 0:
print('loop={:d}, train mean loss={:.6f} , train mean accuracy={:.6f}'.format(loop + 1, sum_loss / N,sum_accuracy / N))
self.optimizer.lr *= self.decay
return self
def predict(self, x_data):
x = Variable(x_data,volatile=True)
y = self.forward(x,train=False)
return self.output_func(y).data
def predict_proba(self, x_data):
x = Variable(x_data,volatile=True)
y = self.forward(x,train=False)
return self.output_func(y).data
def save_model(self,name):
with open(name,"wb") as o:
pickle.dump(self,o)
class ChainerClassifier(BaseChainerEstimator, base.ClassifierMixin):
def predict(self, x_data):
return BaseChainerEstimator.predict(self, x_data).argmax(1)
def predict_proba(self,x_data):
return BaseChainerEstimator.predict_proba(self, x_data)
Die folgende RNN-Implementierung sieht folgendermaßen aus:
DL_chainer.py
class RNNTS(ChainerClassifier):
"""
Recurrent Neurarl Network with LSTM by 1 step
"""
def _setup_network(self, **params):
self.input_dim = params["input_dim"]
self.hidden_dim = params["hidden_dim"]
self.n_classes = params["n_classes"]
self.optsize = params["optsize"] if params.has_key("optsize") else 30
self.batch_size = 1
self.dropout_ratio = params["dropout_ratio"] if params.has_key("dropout_ratio") else 0.5
network = FunctionSet(
l0 = L.Linear(self.input_dim, self.hidden_dim),
l1_x = L.Linear(self.hidden_dim, 4*self.hidden_dim),
l1_h = L.Linear(self.hidden_dim, 4*self.hidden_dim),
l2_h = L.Linear(self.hidden_dim, 4*self.hidden_dim),
l2_x = L.Linear(self.hidden_dim, 4*self.hidden_dim),
l3 = L.Linear(self.hidden_dim, self.n_classes),
)
return network
def forward(self, x, train=True,state=None):
if state is None:
state = self.make_initial_state(train)
h0 = self.network.l0(x)
h1_in = self.network.l1_x(F.dropout(h0, ratio=self.dropout_ratio, train=train)) + self.network.l1_h(state['h1'])
c1, h1 = F.lstm(state['c1'], h1_in)
h2_in = self.network.l2_x(F.dropout(h1, ratio=self.dropout_ratio, train=train)) + self.network.l2_h(state['h2'])
c2, h2 = F.lstm(state['c2'], h2_in)
y = self.network.l3(F.dropout(h2, ratio=self.dropout_ratio, train=train))
state = {'c1': c1, 'h1': h1, 'c2': c2, 'h2': h2}
return y,state
def make_initial_state(self,train=True):
return {name: Variable(np.zeros((self.batch_size, self.hidden_dim), dtype=np.float32),
volatile=not train)
for name in ('c1', 'h1', 'c2', 'h2')}
def fit(self, x_data, y_data):
batchsize = self.batch_size
N = len(y_data)
for loop in range(self.n_iter):
sum_accuracy = Variable(np.zeros((), dtype=np.float32))
sum_loss = Variable(np.zeros((), dtype=np.float32))
state = self.make_initial_state(train=True) #Erzeugung des Ausgangszustands
for i in six.moves.range(0, N, batchsize):
x_batch = x_data[i:i + batchsize]
y_batch = y_data[i:i + batchsize]
x = Variable(x_batch,volatile=False)
y = Variable(y_batch,volatile=False)
yp,state = self.forward(x,train=True,state=state)
loss = self.loss_func(yp,y)
accuracy = F.accuracy(yp,y)
sum_loss += loss
sum_accuracy += accuracy
if (i + 1) % self.optsize == 0:
self.optimizer.zero_grads()
sum_loss.backward()
sum_loss.unchain_backward()
self.optimizer.clip_grads(5)
self.optimizer.update()
if self.report > 0 and (loop + 1) % self.report == 0:
print('loop={:d}, train mean loss={:.6f} , train mean accuracy={:.6f}'.format(loop + 1, sum_loss.data / N,sum_accuracy.data / N))
self.optimizer.lr *= self.decay
return self
def output_func(self, h):
return F.softmax(h)
def loss_func(self, y, t):
return F.softmax_cross_entropy(y, t)
def predict_proba(self, x_data):
N = len(x_data)
state = self.make_initial_state(train=False)
y_list = []
for i in six.moves.range(0, N, self.batch_size):
x = Variable(x_data[i:i+self.batch_size],volatile=True)
y,state = self.forward(x,train=False,state=state)
y_list.append(y.data[0]) #batch size =Unterstützt nur 1
y = Variable(np.array(y_list),volatile=False)
return self.output_func(y).data
def predict(self, x_data):
return self.predict_proba(x_data).argmax(1)
Der Code, auf den fast verwiesen wird, wird übernommen.
Wenn Sie bisher schreiben, können Sie einfach den Hauptprozess schreiben,
main.py
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from DL_chainer import *
import warnings
from sklearn.metrics import classification_report
warnings.filterwarnings("ignore")
I_FILE_EXCEL="excelrand.csv"
I_FILE_R="RRandom.csv"
def main(file=""):
"""
Lernen und prognostizieren Sie Excel-Zufallszahlen mit RNN
:return:
"""
df0 = pd.read_csv(file)
N = len(df0)
x_all = df0.iloc[:,0]
y_all = []
y_all.extend(x_all)
y_all.extend([np.nan])
y_all = y_all[1:(N+1)]
x_all_array = np.reshape(np.array(x_all[0:(N-1)],dtype=np.float32),(len(x_all)-1,1))/10
y_all_array = np.reshape(np.array(y_all[0:(N-1)],dtype=np.int32),(len(x_all)-1))
train_n = 2 * N/3
x_train = x_all_array[0:train_n]
y_train = y_all_array[0:train_n]
x_test = x_all_array[train_n:]
y_test = y_all_array[train_n:]
params = {"input_dim":1,"hidden_dim":100,"n_classes":10,"dropout_ratio":0.5,"optsize":30}
print params
print len(x_train),len(x_test)
rnn = RNNTS(n_iter=200,report=1,**params)
rnn.fit(x_train,y_train)
pred = rnn.predict(x_train)
print classification_report(y_train,pred)
pred = rnn.predict(x_test)
print classification_report(y_test,pred)
if __name__ == '__main__':
main(I_FILE_R)
main(I_FILE_EXCEL)
Grundsätzlich handelt es sich um ein 10-Klassen-Klassifizierungsproblem.
Die Auswertung der Ergebnisse ist schwierig. Es wird davon ausgegangen, dass mit Testdaten mit einer kleinen Anzahl von Proben keine korrekte Bewertung erfolgen kann.
Das RNN-Lernen läuft grundsätzlich unabhängig davon ab, welche Zufallszahlenfolge verwendet wird. Daher habe ich mich entschlossen zu sehen, wie sich die Lerngeschwindigkeit bei gleicher Anzahl von Epochen unterscheidet.
Mit anderen Worten, in derselben Epoche interpretieren diejenigen, die genauer sind, dass die Daten ein Muster enthalten und dass sie "gelernt" wurden.
Als Zufallszahl ist es besser, dass es kein Muster gibt, daher ist es natürlich besser, dass diese Lerngeschwindigkeit langsam ist.
Das Ergebnis ist unten
Sie können sehen, dass die Lerngeschwindigkeit auf der Excel-Seite schneller ist als auf R. Mit anderen Worten, ich frage mich, ob R in Bezug auf die Qualität von Zufallszahlen besser ist. Eigentlich ist es besser, wenn das Lernen nicht voranschreitet.
Dieses Mal habe ich für das Üben von RNN die Implementierung ausprobiert und die Zufallszahlen von Excel und R gelernt. Unabhängig davon, ob die Ergebnisbewertungsmethode korrekt ist oder nicht, wurde festgestellt, dass das Lernen auf der Excel-Seite mit dieser Bewertungsmethode schneller voranschreitet und R als Zufallszahl besser ist.
Wahrscheinlich sind unzählige Zufallszahlenfolgen erforderlich, um eine genauere Überprüfung zu ermöglichen, aber aufgrund der Leistung des Computers habe ich ihn auf diesem Niveau gehalten.
Aber wie kann ich die Berechnung mit RNN beschleunigen?
Recommended Posts