gpt4 book ai didi

python - 堆叠 RBM 以在 sklearn 中创建深度信念网络

转载 作者:太空狗 更新时间:2023-10-29 21:48:13 27 4
gpt4 key购买 nike

根据这个website ,深度信念网络只是将多个RBM堆叠在一起,使用前一个RBM的输出作为下一个RBM的输入。 enter image description here

在 scikit-learn 中 documentation ,有一个使用 RBM 对 MNIST 数据集进行分类的示例。他们将 RBMLogisticRegression 放入管道中以实现更高的准确性。

因此我想知道是否可以将多个 RBM 添加到该管道中以创建深度信念网络,如以下代码所示。

from sklearn.neural_network import BernoulliRBM
import numpy as np
from sklearn import linear_model, datasets, metrics
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline

digits = datasets.load_digits()
X = np.asarray(digits.data, 'float32')
Y = digits.target
X = (X - np.min(X, 0)) / (np.max(X, 0) + 0.0001) # 0-1 scaling

X_train, X_test, Y_train, Y_test = train_test_split(X, Y,
test_size=0.2,
random_state=0)

logistic = linear_model.LogisticRegression(C=100)
rbm1 = BernoulliRBM(n_components=100, learning_rate=0.06, n_iter=100, verbose=1, random_state=101)
rbm2 = BernoulliRBM(n_components=80, learning_rate=0.06, n_iter=100, verbose=1, random_state=101)
rbm3 = BernoulliRBM(n_components=60, learning_rate=0.06, n_iter=100, verbose=1, random_state=101)
DBN3 = Pipeline(steps=[('rbm1', rbm1),('rbm2', rbm2), ('rbm3', rbm3), ('logistic', logistic)])

DBN3.fit(X_train, Y_train)

print("Logistic regression using RBM features:\n%s\n" % (
metrics.classification_report(
Y_test,
DBN3.predict(X_test))))

但是,我发现添加到管道中的 RBM 越多,准确性就越低。

1 RBM 正在筹备中 --> 95%

2 RBM 正在筹备中 --> 93%

3 个 RBM 正在筹备中 --> 89%

下面的训练曲线显示 100 次迭代刚好收敛。更多的迭代会导致过拟合,并且可能性会再次下降。

批量大小 = 10

enter image description here

批量大小 = 256 或以上

我注意到一件有趣的事。如果我使用更高的批量大小,网络性能会下降很多。当 batch size 超过 256 时,准确率下降到只有不到 10%。不知何故,训练曲线对我来说没有意义,第一和第二个 RBM 学得不多,但第三个 RBM 突然学得很快。 enter image description here

看起来 89% 在某种程度上是具有 3 个 RBM 的网络的瓶颈。

我想知道我在这里做错了什么。我对深度信念网络的理解正确吗?

最佳答案

以下并不是一个明确的答案,因为它缺乏任何统计上的严谨性。然而,必要的参数优化和评估仍然需要几天的 CPU 时间。在此之前,我提交以下原理证明作为答案。

Tl;dr

更大的层 + 更长的训练 => 逻辑回归本身的性能 < + 1 RBM 层 < + RBM 堆栈/DBN

简介

正如我在对 OP 帖子的评论之一中所述,在 Erhan et al. (2010) 中系统地探索了使用堆叠 RBM/DBN 进行无监督预训练。 .准确地说,他们的设置与 OP 的设置不同之处在于,在训练 DBN 之后,他们添加了最后一层输出神经元并使用反向传播微调整个网络。 OP 使用逻辑回归对最后一层输出的性能来评估添加一个或多个 RBM 层的好处。此外,Erhan 等人。也不要使用 scikit-learn 中的 64 像素 digits 数据集,而是使用 784 像素的 MNIST 图像(及其变体)。

话虽这么说,但它们的相似性足以将他们的发现作为评估 DBN 的 scikit-learn 实现的起点,这正是我所做的:我也使用 MNIST 数据集,并且我使用 Erhan 等人的最佳参数(报告的地方)。这些参数与 OP 示例中给出的参数有很大不同,很可能是 OP 模型性能不佳的根源:特别是,层大小要大得多,训练样本的数量要多几个数量级。但是,作为 OP,我在管道的最后一步使用逻辑回归来评估 RBM 或 RBM 堆栈/DBN 的图像转换是否改进了分类。

顺便说一句,RBM ​​层(800 个单元)中的单元(大致)与原始图像(784 像素)中的单元一样多,也使原始图像像素上的纯逻辑回归成为合适的基准模型。

因此我比较了以下 3 个模型:

  1. 逻辑回归本身(即基线/基准模型),

  2. RBM 输出的逻辑回归,以及

  3. 对一组 RBM/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

RBM/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

关于python - 堆叠 RBM 以在 sklearn 中创建深度信念网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52166308/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com