[PYTHON] Confirmé la différence de présence ou d'absence de traitement aléatoire lors de l'apprentissage par mini-lots avec chainer

introduction

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.

environnement

contenu de l'étude

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]

la mise en oeuvre

Fixe ou aléatoire

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]]

Paramètres d'apprentissage

Tous les paramètres sont appropriés comme dans l'exemple.

Code entier

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()

Résultat d'exécution

Erreur

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.

sin_diff_order.png

Si vous mélangez toutes les données

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

sin_diff_order2.png

Résumé

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éférence

Réseau neuronal commençant par Chainer

Bases et pratique de la mise en œuvre du Deep Learning

Recommended Posts

Confirmé la différence de présence ou d'absence de traitement aléatoire lors de l'apprentissage par mini-lots avec chainer
Prédire la présence ou l'absence d'infidélité par l'apprentissage automatique
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
rsync Le comportement change en fonction de la présence ou de l'absence de la barre oblique de la source de copie
Recevez une liste des résultats du traitement parallèle en Python avec starmap
Comment la référence du tableau python change en fonction de la présence ou de l'absence d'indices
L'histoire de l'apprentissage profond avec TPU
Afficher le résultat du traitement de la géométrie en Python
À propos du comportement de la file d'attente pendant le traitement parallèle