2013-06-02 78 views
9

我需要解決前饋網絡的迴歸問題,我一直在嘗試使用PyBrain來做到這一點。由於沒有關於pybrain引用的迴歸示例,我嘗試將其作爲迴歸的分類示例來代替,但沒有成功(分類示例可在此處找到:http://pybrain.org/docs/tutorial/fnn.html)。以下是我的代碼:使用pybrain進行神經網絡迴歸

這第一個函數將我的數據以numpy數組形式轉換爲pybrain SupervisedDataset。我使用SupervisedDataset,因爲根據pybrain的參考,它是當問題是迴歸時使用的數據集。的參數與特徵矢量(數據)和它們的期望的輸出(值)的數組:

def convertDataNeuralNetwork(data, values): 

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

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

    fulldata.addSample(d, v)  

return fulldata 

接下來,是運行迴歸函數。 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 

當我打印資源,所有它的值是0。我試着使用buildNetwork函數作爲構建網絡的捷徑,但它並沒有起作用。我也嘗試過隱藏層中不同類型的層和不同數量的節點,但沒有運氣。

有人知道我做錯了什麼嗎?此外,一些pybrain迴歸示例真的會有所幫助!當我看時,我找不到任何東西。

在此先感謝

+0

如果您對神經網絡感興趣,您可以考慮加入機器學習網站:http://area51.stackexchange.com/proposals/41738/machine-learning – travisbartley

+2

很確定您希望輸出層爲線性迴歸---你可能也想用嚴格來說不一定是線性的S/S隱藏單元 –

+1

,但它最不是一個激活,它的輸出被限制在一個範圍內,如'0..1'。另外,我不確定線性隱藏層的目的是什麼(就像在代碼中),通常可以將其吸收到下一層的權重中。 –

回答

5

pybrain.tools.neuralnets.NNregression是一個工具,它

學會數值預測的一組數據的目標,與 可選的在線進度圖。

所以它看起來很適合爲您的迴歸任務構建一個神經網絡。

4

我認爲這裏可能會發生一些事情。

首先,我建議使用不同的圖層激活配置。特別是,對於初學者,嘗試對網絡中的隱藏層使用S形非線性,並對輸出層進行線性激活。這是迄今爲止最典型的典型監督網絡設置,應該可以幫助您開始。

第二件引起我注意的事情是,您的教練器中weightDecay參數的值相對較大(儘管什麼構成「相對較大」取決於您的輸入和輸出值的自然比例)。我會爲初學者刪除該參數,或將其值設置爲0.權重衰減是一個正規化器,它有助於防止網絡過度配合,但如果太多增加該參數的值,則網絡權重將全部爲0非常快(然後你的網絡漸變將基本爲0,所以學習將停止)。如果您在驗證數據集上的表現在訓練期間開始下降,則只需將weightDecay設置爲非零值。

5

按照最初指出由Ben艾裏,爲網絡能夠逼近任意值(即,在範圍0..1不是必須的)是很重要的使用具有有限輸出範圍內的激活函數中的最後層。例如線性激活函數應該很好。

下面是從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面的話(由於在代碼示例您有線性活化函數隱藏層):在任何隱含層,線性函數是沒有用的,因爲:

  • 在輸入側到該層的權重形成的線性變換
  • 激活函數是線性
  • 在輸出側,以該層的權重形成的線性變換

其可以減少到一個單一的線性變換,即,它們相應層也可以被無任何還原消除在可以近似的一組函數中。神經網絡的一個重要特點是激活函數在隱藏層中是非線性的。

0

正如Andre Holzner所解釋的,隱藏層應該是非線性的。 Andre的代碼示例非常棒,但是當你有更多的功能而沒有太多的數據時,它並不能很好地工作。在這種情況下,由於隱藏層較大,我們可以得到相當不錯的近似值,但是當處理更復雜的數據時,只有輸出層中的線性函數不夠,應該對特徵進行歸一化,並將目標值設置在範圍[0..1] 。