3

예측을 위해 반복적 인 신경망을 구축하려고합니다. 나는 PyBrain에서 그것을하고있다.예측을위한 반복 NN은 학습하지 않습니다.

아이디어와 기술을 테스트하기위한 두 개의 간단한 스크립트를 만들어보다 복잡한 것으로 구현하기로했습니다.

가능한 한 많이 작동하는 것으로 확인 된 코드는 다음과 같습니다. stackoverflowgithub입니다. 첫 번째 예에서

나는 과거 값의 기간 주어진 죄 값을 예측하기 위해 노력하고있어 :

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

"""An example of a simple RNN.""" 

import time 
import math 
import matplotlib.pyplot as plt 

from normalizator import Normalizator 

from pybrain.tools.shortcuts import buildNetwork 
from pybrain.structure.modules import LSTMLayer 
from pybrain.structure import LinearLayer, SigmoidLayer 
from pybrain.supervised.trainers import BackpropTrainer 
from pybrain.supervised import RPropMinusTrainer 
from pybrain.datasets import SupervisedDataSet 
from pybrain.datasets import SequentialDataSet 
import pybrain.datasets.sequential 


class Network(object): 
    """Sieć neuronowa.""" 

    def __init__(self, inputs, hidden, outputs): 
     """Just a constructor.""" 
     self.inputs = inputs 
     self.outputs = outputs 
     self.hidden = hidden 
     self.network = self.build_network(inputs, hidden, outputs) 
     self.norm = Normalizator() 

    def build_network(self, inputs, hidden, outputs): 
     """Builds the network.""" 
     network = buildNetwork(inputs, hidden, outputs, 
           hiddenclass=LSTMLayer, 
           #hiddenclass=SigmoidLayer, 
           outclass=SigmoidLayer, 
           bias = True, 
           outputbias=False, recurrent=True) 
     network.sortModules() 
     print "Constructed network:" 
     print network 
     return network 

    def train(self, learning_set, max_terations=100): 
     """Trains the network.""" 
     print "\nThe network is learning..." 
     time_s = time.time() 
     self.network.randomize() 
     #trainer = RPropMinusTrainer(self.network, dataset=learning_set, 
     #       verbose=True) 
     learning_rate = 0.05 
     trainer = BackpropTrainer(self.network, learning_set, verbose=True, 
            momentum=0.8, learningrate=learning_rate) 
     errors = trainer.trainUntilConvergence(maxEpochs=max_terations) 
     #print "Last error in learning:", errors[-1] 
     time_d = time.time() - time_s 
     print "Learning took %d seconds." % time_d 
     return errors, learning_rate 

    def test(self, data): 
     """Tests the network.""" 
     print ("X\tCorrect\tOutput\t\tOutDenorm\tError") 
     mse = 0.0 
     outputs = [] 
     #self.network.reset() 
     for item in data: 
      x_val = self.norm.denormalize("x", item[0]) 
      sin_val = self.norm.denormalize("sin", item[1]) 
      #get the output from the network 
      output = self.network.activate(item[0])[0] 
      out_denorm = self.norm.denormalize("sin", output) 
      outputs.append(out_denorm) 
      #compute the error 
      error = sin_val - out_denorm 
      mse += error**2 
      print "%f\t%f\t%f\t%f\t%f" % \ 
       (round(x_val, 2), sin_val, output, out_denorm, error) 
     mse = mse/float(len(data)) 
     print "MSE:", mse 
     return outputs, mse 

    def show_plot(self, correct, outputs, learn_x, test_x, 
        learning_targets, mse): 
     """Plots some useful stuff :)""" 
     #print "learn_x:", learn_x 
     #print "test_x:", test_x 
     #print "output:", outputs 
     #print "correct:", correct 
     fig = plt.figure() 
     ax = fig.add_subplot(111) 
     ax.plot(test_x, outputs, label="Prediction", color="red") 
     ax.plot(test_x, correct, ":", label="Original data") 
     ax.legend(loc='upper left') 
     plt.xlabel('X') 
     plt.ylabel('Sinus') 
     plt.title('Sinus... (mse=%f)' % mse) 
     #plot a portion of the learning data 
     learning_plt = fig.add_subplot(111) 
     learn_index = int(0.9 * len(learning_targets)) 
     learning_plt.plot(learn_x[learn_index:], learning_targets[learn_index:], 
          label="Learning values", color="blue") 
     learning_plt.legend(loc='upper left') 
     plt.show() 

    def prepare_data(self): 
     """Prepares the data.""" 
     learn_inputs = [round(x, 2) for x in [y * 0.05 for y in range(0, 4001)]] 
     learn_targets = [math.sin(z) for z in learn_inputs] 

     test_inputs = [round(x, 2) for x in [y * 0.05 for y in range(4001, 4101)]] 
     test_targets = [math.sin(z) for z in test_inputs] 

     self.norm.add_feature("x", learn_inputs + test_inputs) 
     self.norm.add_feature("sin", learn_targets + test_targets) 

     #learning_set = pybrain.datasets.sequential.SupervisedDataSet(1, 1) 
     learning_set = SequentialDataSet(1, 1) 
     targ_close_to_zero = 0 
     for inp, targ in zip(learn_inputs, learn_targets): 
      if abs(targ) < 0.01: 
       targ_close_to_zero += 1 
      #if inp % 1 == 0.0: 
      if targ_close_to_zero == 2: 
       print "New sequence at", (inp, targ) 
       targ_close_to_zero = 0 
       learning_set.newSequence() 
      learning_set.appendLinked(self.norm.normalize("x", inp), 
             self.norm.normalize("sin", targ)) 

     testing_set = [] 
     for inp, targ in zip(test_inputs, test_targets): 
      testing_set.append([self.norm.normalize("x", inp), 
           self.norm.normalize("sin", targ), inp, targ]) 
     return learning_set, testing_set, learn_inputs, test_inputs, learn_targets 

if __name__ == '__main__': 
    nnetwork = Network(1, 20, 1) 
    learning_set, testing_set, learning_inputs, testing_inputs, learn_targets = \ 
     nnetwork.prepare_data() 
    errors, rate = nnetwork.train(learning_set, 125) 
    outputs, mse = nnetwork.test(testing_set) 
    correct = [element[3] for element in testing_set] 
    nnetwork.show_plot(correct, outputs, 
         learning_inputs, testing_inputs, learn_targets, mse) 

결과는 비극적이다, 적어도 말을 할 수 있습니다.

X  Correct  Output  OutDenorm Error 

200.050000 -0.847857 0.490775 -0.018445 -0.829411 
200.100000 -0.820297 0.490774 -0.018448 -0.801849 
200.150000 -0.790687 0.490773 -0.018450 -0.772237 
200.200000 -0.759100 0.490772 -0.018452 -0.740648 
200.250000 -0.725616 0.490770 -0.018454 -0.707162 

이것은 미친 짓입니다.

두 번째는 sun spots 데이터를 기반으로, 유사합니다 : 여기

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

"""An example of a simple RNN.""" 

import argparse 
import sys 
import operator 
import time 

from pybrain.tools.shortcuts import buildNetwork 
from pybrain.structure import FullConnection 
from pybrain.structure.modules import LSTMLayer 
from pybrain.structure import LinearLayer, SigmoidLayer 
from pybrain.supervised.trainers import BackpropTrainer 
from pybrain.supervised import RPropMinusTrainer 
from pybrain.datasets import SupervisedDataSet 
import pybrain.datasets.sequential 

import matplotlib.pyplot as plt 
from matplotlib.ticker import FormatStrFormatter 

from normalizator import Normalizator 


class Network(object): 
    """Neural network.""" 

    def __init__(self, inputs, hidden, outputs): 
     """Constructor.""" 
     self.inputs = inputs 
     self.outputs = outputs 
     self.hidden = hidden 
     self.network = self.build_network(inputs, hidden, outputs) 
     self.norm = Normalizator() 

    def build_network(self, inputs, hidden, outputs): 
     """Builds the network.""" 
     network = buildNetwork(inputs, hidden, outputs, bias=True, 
           hiddenclass=LSTMLayer, 
           #hiddenclass=SigmoidLayer, 
           outclass=SigmoidLayer, 
           outputbias=False, fast=False, recurrent=True) 
     #network.addRecurrentConnection(
     # FullConnection(network['hidden0'], network['hidden0'], name='c3')) 
     network.sortModules() 
     network.randomize() 
     print "Constructed network:" 
     print network 
     return network 

    def train(self, learning_set, max_terations=100): 
     """Trains the network.""" 
     print "\nThe network is learning..." 
     time_s = time.time() 
     trainer = RPropMinusTrainer(self.network, dataset=learning_set, 
            verbose=True) 
     learning_rate = 0.001 
     #trainer = BackpropTrainer(self.network, learning_set, verbose=True, 
     #   batchlearning=True, momentum=0.8, learningrate=learning_rate) 
     errors = trainer.trainUntilConvergence(maxEpochs=max_terations) 
     #print "Last error in learning:", errors[-1] 
     time_d = time.time() - time_s 
     print "Learning took %d seconds." % time_d 
     return errors, learning_rate 

    def test(self, data): 
     """Tests the network.""" 
     print ("Year\tMonth\tCount\tCount_norm\t" + 
       "Output\t\tOutDenorm\tError") 
     # do the testing 
     mse = 0.0 
     outputs = [] 
     #print "Test data:", data 
     for item in data: 
      #month = self.norm.denormalize("month", item[1]) 
      #year = self.norm.denormalize("year", item[2]) 
      year, month = self.norm.denormalize("ym", item[5]) 
      count = self.norm.denormalize("count", item[3]) 
      #get the output from the network 
      output = self.network.activate((item[1], item[2])) 
      out_denorm = self.norm.denormalize("count", output[0]) 
      outputs.append(out_denorm) 
      #compute the error 
      error = count - out_denorm 
      mse += error**2 
      print "%d\t%d\t%s\t%f\t%f\t%f\t%f" % \ 
       (year, month, count, item[3], 
       output[0], out_denorm, error) 
     mse /= len(data) 
     print "MSE:", mse 
     #corrects = [self.norm.denormalize("count", item[3]) for item in data] 
     #print "corrects:", len(corrects) 
     return outputs, mse 

    def show_plot(self, correct, outputs, learn_x, test_x, 
        learning_targets, mse): 
     """Rysuje wykres :)""" 
     #print "x_axis:", x_axis 
     #print "output:", output 
     #print "correct:", correct 
     fig = plt.figure() 
     ax = fig.add_subplot(111) 
     ax.plot(test_x, outputs, label="Prediction", color="red") 
     ax.plot(test_x, correct, ":", label="Correct") 
     #            int(201000.0/100) 
     ax.xaxis.set_major_formatter(FormatStrFormatter('%s')) 
     ax.legend(loc='upper left') 
     learn_index = int(0.8 * len(learn_x)) 
     learn_part_x = learn_x[learn_index:] 
     learn_part_vals = learning_targets[learn_index:] 
     learning_plt = fig.add_subplot(111) 
     learning_plt.plot(learn_part_x, learn_part_vals, 
          label="Learning values", color="blue") 
     learning_plt.legend(loc='upper left') 
     plt.xlabel('Year-Month') 
     plt.ylabel('Values') 
     plt.title('... (mse=%f)' % mse) 
     plt.show() 

    def read_data(self, learnfile, testfile): 
     """Wczytuje dane uczące oraz testowe.""" 
     #read learning data 
     data_learn_tmp = [] 
     for line in learnfile: 
      if line[1] == "#": 
       continue 
      row = line.split() 
      year = float(row[0][0:4]) 
      month = float(row[0][4:6]) 
      yearmonth = int(row[0]) 
      count = float(row[2]) 
      data_learn_tmp.append([month, year, count, yearmonth]) 
     data_learn_tmp = sorted(data_learn_tmp, key=operator.itemgetter(1, 0)) 
     # read test data 
     data_test_tmp = [] 
     for line in testfile: 
      if line[0] == "#": 
       continue 
      row = line.split() 
      year = float(row[0][0:4]) 
      month = float(row[0][4:6]) 
      count = float(row[2]) 
      year_month = int(row[0]) 
      data_test_tmp.append([month, year, count, year_month]) 
     data_test_tmp = sorted(data_test_tmp, key=operator.itemgetter(1, 0)) 
     # prepare data for normalization 
     months = [item[0] for item in data_learn_tmp + data_test_tmp] 
     years = [item[1] for item in data_learn_tmp + data_test_tmp] 
     counts = [item[2] for item in data_learn_tmp + data_test_tmp] 
     self.norm.add_feature("month", months) 
     self.norm.add_feature("year", years) 
     ym = [(years[index], months[index]) for index in xrange(0, len(years))] 
     self.norm.add_feature("ym", ym, ranked=True) 
     self.norm.add_feature("count", counts) 
     #build learning data set 
     learning_set = pybrain.datasets.sequential.SequentialDataSet(2, 1) 
     #learning_set = pybrain.datasets.sequential.SupervisedDataSet(2, 1) 
     # add items to the learning dataset proper 
     last_year = -1 
     for item in data_learn_tmp: 
      if last_year != item[1]: 
       learning_set.newSequence() 
       last_year = item[1] 
      year_month = self.norm.normalize("ym", (item[1], item[0])) 
      count = self.norm.normalize("count", item[2]) 
      learning_set.appendLinked((year_month), (count)) 
     #build testing data set proper 
     words = ["N/A"] * len(data_test_tmp) 
     testing_set = [] 
     for index in range(len(data_test_tmp)): 
      month = self.norm.normalize("month", data_test_tmp[index][0]) 
      year = self.norm.normalize("year", data_test_tmp[index][3]) 
      year_month = self.norm.normalize("ym", 
         (data_test_tmp[index][4], data_test_tmp[index][0])) 
      count = self.norm.normalize("count", data_test_tmp[index][5]) 
      testing_set.append((words[index], month, year, 
           count, data_test_tmp[index][6], year_month)) 
     #learning_set, testing_set, learn_inputs, test_inputs, learn_targets 
     learn_x = [element[3] for element in data_learn_tmp] 
     test_x = [element[3] for element in data_test_tmp] 
     learn_targets = [element[2] for element in data_learn_tmp] 
     test_targets = [element[2] for element in data_test_tmp] 
     return (learning_set, testing_set, learn_x, test_x, 
       learn_targets, test_targets) 


def get_args(): 
    """Buduje parser cli.""" 
    parser = argparse.ArgumentParser(
     description='Trains a simple recurrent neural network.') 

    parser.add_argument('--inputs', type=int, default=2, 
         help='Number of input neurons.') 
    parser.add_argument('--hidden', type=int, default=5, 
         help='Number of hidden neurons.') 
    parser.add_argument('--outputs', type=int, default=1, 
         help='Number of output neurons.') 

    parser.add_argument('--iterations', type=int, default=100, 
       help='Maximum number of iteration epoch in training phase.') 

    parser.add_argument('trainfile', nargs='?', type=argparse.FileType('r'), 
         default=sys.stdin, help="File with learning dataset.") 
    parser.add_argument('testfile', nargs='?', type=argparse.FileType('r'), 
         default=sys.stdin, help="File with testing dataset.") 

    parser.add_argument('--version', action='version', version='%(prog)s 1.0') 

    return parser.parse_args() 

if __name__ == '__main__': 
    args = get_args() 
    nnetwork = Network(args.inputs, args.hidden, args.outputs) 
    learning_set, testing_set, learn_x, test_x, learn_targets, test_targets = \ 
     nnetwork.read_data(args.trainfile, args.testfile) 
    errors, rate = nnetwork.train(learning_set, args.iterations) 
    outputs, mse = nnetwork.test(testing_set) 
    nnetwork.show_plot(test_targets, outputs, 
         learn_x, test_x, learn_targets, mse) 

, 나는 내가 충분히 명성 포인트를 가지고 있지 않는 한 나는 플롯을 보여 할 수없는, 오직 혼란을 참조하십시오. 그러나 기본적으로 예측 함수는 입력 또는 과거 데이터와 많이 상관 관계가없는주기적인 이빨 모양의 곡선입니다.

Year Month Count Count_norm Output  OutDenorm Error 
2009 9  4.3  0.016942 0.216687 54.995108 -50.695108 
2009 10  4.8  0.018913 0.218810 55.534015 -50.734015 
2009 11  4.1  0.016154 0.221876 56.312243 -52.212243 
2009 12  10.8 0.042553 0.224774 57.047758 -46.247758 
2010 1  13.2 0.052009 0.184361 46.790833 -33.590833 
2010 2  18.8 0.074074 0.181018 45.942258 -27.142258 
2010 3  15.4 0.060678 0.183226 46.502806 -31.102806 

나는 두 개의 서로 다른 학습 알고리즘, 많은 숨겨진 유닛의 조합, 학습 속도, 학습 데이터 세트에 요소를 추가하는 유형의 시도했지만 아무 소용했습니다.

저는 완전히 잃었습니다.

+1

귀하의 질문을 좀 더 구체적인 것으로 바꿀 것을 제안합니다. 아무도 신경 네트워크가 실제로 어떤 문제에 부합 할 것이라고 당신에게 보증 할 수 없습니다. 정확히 무엇을 요구하고 있습니까? –

+1

@PantelisNatsiavas, 내 문제에 관심을 가져 주셔서 감사합니다. 물론 어느 누구도 주어진 문제에 신경망이 작동한다는 것을 보장 할 수 없습니다. 그러나 시계열 예측/회귀에 대한 반복적 인 신경망의 사용법을 설명하는 논문이 있습니다. 그러므로 죄 기능의 단순 회귀는 RNN의 문제가되지 않아야합니다. 나는 NN의 수렴/학습 문제를 해결할 수있는 힌트/아이디어를 요구하고 있습니다. – Bartosz

+0

목록에 샘플 내 또는 샘플 외 오류가 있습니까? – BartoszKP

답변

5

출력 레이어에서 물류 활성화 기능을 사용하는 경우 출력은 (0,1) 범위로 제한됩니다. 그러나 당신의 죄 함수는 (-1,1)의 범위의 결과를 제공합니다. 나는 이것이 당신의 죄 학습이 작은 오류로 수렴하기 어려운 이유라고 생각합니다. 당신은 당신의 훈련 데이터에서 죄 기능의 정확한 예측을 얻을 수 없습니까? 교육 및 테스트 전에 입력/출력 세트를 확장해야 할 수도 있습니다.

+0

입력에 감사드립니다. 실제로 네트워크 출력의 비늘과 sinus funtions은 다소 다릅니다. 그래서 네트워크에 입력 한 모든 것을 [0, 1] 범위로 정규화 한 다음 네트워크 출력을 원래 값으로 비정규 화합니다. 정상적인 BackPropagation 알고리즘이 RPropMinusTrainer보다 훨씬 더 효과적이라는 것을 발견했습니다. 이제 흑점 및 부비동과 같이 주변에 쌓아 두는 것이 아니라 내 실제 데이터, 즉 내가 예측하고 싶은 데이터로 작업합니다. 나는 더 나은 결과를 얻고있다. 데이터의 특성 + 일부 코드 정리 일 수 있습니다. 하지만이 질문에 내가 뭘 할까? ... – Bartosz