2017-01-27 5 views
1

Je suis la formation d'une couche multi Perceptron (MLP) (avec les options par défaut) dans scikit-learn en utilisant la fonction partial_fit(X,y) et je remarque qu'il ya une différence entre l'appelfonction partial_fit dans sklearn Multi Layer Perceptron

partial_fit([X1],[y1]) 
partial_fit([X2],[y2]) 

et

partial_fit([X1,X2],[y1,y2]) 

La deuxième option semble plus rapide mais le résultat semble pire. Quelqu'un peut-il m'expliquer ce qui se passe?

Répondre

0

Il est un peu difficile de répondre à la question sans un exemple minimal et reproductible, mais voici ma prise.

Un perceptron sklearn a un attribut batch_size qui a une valeur par défaut de 200. Lorsque vous définissez verbose=True de votre MLPClassifier, vous verrez que votre premier exemple (deux appels consécutifs) des résultats en deux itérations, alors que les résultats du 2e exemple en une itération, ie le 2ème appel partial_fit améliore le résultat du premier appel. Dans chaque itération, l'échantillon total est à nouveau divisé en morceaux. Lorsque vous avez un petit sample_size (< 5000 dans l'extrait ci-dessous), le batch_size par défaut est trop grand par rapport à la taille de l'échantillon, le réduire à 100 donnera de meilleurs résultats pour les deux approches, mais il n'y aura pas de différence entre les appels consécutifs et l'approche d'une ligne.

Cet artefact disparaît avec des nombres d'échantillons plus élevés (> 10^6).

enter image description here

from sklearn.datasets import make_moons 
from sklearn.neural_network import MLPClassifier 
from sklearn.preprocessing import StandardScaler 
import matplotlib.pyplot as plt 

def get_mlp(resize_batch, n): 
    mlp = MLPClassifier(verbose=True, random_state=random_state) 
    if resize_batch: 
     mlp.batch_size = min(n // 2, 100) 
    return mlp 

n_samples = [10**2, 10**3, 5*10**3, 10**4, 10**5, 10**6, 10**7] 
batch_resize = [False, True] 
random_state = 1 

results = list() 

for n in n_samples: 
    x = make_moons(n_samples=n, noise=0.3, random_state=random_state) 
    X = StandardScaler().fit_transform(x[0]) 
    results.append([n]) 
    for resize in batch_resize: 
     mlp = get_mlp(resize, n) 
     mlp.partial_fit(X, x[1], [0, 1]) 
     results[-1].append([mlp.score(X, x[1]), 0, resize]) 

     mlp = get_mlp(resize, n) 
     for i in range(2): 

      train_start = i * n // 2 
      train_stop = (i + 1) * n // 2 
      mlp.partial_fit(X[train_start:train_stop], x[1][train_start:train_stop], [0, 1]) 
     results[-1].append([mlp.score(X, x[1]), 1, resize]) 

x = [i[0] for i in results] 
colors = ['red', 'green', 'blue', 'black'] 
labels = ['one call, batch=auto', 'two calls, batch=auto', 'one call, batch=100', 'two calls, batch=100'] 

fig, ax = plt.subplots() 
handles = list() 
for n in range(4): 
    plt.subplot(210 + i) 
    handles.append(plt.plot(x, [i[n + 1][0] for i in results], c=colors[n], label=labels[n])[0]) 
plt.xscale('log') 
plt.legend(handles=handles, loc=2) 
plt.show() 
+0

solveur 'lbfgs' des multi-couches Perceptron ne pas utiliser minibatch. Est-ce une bonne idée d'utiliser ce solveur pour éviter de trouver la valeur optimale de 'batch_size'? (J'utilise 'partial_fit (X, y)' pour l'apprentissage par renforcement, donc je ne connais pas le nombre d'itérations à l'avance) – Victor

+0

Mais l'autre solveur pourrait être moins performant que les autres. Je suggère d'essayer de trouver le meilleur solveur avec ses paramètres optimaux. –