Следующий ответ не совсем однозначен, так как ему не хватает статистической строгости.
Тем не менее, для оптимизации и оценки необходимых параметров все равно потребуется несколько дней процессорного времени. До этого я представляю в качестве ответа следующее доказательство принципа.
Tl, др
Большие уровни + гораздо более длительное обучение => производительность логистической регрессии сама по себе <+ 1 уровень RBM <+ стек RBM / DBN </p>
Введение
Как я уже отмечал в одном из моих комментариев к сообщению OP, использование стековых RBM / DBN для неконтролируемой предварительной подготовки систематически изучалось в Erhan et al. (2010) . Если быть точным, их настройка отличается от настройки OP тем, что после обучения DBN они добавляют последний слой выходных нейронов и настраивают всю сеть с помощью backprop. OP оценивает преимущество добавления одного или нескольких уровней RBM, используя производительность логистической регрессии на выходе конечного уровня.
Кроме того, Erhan et al. также не используйте 64-пиксельный набор данных digits
в scikit-learn, но 784-пиксельные изображения MNIST (и их варианты).
При этом сходства достаточно существенны, чтобы их выводы послужили отправной точкой для оценки реализации DBN с помощью scikit-learn, что я и сделал: я также использую набор данных MNIST и Я использую оптимальные параметры (где сообщается), Erhan et al. Эти параметры существенно отличаются от параметров, приведенных в примере OP, и, вероятно, являются причиной плохой работы модели OP: в частности, размеры слоев намного больше, а количество обучающих выборок на несколько порядков больше. Однако, как OP, я использую логистическую регрессию на последнем этапе конвейера, чтобы оценить, улучшают ли преобразования изображения с помощью RBM или стека RBM / DBN.
Кстати, наличие (приблизительно) такого же количества единиц в слоях RBM (800 единиц), что и в исходном изображении (784 пикселя), также делает чистую логистическую регрессию для пикселей необработанного изображения подходящей эталонной моделью.
Поэтому я сравниваю следующие 3 модели:
логистическая регрессия сама по себе (т.е. базовая / эталонная модель),
логистическая регрессия на выходах RBM и
логистическая регрессия на выходах стеков RBMs / DBN.
Результаты
В соответствии с предыдущей литературой, мои предварительные результаты действительно указывают на то, что использование вывода RBM для логистической регрессии улучшает производительность по сравнению с простым использованием необработанных значений пикселей, а преобразование DBN все же улучшает RBM, хотя и улучшает меньше.
Логистическая регрессия сама по себе:
Model performance:
precision recall f1-score support
0.0 0.95 0.97 0.96 995
1.0 0.96 0.98 0.97 1121
2.0 0.91 0.90 0.90 1015
3.0 0.90 0.89 0.89 1033
4.0 0.93 0.92 0.92 976
5.0 0.90 0.88 0.89 884
6.0 0.94 0.94 0.94 999
7.0 0.92 0.93 0.93 1034
8.0 0.89 0.87 0.88 923
9.0 0.89 0.90 0.89 1020
avg / total 0.92 0.92 0.92 10000
Логистическая регрессия на выходах RBM:
Model performance:
precision recall f1-score support
0.0 0.98 0.98 0.98 995
1.0 0.98 0.99 0.99 1121
2.0 0.95 0.97 0.96 1015
3.0 0.97 0.96 0.96 1033
4.0 0.98 0.97 0.97 976
5.0 0.97 0.96 0.96 884
6.0 0.98 0.98 0.98 999
7.0 0.96 0.97 0.97 1034
8.0 0.96 0.94 0.95 923
9.0 0.96 0.96 0.96 1020
avg / total 0.97 0.97 0.97 10000
Логистическая регрессия на выходах стеков RBMs / DBN:
Model performance:
precision recall f1-score support
0.0 0.99 0.99 0.99 995
1.0 0.99 0.99 0.99 1121
2.0 0.97 0.98 0.98 1015
3.0 0.98 0.97 0.97 1033
4.0 0.98 0.97 0.98 976
5.0 0.96 0.97 0.97 884
6.0 0.99 0.98 0.98 999
7.0 0.98 0.98 0.98 1034
8.0 0.98 0.97 0.97 923
9.0 0.96 0.97 0.96 1020
avg / total 0.98 0.98 0.98 10000
Код
#!/usr/bin/env python
"""
Using MNIST, compare classification performance of:
1) logistic regression by itself,
2) logistic regression on outputs of an RBM, and
3) logistic regression on outputs of a stacks of RBMs / a DBN.
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_mldata
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.neural_network import BernoulliRBM
from sklearn.base import clone
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report
def norm(arr):
arr = arr.astype(np.float)
arr -= arr.min()
arr /= arr.max()
return arr
if __name__ == '__main__':
# load MNIST data set
mnist = fetch_mldata('MNIST original')
X, Y = mnist.data, mnist.target
# normalize inputs to 0-1 range
X = norm(X)
# split into train, validation, and test data sets
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=10000, random_state=0)
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size=10000, random_state=0)
# --------------------------------------------------------------------------------
# set hyperparameters
learning_rate = 0.02 # from Erhan et el. (2010): median value in grid-search
total_units = 800 # from Erhan et el. (2010): optimal for MNIST / only slightly worse than 1200 units when using InfiniteMNIST
total_epochs = 50 # from Erhan et el. (2010): optimal for MNIST
batch_size = 128 # seems like a representative sample; backprop literature often uses 256 or 512 samples
C = 100. # optimum for benchmark model according to sklearn docs: https://scikit-learn.org/stable/auto_examples/neural_networks/plot_rbm_logistic_classification.html#sphx-glr-auto-examples-neural-networks-plot-rbm-logistic-classification-py)
# TODO optimize using grid search, etc
# --------------------------------------------------------------------------------
# construct models
# RBM
rbm = BernoulliRBM(n_components=total_units, learning_rate=learning_rate, batch_size=batch_size, n_iter=total_epochs, verbose=1)
# "output layer"
logistic = LogisticRegression(C=C, solver='lbfgs', multi_class='multinomial', max_iter=200, verbose=1)
models = []
models.append(Pipeline(steps=[('logistic', clone(logistic))])) # base model / benchmark
models.append(Pipeline(steps=[('rbm1', clone(rbm)), ('logistic', clone(logistic))])) # single RBM
models.append(Pipeline(steps=[('rbm1', clone(rbm)), ('rbm2', clone(rbm)), ('logistic', clone(logistic))])) # RBM stack / DBN
# --------------------------------------------------------------------------------
# train and evaluate models
for model in models:
# train
model.fit(X_train, Y_train)
# evaluate using validation set
print("Model performance:\n%s\n" % (
classification_report(Y_val, model.predict(X_val))))
# TODO: after parameter optimization, evaluate on test set