2013-06-02 18 views
9

Potrzebuję rozwiązać problem regresji z siecią przesyłania danych i próbowałem użyć PyBrain, aby to zrobić. Ponieważ nie ma przykładów regresji na referencję pybraba, próbowałem zaadaptować jego przykład klasyfikacji do regresji, ale bez powodzenia (Przykład klasyfikacji można znaleźć tutaj: http://pybrain.org/docs/tutorial/fnn.html). Poniżej znajduje się mój kod:Regresja sieci neuronowych za pomocą pybrain

Ta pierwsza funkcja przekształca moje dane w postaci tablicy numpy na suprywję nadzorowaną pybrain. Używam SupervisedDataset, ponieważ zgodnie z referencją pybrain jest to zestaw danych do użycia, gdy problem jest regresji. Parametry są tablicą wektory cech (dane) i ich oczekiwany wynik (wartości)

def convertDataNeuralNetwork(data, values): 

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

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

    fulldata.addSample(d, v)  

return fulldata 

Następnie jest uruchomienia funkcji regresji. train_data i train_values ​​są wektory cech pociąg i ich oczekiwany wynik, test_data i test_values ​​są wektory cech testy i ich oczekiwany wynik:

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 

podczas drukowania res, wszystkich jego wartości 0. Starałem się używać funkcja buildNetwork jako skrót do budowania sieci, ale nie działała tak dobrze. Próbowałem także różnych rodzajów warstw i różnych liczb węzłów w ukrytej warstwie, bez powodzenia.

Czy ktoś ma pojęcie o tym, co robię źle? Również niektóre przykłady regresji pybranii naprawdę pomogłyby! Nie mogłem znaleźć, kiedy patrzyłem.

góry dzięki

+0

Jeśli interesują Cię sieci neuronowe, możesz rozważyć dołączenie do witryny uczącej się maszyn: http://area51.stackexchange.com/proposals/41738/machine-learning – travisbartley

+2

- pewnie chcesz, aby warstwa wyjściowa była liniowa dla regresja --- prawdopodobnie również chcesz użyć jednostek ukrytych sigmoidalnych/tanh –

+1

ściśle mówiąc niekoniecznie liniowo, ale najczęściej nie jest to aktywacja, której wyjście jest ograniczone do zakresu jak "0..1". Ponadto, nie jestem pewien, jaki jest cel liniowej ukrytej warstwy (jak w kodzie wysłanym), to zwykle może zostać zaabsorbowane w wadze do następnej warstwy. –

Odpowiedz

5

pybrain.tools.neuralnets.NNregression jest narzędziem, które

uczy się numerycznie przewidzieć cele zbioru danych, z opcjonalnych wykresów postępu internetowych.

, więc wydaje się, że coś dobrze nadaje się do budowy sieci neuronowej do zadań regresji.

4

Myślę, że może tu być kilka rzeczy.

Po pierwsze, polecam używanie innej konfiguracji aktywacji warstw niż używana. W szczególności, na początek, spróbuj użyć nieliniowych sigmoidalnych dla ukrytych warstw w twojej sieci i liniowych aktywacji dla warstwy wyjściowej. Jest to zdecydowanie najczęstsza konfiguracja typowej nadzorowanej sieci i powinna pomóc w rozpoczęciu pracy.

Drugą rzeczą, która rzuciła mi się w oczy jest to, że masz stosunkowo dużą wartość parametru weightDecay w swoim trenerze (choć to, co stanowi "stosunkowo duży", zależy od naturalnej skali wartości wejściowych i wyjściowych). Chciałbym usunąć ten parametr dla starterów lub ustawić jego wartość na 0. Zanik masy jest regularyzatorem, który pomoże zapobiec przeładowaniu twojej sieci, ale jeśli zwiększysz wartość tego parametru za bardzo, twoje ciężary sieci pójdą na 0 bardzo szybko (a wtedy gradient twojej sieci będzie wynosił 0, więc uczenie się zatrzyma). Ustaw tylko wartość weightDecay na wartość niezerową, jeśli wydajność treningu próbnego zaczyna spadać.

5

Jak pierwotnie wskazał Ben Allison, na sieć, aby móc zbliżyć dowolne wartości (nie koniecznie w zakresie 0..1) Ważne jest nie użyć funkcji aktywacji z ograniczonym zakresie mocy w ostatecznej warstwy . Na przykład liniowa funkcja aktywacji powinna działać dobrze.

Oto prosty przykład regresja zbudowany z podstawowych elementów 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() 

uwaga bocznej (ponieważ w przykładzie kodu masz ukrytą warstwę liniową funkcja aktywacji): W dowolnym ukryty warstwa, funkcji liniowej nie są przydatne, ponieważ:

  • wagi po stronie wejścia do tej warstwy, tworząc liniową transformację
  • aktywacja funkcji liniowy
  • wagi na wyjściu z tej warstwy, tworząc przekształcenie liniowe

, które mogą być zredukowane do jednego transformacji liniowej, to znaczy, że odpowiednia warstwa może być także wyeliminowane, bez zmniejszania w zestawie funkcji, które można aproksymować. Ważnym punktem sieci neuronowych jest to, że funkcje aktywacyjne są nieliniowe w ukrytych warstwach.

0

Jak wyjaśnił Andre Holzner, ukryta warstwa powinna być nieliniowa. Przykładowy kod Andrea jest świetny, ale nie działa dobrze, gdy masz więcej funkcji i mniej danych. W tym przypadku z powodu dużej ukrytej warstwy uzyskujemy całkiem dobre przybliżenie, ale gdy mamy do czynienia z bardziej złożonymi danymi, tylko funkcja liniowa w warstwie wyjściowej jest niewystarczająca, należy znormalizować funkcje i cel, aby znaleźć się w zasięgu [0..1] .

Powiązane problemy