En apprentissage profond, il semble qu'il soit courant de mélanger au hasard les données d'entraînement du mini lot pour chaque époque, j'ai donc vérifié l'effet.
Vérifiez la différence entre les données d'entraînement par mini-lots fixes et les données d'entraînement par mini-lots aléatoires pour chaque époque. La formation est la même fonction de péché que dans J'ai essayé d'apprendre la fonction de péché avec chainer.
[training data]
Les données d'apprentissage du mini-lot sont commutées entre fixes et aléatoires. Le code fixe est le même que la technique souvent utilisée lors des tests.
Fixe ou aléatoire
perm = np.random.permutation(N)
sum_loss = 0
for i in range(0, N, batchsize):
if order == "fixed": #L'ordre d'apprentissage est fixe
x_batch = x_train[i:i + batchsize]
y_batch = y_train[i:i + batchsize]
elif order == "random": #Ordre aléatoire d'apprentissage
x_batch = x_train[perm[i:i + batchsize]]
y_batch = y_train[perm[i:i + batchsize]]
Tous les paramètres sont appropriés comme dans l'exemple.
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):
x = np.linspace(0, 2 * np.pi, N)
y = np.sin(x)
return x, y
#réseau neuronal
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)) #Convertir en objet variable
y = Variable(y_data.astype(np.float32).reshape(len(y_data),1)) #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),1))).data
# main
if __name__ == "__main__":
#Données d'entraînement
N = 1000
x_train, y_train = get_dataset(N)
#Paramètres d'apprentissage
batchsize = 10
n_epoch = 500
n_units = 100
#Boucle d'apprentissage
fixed_losses =[]
random_losses =[]
print "start..."
for order in ["fixed", "random"]:
#La modélisation
model = MyChain(n_units)
optimizer = optimizers.Adam()
optimizer.setup(model)
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):
if order == "fixed": #L'ordre d'apprentissage est fixe
x_batch = x_train[i:i + batchsize]
y_batch = y_train[i:i + batchsize]
elif order == "random": #Ordre aléatoire d'apprentissage
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
if order == "fixed":
fixed_losses.append(average_loss)
elif order == "random":
random_losses.append(average_loss)
#Processus d'apprentissage des extrants
if epoch % 10 == 0:
print "({}) epoch: {}/{} loss: {}".format(order, epoch, n_epoch, average_loss)
interval = int(time.time() - start_time)
print "Temps d'exécution({}): {}sec".format(order, interval)
print "end"
#Graphique d'erreur
plt.plot(fixed_losses, label = "fixed_loss")
plt.plot(random_losses, label = "random_loss")
plt.yscale('log')
plt.legend()
plt.grid(True)
plt.title("loss")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.show()
Il y avait une différence d'environ 10 fois dans l'erreur entre le temps fixe et le temps aléatoire. Il vaut mieux le rendre aléatoire en fonction de la réputation précédente.
Nous avons également confirmé le cas où toutes les données d'entraînement étaient mélangées au hasard. Lorsque toutes les données d'entraînement étaient mélangées au hasard, le résultat était comparable à celui au hasard une fois fixé. Au contraire, la variation pour chaque époque est meilleure lorsqu'elle est fixée.
Données entières aléatoires
def get_dataset(N):
x = 2 * np.pi * np.random.random(N)
y = np.sin(x)
return x, y
Lors de l'apprentissage de la fonction sin, l'erreur est environ 10 fois meilleure que lorsque les données d'apprentissage du mini-lot ne sont pas mélangées au hasard pour chaque époque. Cependant, la randomisation de l'ensemble des données d'entraînement a donné de bons résultats dans les deux cas.
Cela peut être limité à des conditions spécifiques telles que la fonction sin, mais il vaut également la peine d'essayer une méthode de mélange aléatoire de toutes les données et de correction des données d'apprentissage du mini-lot.
Réseau neuronal commençant par Chainer
Bases et pratique de la mise en œuvre du Deep Learning
Recommended Posts