Jusqu'à précédent, je n'ai appris qu'une entrée et une sortie de sin like angle (theta), mais cette fois, j'ai appris seulement 1 entrée et 1 sortie de sin et cos. Je voudrais apprendre 2 entrées et 1 sortie.
Apprenez l'angle (thêta) à partir de sin et cos (0-2π).
[training data]
Données d'entraînement
def get_dataset(N):
theta = np.linspace(0, 2 * np.pi, N)
sin = np.sin(theta)
cos = np.cos(theta)
x = np.c_[sin, cos]
y = theta
return x, y
Étant donné que le nombre d'unités dans la couche d'entrée (in_units) et la couche de sortie (out_units) est défini, la polyvalence est légèrement augmentée par rapport au code précédent.
Apprentissage par lots
class MyChain(Chain):
def __init__(self, in_units=1, n_units=10, out_units=1):
super(MyChain, self).__init__(
l1=L.Linear(in_units, n_units),
l2=L.Linear(n_units, n_units),
l3=L.Linear(n_units, out_units))
self.in_units = in_units
self.out_units = out_units
Tous les paramètres sont appropriés.
L'ensemble
# -*- coding: utf-8 -*-
#Importer depuis une extrémité pour le moment
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
#Les données
def get_dataset(N):
theta = np.linspace(0, 2 * np.pi, N)
sin = np.sin(theta)
cos = np.cos(theta)
x = np.c_[sin, cos]
y = theta
return x, y
#réseau neuronal
class MyChain(Chain):
def __init__(self, in_units=1, n_units=10, out_units=1):
super(MyChain, self).__init__(
l1=L.Linear(in_units, n_units),
l2=L.Linear(n_units, n_units),
l3=L.Linear(n_units, out_units))
self.in_units = in_units
self.out_units = out_units
def __call__(self, x_data, y_data):
x = Variable(x_data.astype(np.float32).reshape(len(x_data),self.in_units)) #Convertir en objet variable
y = Variable(y_data.astype(np.float32).reshape(len(y_data),self.out_units)) #Convertir en objet variable
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),self.in_units))).data
# main
if __name__ == "__main__":
#Données d'entraînement
N = 1000
x_train, y_train = get_dataset(N)
#données de test
N_test = 900
x_test, y_test = get_dataset(N_test)
#Paramètres d'apprentissage
batchsize = 10
n_epoch = 500
in_units = 2
n_units = 100
out_units = 1
#La modélisation
model = MyChain(in_units, n_units, out_units)
optimizer = optimizers.Adam()
optimizer.setup(model)
#Boucle d'apprentissage
print "start..."
train_losses =[]
test_losses =[]
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)
#Processus d'apprentissage des extrants
if epoch % 10 == 0:
print "epoch: {}/{} train loss: {} test loss: {}".format(epoch, n_epoch, average_loss, loss.data)
interval = int(time.time() - start_time)
print "Temps d'exécution(normal): {}sec".format(interval)
print "end"
#Graphique d'erreur
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.show()
#Créer un graphique des résultats d'apprentissage
sin, cos = np.hsplit(x_test ,in_units)
theta = y_test
test = model.get_predata(x_test)
plt.subplot(3, 1, 1)
plt.plot(theta, sin, "b", label = "sin")
plt.legend(loc = "upper left")
plt.grid(True)
plt.xlim(0, 2 * np.pi)
plt.ylim(-1.2, 1.2)
plt.subplot(3, 1, 2)
plt.plot(theta, cos, "g", label = "cos")
plt.legend(loc = "upper left")
plt.grid(True)
plt.xlim(0, 2 * np.pi)
plt.ylim(-1.2, 1.2)
plt.subplot(3, 1, 3)
plt.plot(theta, theta, "r", label = "theta")
plt.plot(theta, test, "c", label = "test")
plt.legend(loc = "upper left")
plt.grid(True)
plt.xlim(0, 2 * np.pi)
plt.ylim(-0.5, 7)
plt.tight_layout()
plt.show()
Si le nombre d'époques est de 500, l'erreur est importante. De plus, étant donné que le degré de diminution de l'erreur devient saturé, il est peu probable que l'on puisse s'attendre à une réduction supplémentaire à moins que le nombre d'époques ne soit significativement augmenté.
Étant donné que la sortie est linéaire, elle ne semble pas avoir d'erreur importante.
J'ai également confirmé le cas où les entrées sin et cos ont été multipliées par le transporteur. (3 entrées et 1 sortie avec porteuse) C'est le même principe que le résolveur qui détecte l'angle du moteur.
Données d'entraînement avec transporteur
def get_dataset(N):
theta = np.linspace(0, 2 * np.pi, N)
ref = np.sin(40 * theta) #Transporteur
sin = np.sin(theta) * ref
cos = np.cos(theta) * ref
x = np.c_[sin, cos, ref]
y = theta
return x, y
# in_Changer les unités en 3
Il peut être confirmé que l'erreur est importante même en apparence car la saisie est compliquée. Les composants harmoniques restent.
Bien que l'erreur soit importante, j'ai pu apprendre l'angle de sin et cos. (2 entrées et 1 sortie) Nous avons également pu apprendre l'angle de la forme d'onde du résolveur multiplié par la porteuse. Cependant, une composante harmonique a été générée. Ce n'était pas un gros problème, alors j'ai pensé que je pourrais apprendre plus précisément, mais j'ai été surpris que l'erreur soit importante. Dans le futur, je veux apprendre des contenus plus compliqués, pour pouvoir penser à l'avenir ...
Recommended Posts