2016-09-30 19 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') 

出力数値は以下の通りである:

は、ここに私はPython 2.7のコードです。

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

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

最初の数字は良好な結果を示しているが、両方の出力が不十分です。私はいくつかの基本的なニューラルネットワークの原理を欠いているのですか?この場合、ターゲット信号を推定する簡単な統計的方法があることはわかっていますが、ここでは簡単なNN構造を使用することを目的としています。

答えて

0

問題は入力値と出力値の範囲です。これらの信号によってstandardizingは、問題が解決されます。

NN input and output signal

これは以下の表示、シグモイドTANH活性化関数を考慮することによって説明することができます。 sigmoid and tanh activation functions

結果は特定のアプリケーションによって異なります。また、アクティベーション機能(this answerを参照)を変更すると、入力信号と出力信号の最適なスケーリング値に影響する可能性があります。

-1

少しチューニングすれば(より多くの学習ステップ)、ニューラルネットワークで正確に洞の機能を予測することができます。ニューラルネットワークの限界を決定するために、「逆運動学」の予測がより有用であろう。この例では、ほとんどのニューラルネットワークは、ソルバーが結果を出さずに高いCPU要求を生成するため、失敗します。ニューラルネットワークの限界をテストするもう1つの例は、ゲームによる強化学習の問題です。

ニューラルネットワークの失望の側面は、容易な数学的機能を予測することができますが、複雑な領域では失敗するということです。 「簡単」は、ソルバー(Backproptrainer)が特定の精度に達するためにCPUパワーを低くする必要があるすべての問題が定義されているためです。

+0

これ以上の学習ステップでは、予測が改善されません。この問題は出力飽和と思われます。入力値と出力値をスケーリングすることにより、より良い予測を達成することができます。 – aslan

関連する問題