Ein Anfänger im tiefen Lernen versuchte, die Sündenfunktion mit Chainer zu lernen. Als Anfänger fühlte ich mich nach dem Lesen von Deep Learning ein wenig verstanden, aber als ich mich entschied, diesen Artikel zu schreiben, war ich verzweifelt über mein geringes Verständnis. Das Erlernen der Sündenfunktion wurde von yuukiclass und vielen anderen durchgeführt, aber es ist nicht schlecht.
Lerne Sünde (Theta) aus Winkeln (Theta) von 0 bis 2π
[training data]
Dies ist der Implementierungsteil des Mini-Batch-Lernens. Dieser Code ist aus MNIST-Beispielen bekannt (einige Änderungen wie der Bereich). Dieses Mini-Batch-Lernen scheint beliebt zu sein.
Auszug aus dem Mini-Batch-Lernen
perm = np.random.permutation(N)
sum_loss = 0
for i in range(0, N, batchsize):
x_batch = x_train[perm[i:i + batchsize]]
y_batch = y_train[perm[i:i + batchsize]]
model.zerograds()
loss = model(x_batch,y_batch)
sum_loss += loss.data * batchsize
loss.backward()
optimizer.update()
Die Anzahl der Daten wird so geändert, dass sich der während des Tests verwendete Winkel von dem während des Trainings unterscheidet. Der Winkel wird geändert, indem 0 bis 2π während des Lernens in 1.000 und während des Testens 0 bis 2π in 900 geteilt werden.
Trainingsdaten&Auszug aus der Ergebnisbestätigung
#Trainingsdaten
N = 1000
x_train, y_train = get_dataset(N)
#Testdaten
N_test = 900
x_test, y_test = get_dataset(N_test)
'''
Kürzung
'''
# test
loss = model(x_test,y_test)
test_losses.append(loss.data)
Mini-Chargengröße: 10
Epoche (n_epoch): 500
Anzahl der versteckten Ebenen: 2
Anzahl der versteckten Ebeneneinheiten (n_Einheiten): 100
Aktivierungsfunktion: Normalisierte lineare Funktion (relu)
Schulabbrecher: Keine (0%)
Optimierung: Adam
Verlustfehlerfunktion: Mittlere quadratische Fehlerfunktion (mean_squared_error)
Alle Parameter sind angemessen.
Das ganze
# -*- coding: utf-8 -*-
#Vorerst von einem Ende importieren
import numpy as np
import chainer
from chainer import cuda, Function, gradient_check, Variable, optimizers, serializers, utils
from chainer import Link, Chain, ChainList
import chainer.functions as F
import chainer.links as L
import time
from matplotlib import pyplot as plt
#Daten
def get_dataset(N):
x = np.linspace(0, 2 * np.pi, N)
y = np.sin(x)
return x, y
#neurales Netzwerk
class MyChain(Chain):
def __init__(self, n_units=10):
super(MyChain, self).__init__(
l1=L.Linear(1, n_units),
l2=L.Linear(n_units, n_units),
l3=L.Linear(n_units, 1))
def __call__(self, x_data, y_data):
x = Variable(x_data.astype(np.float32).reshape(len(x_data),1)) #In variables Objekt konvertieren
y = Variable(y_data.astype(np.float32).reshape(len(y_data),1)) #In variables Objekt konvertieren
return F.mean_squared_error(self.predict(x), y)
def predict(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
h3 = self.l3(h2)
return h3
def get_predata(self, x):
return self.predict(Variable(x.astype(np.float32).reshape(len(x),1))).data
# main
if __name__ == "__main__":
#Trainingsdaten
N = 1000
x_train, y_train = get_dataset(N)
#Testdaten
N_test = 900
x_test, y_test = get_dataset(N_test)
#Lernparameter
batchsize = 10
n_epoch = 500
n_units = 100
#Modellieren
model = MyChain(n_units)
optimizer = optimizers.Adam()
optimizer.setup(model)
#Lernschleife
train_losses =[]
test_losses =[]
print "start..."
start_time = time.time()
for epoch in range(1, n_epoch + 1):
# training
perm = np.random.permutation(N)
sum_loss = 0
for i in range(0, N, batchsize):
x_batch = x_train[perm[i:i + batchsize]]
y_batch = y_train[perm[i:i + batchsize]]
model.zerograds()
loss = model(x_batch,y_batch)
sum_loss += loss.data * batchsize
loss.backward()
optimizer.update()
average_loss = sum_loss / N
train_losses.append(average_loss)
# test
loss = model(x_test,y_test)
test_losses.append(loss.data)
#Lernprozess ausgeben
if epoch % 10 == 0:
print "epoch: {}/{} train loss: {} test loss: {}".format(epoch, n_epoch, average_loss, loss.data)
#Erstellen eines Diagramms der Lernergebnisse
if epoch in [10, 500]:
theta = np.linspace(0, 2 * np.pi, N_test)
sin = np.sin(theta)
test = model.get_predata(theta)
plt.plot(theta, sin, label = "sin")
plt.plot(theta, test, label = "test")
plt.legend()
plt.grid(True)
plt.xlim(0, 2 * np.pi)
plt.ylim(-1.2, 1.2)
plt.title("sin")
plt.xlabel("theta")
plt.ylabel("amp")
plt.savefig("fig/fig_sin_epoch{}.png ".format(epoch)) #Angenommen, der Feigenordner existiert
plt.clf()
print "end"
interval = int(time.time() - start_time)
print "Ausführungszeit: {}sec".format(interval)
#Fehlergrafik
plt.plot(train_losses, label = "train_loss")
plt.plot(test_losses, label = "test_loss")
plt.yscale('log')
plt.legend()
plt.grid(True)
plt.title("loss")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.savefig("fig/fig_loss.png ") #Angenommen, der Feigenordner existiert
plt.clf()
Der Fehler nimmt tendenziell mit zunehmender Epoche (Anzahl der Lernvorgänge) ab. Es gab keinen signifikanten Unterschied zwischen Lern- und Testfehlern. Ich denke, dass der Fehler beim Testen etwas besser ist als beim Lernen, da die Methode zur Berechnung des Fehlers unterschiedlich ist.
Wenn die Epoche 10 ist, ist es schwer zu sagen, dass es sich um eine Sündenfunktion handelt, aber wenn das Lernen auf 500 fortschreitet, kommt es der Sündenfunktion ziemlich nahe.
epoch: 10
epoch: 500
Vorerst konnte ich die Sündenfunktion mit Chainer trainieren.
Aus irgendeinem Grund ist der Fehler jedoch umso größer, je größer der Winkel ist. Ich dachte, wenn die Reihenfolge der zu lernenden Winkel zufällig gewählt würde, könnte die Variation des Fehlers für jeden Winkel unterdrückt werden, aber es scheint anders zu sein. Es ist nicht gut verstanden.
Ich habe versucht, die Sündenfunktion mit Chainer zu approximieren (erneute Herausforderung)
Chainer und Deep Learning durch Funktionsnäherung gelernt
Neuronales Netzwerk vom Typ Regressive Forward Propagation mit Chainer
Recommended Posts