2017-10-11 64 views
2
import numpy as np 

alpha = 0.0251 # as close to true alpha as possible 
def nonlinear(x, deriv=False): 
    if(deriv==True): 
    return x*(1-x) 
    return 1/(1+np.e**(-x)) 

#seed 
np.random.seed(1) 

#testing sample 
test_x = np.array([[251,497,-246], 
       [299,249,50], 
       [194,180,14], 
       [140,148,-8], 
       [210,140,70]]) 
#Input Array - This input will be taken directly from a Pong game 
X = np.array([[198,200,-2], 
      [90, 280,-190], 
      [84, 256,-172], 
      [140,240,-100], 
      [114,216,-102], 
      [72, 95,-23], 
      [99, 31, 68], 
      [144, 20, 124], 
      [640, 216,424], 
      [32, 464,-432], 
      [176, 64,112], 
      [754, 506,248], 
      [107, 104,3], 
      [116,101,15]]) 

#output array - if ball_pos - paddle > 0 move up else move down 
Y = np.array([[0,0,0,0,0,0,1,1,1,0,1,1,1,1,]]).T 

syn0 = 2*np.random.random((3,14))-1 
syn1 = 2*np.random.random((14,14))-1 

for j in range(60000): 

    #forward propagation 
    l0 = X 
    l1 = nonlinear(np.dot(l0, syn0)) 
    l2 = nonlinear(np.dot(l1, syn1)) 

    #how much did we miss 
    l2_error = Y - l2 

    #multiply how much missed by the slope of sigmoid at the value in l1 
    l2_delta = l2_error * nonlinear(l2, True) 

    #how much did l1 contribute to l2 error 
    #(according to the weights) 
    l1_error = l2_delta.dot(syn1.T) 

    #in what direction is the target l1? 
    # Sure? 
    l1_delta = l1_error*nonlinear(l1,True) 

    #update weight 
    syn1 += alpha * (l1.T.dot(l2_delta)) 
    syn0 += alpha * (l0.T.dot(l1_delta)) 

    # display error 
    if(j % 10000) == 0: 
    print("ERROR: " + str(np.mean(np.abs(l2_error)))) 


#Testing Forward propagation 
l0_test = test_x 
l1_test = nonlinear(np.dot(l0_test,syn0)) 
l2_test = nonlinear(np.dot(l1_test,syn1)) 

#Dress up the array (make it look nice) 
l2_test_output = [] 
for x in range(len(l2_test)): 
    l2_test_output.append(l2_test[x][0]) 

print("Test Output") 
print(l2_test_output) 

#Put all the l2 data in a way I could see it: Just the first probabilites 
l2_output = [] 
for x in range(len(l2)): 
    l2_output.append(l2[x][0]) 

print("Output") 
print(l2_output) 

該代碼應該包含一組三個數字[(value_1),(value_2),(value_1-value_2)]並返回一個「0」如果第一個值和第二個值之間的差值爲負值,或者如果差值爲正值,則爲「1」。到目前爲止,它實際上工作得很好。如何實現代替乙狀函數的ReLU

這裏是輸出: ERROR: 0.497132186092 ERROR: 0.105081486632 ERROR: 0.102115299177 ERROR: 0.100813655802 ERROR: 0.100042420179 ERROR: 0.0995185781466 Test Output [0.0074706006801269686, 0.66687458928464094, 0.66687458928463983, 0.66686236694464551, 0.98341439176739631] Output [0.66687459245609326, 0.00083944690766060215, 0.00083946471285455484, 0.0074706634783305243, 0.0074706634765733968, 0.007480987498372226, 0.99646513183073093, 0.99647100131874755, 0.99646513180692531, 0.00083944572383107523, 0.99646513180692531, 0.98324165810211861, 0.66687439729829612, 0.66687459321626519] ERROR:0.497132186092

正如你可以看到給定的α誤差= 0.0251(對於梯度下降 - 發現這個通過試驗和錯誤)僅爲約9.95%。

因爲我做了這個節目,我瞭解到,泄漏RELU是S型函數一個更好的選擇,因爲它優化和學習比乙狀結腸更快。我想在這個程序中使用numpy實現泄漏的RelU函數,但我不確定從哪裏開始,更特別是它的衍生物。

我如何能實現泄漏RELU到這個神經網絡?

+0

它優化和學習不是隻在特定條件下乙狀結腸快(它缺乏一些乙狀結腸缺點,但有它自己的,例如所謂的「死RELU」的問題等等等等,這一切都複雜得多),如果你還需要你的網要返回0和1之間的值,您將需要S形或無論如何它是接近的替代,因爲relu是無界的。如果你想自己設計神經網絡,我開始的地方在這裏:https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b – Bob

+0

謝謝你的信息。我希望我的網絡返回0到1之間的值,因爲我需要它返回經典概率。我有一個關於ReLU函數的問題,爲什麼有人需要一個不輸出0和1之間的值的函數,這是否意味着sigmoid函數和ReLU函數是不可互換的?另外我可能會不小心標記了你的評論。 –

回答

0

我想在這裏補充一點,其實是有一個廣泛的RELU樣激活功能,可以用來代替標準ReLu activation

elu formula

  • Scaled exponential linear unit(九色鹿)已經非常最近出版。它是ELU的擴展,具有特定的參數選擇,具有額外的標準化效果並有助於更快地學習。

Here's the list所有激活及其衍生物。