Scikit-Learn 中的神经网络没有产生有意义的结果

Posted

技术标签:

【中文标题】Scikit-Learn 中的神经网络没有产生有意义的结果【英文标题】:Neural Network In Scikit-Learn not producing meaningful results 【发布时间】:2016-12-08 07:14:53 【问题描述】:

我目前正在尝试将 scikit learn 包用于其神经网络功能。我有一个复杂的问题要解决,但一开始我只是尝试一些基本测试来熟悉它。我已经让它做某事,但它没有产生有意义的结果。我的代码:

import sklearn.neural_network.multilayer_perceptron as nnet
import numpy
def generateTargetDataset(expression="%s", generateRange=(-100,100), s=1000):
    expression = expression.replace("x", "%s")    
    x = numpy.random.rand(s,)
    y = numpy.zeros((s,), dtype="float")
    numpy.multiply(x, abs(generateRange[1]-generateRange[0]), x)
    numpy.subtract(x, min(generateRange), x)
    for z in range(0, numpy.size(x)):
        y[z] = eval(expression % (x[z]))
    x = x.reshape(-1, 1)
    outTuple = (x, y)
    return(outTuple)
print("New Net + Training")
QuadRegressor = nnet.MLPRegressor(hidden_layer_sizes=(10), warm_start=True, verbose=True, learning_rate_init=0.00001, max_iter=10000, algorithm="sgd", tol=0.000001)
data = generateTargetDataset(expression="x**2", s=10000, generateRange=(-1,1))
QuadRegressor.fit(data[0], data[1])
print("Net Trained")
xt = numpy.random.rand(10000, 1)
yr = QuadRegressor.predict(xt)
yr = yr.reshape(-1, 1)
xt = xt.reshape(-1, 1)
numpy.multiply(xt, 100, xt)
numpy.multiply(yr, 10000, yr)
numpy.around(yr, 2, out=yr)
numpy.around(xt, 2, out=xt)
out = numpy.concatenate((xt, yr), axis=1)
numpy.set_printoptions(precision=4)
numpy.savetxt(fname="C:\\SCRATCHDIR\\numpydump.csv", X=out, delimiter=",")

我不明白如何发布它给我的数据,但是对于 0 到 100 之间的所有输入,它会吐出 7000 到 10000 之间的数据。它似乎正确映射到非常接近范围的顶部,但是对于输入接近 0,它只返回接近 7000 的值。

编辑:我忘了添加这个。如果我将虚拟训练移除到 y=x,网络具有相同的行为,但我在某处读到,有时您可以通过将网络训练到不同但更接近的功能,然后使用已经加权的网络作为起点来帮助网络。它没有用,但我还没有拿出那一点。

【问题讨论】:

您是否对输入数据进行了标准化以及如何初始化权重? 这个网络只有一个输入,范围从 -100 到 100。我想我可以尝试将其标准化为 -1 到 1,然后在最后乘以 10,000。我尝试使用 scikit-learn 中的内置功能随机初始化权重,以及使用经过训练以回归 y=x 的网络的热启动。 我刚刚尝试将我的输入标准化为 -1,1 并将我的学习率降低了十倍。我还将收敛的容差设置得更低,因为现在误差会成倍增加。该网络现在的训练速度提高了大约 60 倍,但实际上并没有提高其性能,因为所有预测的数据点都大致遵循公式 f(x) = 240x-17000,而不是应该的 x^2 【参考方案1】:

我的建议是减少每层的神经元数量,并增加训练数据集的大小。现在,你有很多参数要在网络中训练,还有一个小的训练集(~10K)。但是,我回答的要点是 sklearn 可能不是您的最终应用程序的好选择。

所以你有一个复杂的问题想用神经网络解决?

我有一个复杂的问题要解决,但一开始我只是尝试几个基本测试来熟悉它。

根据official user guide 的说法,sklearn 的神经网络实现不是为大型应用程序设计的,在深度学习方面的灵活性远低于other options。

我使用过的一个 Python 深度学习库是 keras,它是一个模块化、易于使用的库,支持 GPU。

这是我编写的一个样本,用于训练单个感知器进行二次回归。

from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.optimizers import SGD
import numpy as np
import matplotlib.pyplot as plt

model = Sequential()
model.add(Dense(1, init = 'uniform', input_dim=1))
model.add(Activation('sigmoid'))


model.compile(optimizer = SGD(lr=0.02, decay=1e-6, momentum=0.9, nesterov=True), loss = 'mse')

data = np.random.random(1000)
labels = data**2

model.fit(data.reshape((len(data),1)), labels, nb_epoch = 1000, batch_size = 128, verbose = 1)

tdata = np.sort(np.random.random(100))
tlabels = tdata**2

preds = model.predict(tdata.reshape((len(tdata), 1)))

plt.plot(tdata, tlabels)
plt.scatter(tdata, preds)
plt.show()

这会输出测试数据点的散点图以及真实曲线图。

如您所见,结果是合理的。一般来说,神经网络很难训练,在我让这个例子工作之前,我必须做一些参数调整。

您似乎使用的是 Windows。 This question 可能有助于在 Windows 上安装 Keras。

【讨论】:

因成为唯一花时间提供帮助的人而获得奖金。谢谢你,我稍后会看看这个。

以上是关于Scikit-Learn 中的神经网络没有产生有意义的结果的主要内容,如果未能解决你的问题,请参考以下文章

Scikit-learn 转换器管道产生的结果与单独运行不同

sklearn MLPRegressor 的 TensorFlow 副本产生其他结果

scikit-learn GMM 产生正对数概率

scikit-learn: isotonic regression(保序回归,非常有意思,仅做知识点了解,但差点儿没用到过)

使用Python scikit-learn 库实现神经网络算法

确认号啥时候有意义