如果没有一个最小的、可重复的例子,回答这个问题有点困难,但这是我的看法。
sklearn 感知器有一个属性 batch_size,其默认值为 200。当您设置 verbose=True 的 MLPClassifier 时,您会看到您的第一个示例(两次连续调用)导致两次迭代,而第二个示例导致一次迭代,即第二个partial_fit 调用改进了第一次调用的结果。在每次迭代中,总样本再次被分成块。
当您的 sample_size 较小时(在下面的 sn-p 中 batch_size 相对于样本大小来说太大了,将其减小到 100 将为这两种方法提供更好的结果,但不会是连续调用和单行方法之间的区别。
随着样本数的增加 (>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()