2012-12-15 53 views
11

爲了學習的目的,我實現了一個簡單的神經網絡框架,它只支持多層感知器和簡單的反向傳播。對於線性分類和通常的XOR問題,它的工作原理沒問題,但對於正弦函數逼近,結果並不令人滿意。用神經網絡逼近正弦函數

我基本上試圖用一個由6-10個神經元組成的隱藏層來逼近正弦函數的一個週期。網絡使用雙曲線切線作爲隱藏層的激活函數和輸出的線性函數。結果仍然是對正弦波的相當粗略的估計,需要很長的時間來計算。

我看着encog參考,但即使有,我不能把它簡單的反向傳播的工作(通過切換到彈性傳播它開始變得更好,但仍比提供in this similar question超光滑[R腳本的方式更糟糕)。那麼我是否真的想做一些不可能的事情?用簡單的反向傳播(無動量,沒有動態學習速率)是否無法逼近正弦? R中神經網絡庫使用的實際方法是什麼?

編輯:我知道這肯定是可能找到一個足夠好的近似,即使簡單的反向傳播(如果你與你的初始權重非常幸運),但其實我更想知道這是否是一個可行的辦法。與我的實現相比,我鏈接到的R腳本看起來似乎非常快速且穩健地收斂(在40個時期,只有很少的學習樣本),甚至是encog的彈性傳播。我只是想知道我是否可以做些什麼來改進反向傳播算法以獲得相同的性能,還是需要研究一些更高級的學習方法?

+0

你有沒有得到它的工作?面對同樣的問題。 –

+0

不要這麼想,但是因爲這是4年前,所以不能真正回憶所有的細節。上面提到的nnet包是用C實現的,只有700行代碼,然後一些R包裝在它的上面。也許看看會給你一些想法。 – Muton

回答

1

你絕對不是在爲不可能的事情而努力。神經網絡是universal approximators - 這意味着對於任何函數F和誤差E,存在可以與誤差小於E.近似˚F一些神經網絡(僅需要單個隱藏層)

當然,發現(那些)網絡是完全不同的問題。我可以告訴你最好是試錯......這裏的基本步驟:

  1. 將數據分成兩個部分:訓練集(〜2/3)和測試組(〜三分之一)。
  2. 在訓練集中的所有項目上訓練您的網絡。
  3. 在測試集中的所有項目上測試(但不要訓練)您的網絡並記錄平均誤差。
  4. 重複第2步和第3步,直到您達到最小測試錯誤(當網絡開始超越訓練數據而損害其他所有內容時發生「過度配合」),或者直到您的整體錯誤消失明顯下降(意味着網絡和它將要獲得的一樣好)。
  5. 如果在這一點上的錯誤是可接受的低,你就完成了。否則,你的網絡不夠複雜,無法處理你正在訓練的功能;添加更多隱藏的神經元,並回到開始...

有時更改您的激活函數也可以有所作爲(只是不要使用線性,因爲它否定了添加更多圖層的能力)。但是,再次看到什麼效果最好,這將是試錯。

希望有幫助(對不起,我不能更有用)!

PS:我也知道這是可能的,因爲我已經看到有人近似與網絡正弦。我想說她利用S形激活函數不是,但我不能保證我的記憶對個性化......

+0

謝謝!這實際上是我已經在做的事情,如果我有點不清楚,我很抱歉。我知道這是*可能*,但更多地試圖找出我使用的簡單學習方法對於這個特定問題是否可行? – Muton

+0

@Muton - Gotcha。在這種情況下,我唯一的提示是爲當前的設置添加一個動量項。應該在兩個方面提供幫助:它會加快學習的速度,並讓你擺脫一些當地的最低限度。儘管如此,我無法想象它會帶來巨大的性能差異。 –

3

這可以通過使用現代框架像TensorFlow神經網絡可以比較容易地實現。

例如,使用每層火車100元在我的電腦上幾秒鐘,兩層的神經網絡提供了一個很好的近似:

enter image description here

代碼也很簡單:

import tensorflow as tf 
import numpy as np 

with tf.name_scope('placeholders'): 
    x = tf.placeholder('float', [None, 1]) 
    y = tf.placeholder('float', [None, 1]) 

with tf.name_scope('neural_network'): 
    x1 = tf.contrib.layers.fully_connected(x, 100) 
    x2 = tf.contrib.layers.fully_connected(x1, 100) 
    result = tf.contrib.layers.fully_connected(x2, 1, 
               activation_fn=None) 

    loss = tf.nn.l2_loss(result - y) 

with tf.name_scope('optimizer'): 
    train_op = tf.train.AdamOptimizer().minimize(loss) 

with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 

    # Train the network 
    for i in range(10000): 
     xpts = np.random.rand(100) * 10 
     ypts = np.sin(xpts) 

     _, loss_result = sess.run([train_op, loss], 
            feed_dict={x: xpts[:, None], 
              y: ypts[:, None]}) 

     print('iteration {}, loss={}'.format(i, loss_result)) 
+2

你的代碼實際上實現了3層神經網絡,而不是2層。命名方案包含隱藏層和輸出層,因此您的三個圖層分別爲「x1」,「x2」和「結果」。 – stackoverflowuser2010