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