Регрессия нейронных сетей с использованием pybrain

Мне нужно решить проблему регрессии с помощью сети прямой связи, и я пытался использовать PyBrain для этого. Поскольку в реферате Pybrain нет примеров регрессии, я попытался вместо этого использовать его пример классификации для регрессии, но безуспешно (Пример классификации можно найти здесь: http://pybrain.org/docs/tutorial/fnn.html). Ниже приведен мой код:

Эта первая функция преобразует мои данные в виде массива в 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

когда я печатаю res, все его значения равны 0. Я пытался использовать функцию buildNetwork в качестве ярлыка для построения сети, но это не сработало. Я также пробовал разные типы слоев и разное количество узлов в скрытом слое, но не повезло.

Кто-нибудь имеет представление о том, что я делаю неправильно? Кроме того, некоторые примеры регрессии Pybrain действительно помогли бы! Я не мог найти, когда я смотрел.

заранее спасибо

4 ответа

Как первоначально указывал Бен Аллисон, для того, чтобы сеть могла аппроксимировать произвольные значения (т.е. не обязательно в диапазоне 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()

Дополнительное замечание (поскольку в вашем примере кода у вас есть скрытый слой с функциями линейной активации): в любом скрытом слое линейные функции бесполезны, потому что:

  • веса на входной стороне этого слоя образуют линейное преобразование
  • функция активации является линейной
  • веса на выходной стороне этого слоя образуют линейное преобразование

которые могут быть сведены к одному линейному преобразованию, то есть их соответствующий слой также может быть исключен без какого-либо сокращения набора функций, которые могут быть аппроксимированы. Важным моментом нейронных сетей является то, что функции активации являются нелинейными в скрытых слоях.

pybrain.tools.neuralnets.NNregression это инструмент, который

Научится численно прогнозировать цели набора данных с помощью дополнительных графиков прогресса в Интернете.

так что это похоже на то, что хорошо подходит для построения нейронной сети для вашей задачи регрессии.

Я думаю, что здесь может быть несколько вещей.

Во-первых, я бы рекомендовал использовать другую конфигурацию активаций слоев, чем та, которую вы используете. В частности, для начала попробуйте использовать сигмоидальные нелинейности для скрытых слоев в вашей сети и линейные активации для выходного слоя. Это, безусловно, самая распространенная настройка для типичной контролируемой сети, которая должна помочь вам начать работу.

Второе, что бросилось в глаза, это то, что у вас есть относительно большое значение для weightDecay параметр в вашем тренере (хотя то, что составляет "относительно большой", зависит от естественного масштаба ваших входных и выходных значений). Я бы удалил этот параметр для начинающих или установил бы его значение на 0. Уменьшение веса является регуляризатором, который поможет предотвратить переоснащение вашей сети, но если вы слишком увеличите значение этого параметра, все веса вашей сети будут равны 0 очень быстро (и тогда градиент вашей сети будет в основном равен 0, поэтому обучение остановится). Только установить weightDecay к ненулевому значению, если ваша производительность в наборе данных проверки начинает снижаться во время обучения.

Как объяснил Андре Хольцнер, скрытый слой должен быть нелинейным. Пример кода Андреа великолепен, но он не работает, когда у вас больше функций и не так много данных. В этом случае из-за большого скрытого слоя мы получаем довольно хорошее приближение, но когда вы имеете дело с более сложными данными, недостаточно только линейной функции в выходном слое, вам следует нормализовать объекты и цель, чтобы они находились в диапазоне [0..1],

Другие вопросы по тегам