简体   繁体   English

使用pybrain进行神经网络回归

[英]neural networks regression using pybrain

I need to solve a regression problem with a feed forward network and I've been trying to use PyBrain to do it. 我需要解决前馈网络的回归问题,并且我一直在尝试使用PyBrain来完成它。 Since there are no examples of regression on pybrain's reference, I tried to adapt it's classification example for regression instead, but with no success (The classification example can be found here: http://pybrain.org/docs/tutorial/fnn.html ). 由于没有关于pybrain参考的回归的例子,我试图改编它的回归分类示例,但没有成功(分类示例可以在这里找到: http//pybrain.org/docs/tutorial/fnn.html )。 Following is my code: 以下是我的代码:

This first function converts my data in numpy array form to a pybrain SupervisedDataset. 第一个函数将我的数据以numpy数组形式转换为pybrain SupervisedDataset。 I use the SupervisedDataset because according to pybrain's reference it is the dataset to use when the problem is regression. 我使用SupervisedDataset,因为根据pybrain的参考,它是在问题回归时使用的数据集。 The parameters are an array with the feature vectors (data) and their expected output (values): 参数是一个包含特征向量(数据)及其预期输出(值)的数组:

def convertDataNeuralNetwork(data, values):

fulldata = SupervisedDataSet(data.shape[1], 1)

for d, v in zip(data, values):

    fulldata.addSample(d, v)    

return fulldata

Next, is the function to run the regression. 接下来,是运行回归的功能。 train_data and train_values are the train feature vectors and their expected output, test_data and test_values are the test feature vectors and their expected output: train_data和train_values是列车特征向量及其预期输出,test_data和test_values是测试特征向量及其预期输出:

regressionTrain = convertDataNeuralNetwork(train_data, train_values)

regressionTest = convertDataNeuralNetwork(test_data, test_values)

fnn = FeedForwardNetwork()

inLayer = LinearLayer(regressionTrain.indim)
hiddenLayer = LinearLayer(5)
outLayer = GaussianLayer(regressionTrain.outdim)

fnn.addInputModule(inLayer)
fnn.addModule(hiddenLayer)
fnn.addOutputModule(outLayer)

in_to_hidden = FullConnection(inLayer, hiddenLayer)
hidden_to_out = FullConnection(hiddenLayer, outLayer)

fnn.addConnection(in_to_hidden)
fnn.addConnection(hidden_to_out)

fnn.sortModules()

trainer = BackpropTrainer(fnn, dataset=regressionTrain, momentum=0.1, verbose=True, weightdecay=0.01)

for i in range(10):

    trainer.trainEpochs(5)

    res = trainer.testOnClassData(dataset=regressionTest )

    print res

when I print res, all it's values are 0. I've tried to use the buildNetwork function as a shortcut to build the network, but it didn't work as well. 当我打印res时,它的所有值都是0.我已经尝试使用buildNetwork函数作为构建网络的快捷方式,但它不能正常工作。 I've also tried different kinds of layers and different number of nodes in the hidden layer, with no luck. 我还在隐藏层中尝试了不同类型的层和不同数量的节点,没有运气。

Does somebody have any idea of what I am doing wrong? 有人知道我做错了什么吗? Also, some pybrain regression examples would really help! 此外,一些pybrain回归示例真的会有所帮助! I couldn't find any when I looked. 我看的时候找不到任何东西。

Thanks in advance 提前致谢

pybrain.tools.neuralnets.NNregression is a tool which pybrain.tools.neuralnets.NNregression是一个工具

Learns to numerically predict the targets of a set of data, with optional online progress plots. 通过可选的在线进度图,学习数字预测一组数据的目标。

so it seems like something well suited for constructing a neural network for your regression task. 所以它似乎非常适合为你的回归任务构建一个神经网络。

As originally pointed out by Ben Allison, for the network to be able to approximate arbitrary values (ie not necessarily in the range 0..1 ) it is important not to use an activation function with limited output range in the final layer. 正如Ben Allison最初指出的那样,为了使网络能够逼近任意值(即不一定在0..1范围内),重要的是不要在最后一层使用输出范围有限的激活函数。 A linear activation function for example should work well. 例如,线性激活功能应该很好。

Here is a simple regression example built from the basic elements of pybrain: 这是一个从pybrain的基本元素构建的简单回归示例:

#----------
# build the dataset
#----------
from pybrain.datasets import SupervisedDataSet
import numpy, math

xvalues = numpy.linspace(0,2 * math.pi, 1001)
yvalues = 5 * numpy.sin(xvalues)

ds = SupervisedDataSet(1, 1)
for x, y in zip(xvalues, yvalues):
    ds.addSample((x,), (y,))

#----------
# build the network
#----------
from pybrain.structure import SigmoidLayer, LinearLayer
from pybrain.tools.shortcuts import buildNetwork

net = buildNetwork(1,
                   100, # number of hidden units
                   1,
                   bias = True,
                   hiddenclass = SigmoidLayer,
                   outclass = LinearLayer
                   )
#----------
# train
#----------
from pybrain.supervised.trainers import BackpropTrainer
trainer = BackpropTrainer(net, ds, verbose = True)
trainer.trainUntilConvergence(maxEpochs = 100)

#----------
# evaluate
#----------
import pylab
# neural net approximation
pylab.plot(xvalues,
           [ net.activate([x]) for x in xvalues ], linewidth = 2,
           color = 'blue', label = 'NN output')

# target function
pylab.plot(xvalues,
           yvalues, linewidth = 2, color = 'red', label = 'target')

pylab.grid()
pylab.legend()
pylab.show()

A side remark (since in your code example you have a hidden layer with linear activation functions): In any hidden layer, linear functions are not useful because: 旁注(因为在您的代码示例中,您有一个带有线性激活函数的隐藏层):在任何隐藏层中,线性函数都没用,因为:

  • the weights at the input side to this layer form a linear transformation 该层输入侧的权重形成线性变换
  • the activation function is linear 激活功能是线性的
  • the weights at the output side to this layer form a linear transformation 在该层的输出侧的权重形成线性变换

which can be reduced to one single linear transformation, ie they corresponding layer may as well be eliminated without any reduction in the set of functions which can be approximated. 这可以简化为单个线性变换,即它们也可以被消除,而不会减少可以近似的函数集。 An important point of neural networks is that the activation functions are non-linear in the hidden layers. 神经网络的一个重点是激活函数在隐藏层中是非线性的。

I think there could be a couple of things going on here. 我想这里可能会发生一些事情。

First, I'd recommend using a different configuration of layer activations than what you're using. 首先,我建议使用与您使用的不同的图层激活配置。 In particular, for starters, try to use sigmoidal nonlinearities for the hidden layers in your network, and linear activations for the output layer. 特别是,对于初学者,尝试对网络中的隐藏层使用S形非线性,并对输出层使用线性激活。 This is by far the most common setup for a typical supervised network and should help you get started. 这是迄今为止典型监督网络最常见的设置,应该可以帮助您入门。

The second thing that caught my eye is that you have a relatively large value for the weightDecay parameter in your trainer (though what constitutes "relatively large" depends on the natural scale of your input and output values). 引起我注意的第二件事是你的训练师的weightDecay参数值相对较大(虽然构成“相对较大”的值取决于输入和输出值的自然比例)。 I would remove that parameter for starters, or set its value to 0. The weight decay is a regularizer that will help prevent your network from overfitting, but if you increase the value of that parameter too much, your network weights will all go to 0 very quickly (and then your network's gradient will be basically 0, so learning will halt). 我会为初学者删除该参数,或将其值设置为0.重量衰减是一个有助于防止网络过度拟合的正则化器,但如果你过多地增加该参数的值,你的网络权重将全部变为0很快(然后你的网络的梯度基本上是0,所以学习将停止)。 Only set weightDecay to a nonzero value if your performance on a validation dataset starts to decrease during training. 如果在训练期间验证数据集上的性能开始下降,则仅将weightDecay设置为非零值。

As Andre Holzner explained, hidden layer should be nonlinear. 正如Andre Holzner所解释的那样,隐藏层应该是非线性的。 Andre's code example is great, but it doesn't work well when you have more features and not so much data. Andre的代码示例很棒,但是当您拥有更多功能而不是那么多数据时,它不能很好地工作。 In this case because of large hidden layer we get quite good approximation, but when you are dealing with more complex data, only linear function in output layer is not enough, you should normalize features and target to be in range [0..1]. 在这种情况下,由于隐藏层很大,我们得到了很好的近似,但是当你处理更复杂的数据时,输出层中只有线性函数是不够的,你应该将特征和目标规范化到范围[0..1] 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM