2017-10-11 4 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) 

Ce code est supposé prendre un groupe de trois nombres [(valeur_1), (valeur_2), (valeur_1-valeur_2)] et retourner soit un "0" si la différence entre la première et la deuxième valeur est négative ou un "1" si la différence est positive. Jusqu'à présent, cela fonctionne très bien.Comment implémenter ReLU à la place de la fonction sigmoïde

Voici la sortie: 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] ERREUR: ,497132186092

Comme vous pouvez le voir l'erreur étant donné l'alpha = 0,0251 (pour une descente de gradient - trouvé cet par essai et erreur) est seulement d'environ 9,95%. Depuis que j'ai fait ce programme, j'ai appris que le RelU qui fuit est une meilleure alternative à la fonction Sigmoïde puisqu'il optimise et apprend plus rapidement que le Sigmoïde. Je veux implémenter la fonction RelU qui fuit en utilisant numpy dans ce programme mais je ne suis pas sûr de savoir par où commencer et plus particulièrement ce qu'est sa dérivée. Comment puis-je implémenter RelU qui fuit dans ce réseau neuronal?

+0

il optimise et apprend plus rapidement que le sigmoïde uniquement dans des conditions spécifiques (il manque certains inconvénients sigmoïdes mais a son propre, par exemple le soi-disant "problème relu" etc etc, c'est beaucoup plus compliqué), aussi si vous avez besoin de votre net pour renvoyer des valeurs entre 0 et 1, vous aurez besoin de sigmoïde ou de son alternative de toute façon, car relu est illimité. Si vous voulez vous-même concevoir des réseaux de neurones, je commencerais quelque part par ici: https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b – Bob

+0

Merci pour cette information. Je voudrais que mon réseau renvoie des valeurs entre 0 et 1 car j'en ai besoin pour retourner des probabilités classiques. J'ai une question à propos de la fonction ReLU, pourquoi quelqu'un aurait-il besoin d'une fonction qui ne produit pas de valeur entre 0 et 1 et cela signifie-t-il que les fonctions sigmoïde et ReLU ne sont pas interchangeables? Aussi, j'ai peut-être accidentellement signalé votre commentaire. –

Répondre

0

Je voudrais ajouter ici qu'il ya effectivement un large éventail de fonctions d'activation comme Relu qui peut être utilisé à la place de la norme ReLu activation:

  • Vous avez mentionné Leaky Relu vous (par paramétrés alpha).
  • Parametric Rectified Linear Unit (PReLU). La formule est la même que Leaky ReLu, mais permet d'apprendre le coefficient alpha. Voir aussi this discussion.
  • Exponential linear unit (ELU), qui tentent de faire les activations moyennes plus proche de zéro, ce qui accélère l'apprentissage:

elu formula

  • Scaled exponential linear unit (SELU) a été publié récemment. C'est une extension d'ELU, avec un choix de paramètre spécifique, qui a un effet de normalisation supplémentaire et aide à apprendre plus rapidement.

Here's the list de toutes les activations et de leurs dérivés.