2016-09-30 3 views
1

신경망과 pybrain을 이해하기 위해 입력으로 시간 인덱스만을 사용하여 잡음의 사인파 함수를 예측하려고했습니다. 따라서 전제는 간단한 NN 구조가 을 모방 할 수 있다는 것입니다. y (t) = sin (t).pybrain을 사용한 사인 곡선 함수의 예측

디자인은 입력 레이어 1 개 (선형), 숨겨진 레이어 1 개 (tanh) 및 출력 레이어 1 개 (선형)입니다. 노드의 수는 각 계층마다 1,10,1입니다.

입력 (시간 변수 )는 그 범위 되도록 스케일링된다 [0,1]. 범위가 [0; 1] 또는 [-1; 1] 인 결과가 다른 범위로 조정됩니다 (아래 명시).

#!/usr/bin/python 
from __future__ import division 
import numpy as np 
import pylab as pl 

from pybrain.structure import TanhLayer, LinearLayer #SoftmaxLayer, SigmoidLayer 
from pybrain.datasets import SupervisedDataSet 
from pybrain.supervised.trainers import BackpropTrainer 
from pybrain.structure import FeedForwardNetwork 
from pybrain.structure import FullConnection 

np.random.seed(0) 
pl.close('all') 

#create NN structure: 
net = FeedForwardNetwork() 
inLayer = LinearLayer(1) 
hiddenLayer = TanhLayer(10) 
outLayer = LinearLayer(1) 

#add classes of layers to network, specify IO: 
net.addInputModule(inLayer) 
net.addModule(hiddenLayer) 
net.addOutputModule(outLayer) 

#specify how neurons are to be connected: 
in_to_hidden = FullConnection(inLayer, hiddenLayer) 
hidden_to_out = FullConnection(hiddenLayer, outLayer) 

#add connections to network: 
net.addConnection(in_to_hidden) 
net.addConnection(hidden_to_out) 

#perform internal initialisation: 
net.sortModules() 

#construct target signal: 
T = 1 
Ts = T/10 
f = 1/T 
fs = 1/Ts 

#NN input signal: 
t0 = np.arange(0,10*T,Ts) 
L = len(t0) 

#NN target signal: 
x0 = 10*np.cos(2*np.pi*f*t0) + 10 + np.random.randn(L) 

#normalise input signal: 
t = t0/np.max(t0) 

#normalise target signal to fit in range [0,1] (min) or [-1,1] (mean): 
dcx = np.min(x0) #np.min(x0) #np.mean(x0) 
x = x0-dcx 
sclf = np.max(np.abs(x)) 
x /= sclf 

#add samples and train NN: 
ds = SupervisedDataSet(1, 1) 
for c in range(L): 
ds.addSample(t[c], x[c]) 

trainer = BackpropTrainer(net, ds, learningrate=0.01, momentum=0.1) 

for c in range(20): 
e1 = trainer.train() 
print 'Epoch %d Error: %f'%(c,e1) 

y=np.zeros(L) 
for c in range(L): 
#y[c] = net.activate([x[c]]) 
y[c] = net.activate([t[c]]) 

yout = y*sclf 
yout = yout + dcx 

fig1 = pl.figure(1) 
pl.ion() 

fsize=8 
pl.subplot(211) 
pl.plot(t0,x0,'r.-',label='input') 
pl.plot(t0,yout,'bx-',label='predicted') 
pl.xlabel('Time',fontsize=fsize) 
pl.ylabel('Amplitude',fontsize=fsize) 
pl.grid() 
pl.legend(loc='lower right',ncol=2,fontsize=fsize) 
pl.title('Target range = [0,1]',fontsize=fsize) 

fig1name = './sin_min.png' 
print 'Saving Fig. 1 to:', fig1name 
fig1.savefig(fig1name, bbox_inches='tight') 

출력 수치는 아래와 같다 :

여기 내 파이썬 2.7 코드입니다.

Output when target is scaled to fit range *[-1;1]*

첫번째 숫자는 더 좋은 결과를 나타내지 만

Output when target is scaled to fit range *[0;1]*

는 두 출력은 만족스럽지 못하다. 근본적인 신경 네트워크 원리가 없거나 결함이 있습니까? 이 경우 대상 신호를 예측하는 통계 방법이 더 쉽다는 것을 알고 있습니다 만 목표는 간단한 NN 구조를 사용하는 것입니다.

답변

0

문제는 입력 값과 출력 값의 범위입니다. 이 신호로 standardizing함으로써 문제가 해결되었습니다.

NN input and output signal

는 S 자형을하고 TANH 활성화 함수를 고려함으로써 설명 될 수 있고, 아래에 표시. sigmoid and tanh activation functions

결과는 특정 응용 프로그램에 따라 다릅니다. 또한 활성화 함수 (this answer 참조)를 변경하면 입력 및 출력 신호의 최적 스케일링 값에 영향을 미칠 수 있습니다.

-1

약간의 튜닝 (더 많은 학습 단계)을 사용하면 신경 네트워크로 정확하게 부비동 기능을 예측할 수 있습니다. 신경망의 한계를 결정하기 위해 "inverse kinematics"의 예측이 더 유용 할 것입니다. 이 예에서 대부분의 신경망은 아무런 결과없이 높은 CPU 요구를 생성하기 때문에 실패합니다. 신경 네트워크의 한계를 시험하기위한 또 다른 예는 게임의 강화 학습 문제입니다.

신경망의 실망스러운 측면은 쉽게 수학적 기능을 예측할 수 있지만 복잡한 영역에서는 실패한다는 것입니다. "쉬운"은 솔버 (Backproptrainer)가 주어진 정확도에 도달하기 위해 낮은 CPU 파워를 필요로하는 모든 문제로 정의됩니다.

+0

더 많은 학습 단계는이 경우 예측을 향상시키지 않습니다. 이 문제는 출력 포화 상태 인 것 같습니다. 입력 및 출력 값을 스케일링함으로써 훨씬 더 나은 예측을 달성 할 수 있습니다. – aslan

관련 문제