[PYTHON] <Cours> Apprentissage en profondeur: Jour 1 NN

sutudy-ai


Apprentissage en profondeur

[Apprentissage en profondeur: Day1 NN] (https://qiita.com/matsukura04583/items/6317c57bc21de646da8e) [Apprentissage en profondeur: Day2 CNN] (https://qiita.com/matsukura04583/items/29f0dcc3ddeca4bf69a2) [Apprentissage en profondeur: Day3 RNN] (https://qiita.com/matsukura04583/items/9b77a238da4441e0f973) [Deep learning: Day4 Strengthening learning / Tensor Flow] (https://qiita.com/matsukura04583/items/50806b750c8d77f2305d)

Deep Learning: Day1 NN (Résumé de la conférence)

Section 1) Couche d'entrée vers couche intermédiaire

NN01.jpg

NN02.jpg

Section 2) Fonction d'activation

Formule

f(x) = \left\{
\begin{array}{ll}
1 & (x \geq 0) \\
0 & (x \lt 0)
\end{array}
\right.

python


def 
step_function(x):
 if x > 0:
    return 1
 else:
    return 0

Formule

f(u) =  \frac{1}{1+e^{-u}}

python


def sigmoid(x):
  return 1/(1 + np.exp(-x))

C'est une fonction qui change lentement entre 0 et 1, et il est devenu possible de transmettre la force du signal à l'état où la fonction d'étape n'a que ON / OFF, ce qui a déclenché la propagation de réseaux de neurones prédictifs. Tâche À des valeurs élevées, le changement de sortie est faible, ce qui peut entraîner un problème de disparition du gradient.

f(x) = \left\{
\begin{array}{ll}
x & (x \gt 0) \\
0 & (x \leq 0)
\end{array}
\right.

python


def relu(x):
   return 
np.maximum(0, x)

La fonction d'activation la plus utilisée actuellement De bons résultats ont été obtenus en contribuant à éviter le problème de disparition du gradient et en le rendant clairsemé.

Section3) Couche de sortie

3-1 Fonction d'erreur

nn04.jpg Calcul d'erreur Fonction d'erreur = erreur carrée

En(w)=\frac{1}{2}\sum_{j=1}^{I} (y_j-d_j)^2 = \frac{1}{2}||(y-d)||^2

3-2 Fonction d'activation de la couche de sortie

En(w)=-\sum_{i=1}^Id_ilog y_i

python


#Entropie croisée
def cross_entropy_error(d, y):
    if y.ndim == 1:
        d = d.reshape(1, d.size)
        y = y.reshape(1, y.size)
        
    #Les données des enseignants en sont une-hot-Pour le vecteur, convertissez en index de l'étiquette correcte
    if d.size == y.size:
        d = d.argmax(axis=1)
             
    batch_size = y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size

Un vecteur one-hot est un vecteur tel que (0,1,0,0,0,0,0) où un composant est 1 et les composants restants sont tous 0. (Référence) Qu'est-ce qu'un vecteur One-hot?

Section 4) Méthode de descente de gradient

(Référence) Site d'explication de la méthode de descente de gradient

$ W ^ {(t + 1)} = W ^ {(t)} - \ varepsilon \ nabla Et (\ varepsilon est le taux d'apprentissage) $ ・ ・ ・ Méthode de descente de gradient en mini batch
E_t=\frac{1}{N_t}\sum_{n\in D_t}E_n
N_t=|D_t|

La méthode de descente de gradient mini-batch est un ensemble d'erreur moyenne de données extraites aléatoirement () mini-batch) d'échantillons appartenant à $ D_t $

Avantages de la méthode de descente de gradient mini-batch Utilisation efficace des ressources informatiques sans compromettre les mérites de la méthode de descente de gradient stochastique → Parallélisation des threads à l'aide de la parallélisation CPU et SIMD à l'aide de GPU

Section 5) Méthode de propagation de retour d'erreur

Calcul du gradient d'erreur - méthode de rétropropagation [Méthode de propagation de l'erreur en retour] L'erreur calculée est différenciée dans l'ordre du côté de la couche de sortie et propagée à la couche avant la couche précédente. Une méthode pour calculer analytiquement la valeur différentielle de chaque paramètre avec le calcul minimum nn07.jpg nn08.jpg En rétrocalculant le différentiel à partir du résultat du calcul (= erreur), le différentiel peut être calculé tout en évitant les calculs récursifs inutiles. nn09.jpg

python


#Erreur de propagation de retour
def backward(x, d, z1, y):
    print("\n#####Démarrer la propagation de l'erreur de retour#####")

    grad = {}

    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']
    #Delta à la couche de sortie
    delta2 = functions.d_sigmoid_with_loss(d, y)
    #pente de b2
    grad['b2'] = np.sum(delta2, axis=0)
    #Dégradé W2
    grad['W2'] = np.dot(z1.T, delta2)
    #Delta dans la couche intermédiaire
    delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)
    #pente de b1
    grad['b1'] = np.sum(delta1, axis=0)
    #Dégradé W1
    grad['W1'] = np.dot(x.T, delta1)
        
    print_vec("Différenciation partielle_dE/du2", delta2)
    print_vec("Différenciation partielle_dE/du2", delta1)

    print_vec("Différenciation partielle_Poids 1", grad["W1"])
    print_vec("Différenciation partielle_Poids 2", grad["W2"])
    print_vec("Différenciation partielle_Biais 1", grad["b1"])
    print_vec("Différenciation partielle_Biais 2", grad["b2"])

    return grad
    

Prise en compte du test de confirmation

[P10] En apprentissage profond, décrivez ce que vous essayez de faire en deux lignes ou moins. De plus, laquelle des valeurs suivantes est le but ultime de l'optimisation? Choisir tous. ① Valeur d'entrée [X] ② Valeur de sortie [Y] ③ Poids [W] ④ Biais [b] ⑤ Entrée totale [u] ⑥ Entrée de couche intermédiaire [z] ⑦ Taux d'apprentissage [ρ]

⇒ [Discussion] Après tout, l'apprentissage en profondeur vise à déterminer les paramètres qui minimisent l'erreur. Le but ultime de l'optimisation des valeurs est (3) poids [W] et (4) biais [b].

[P12] Mettez le réseau suivant sur papier.

⇒ [Discussion] IMG_2280.jpg C'est facile à comprendre si vous l'écrivez vous-même.

[P19] Test de confirmation Mettons un exemple de classification animale dans ce schéma![P19.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357717/6a0b680d-9466-598d- 67e9-d9156a754193.gif)

⇒ [Discussion] p19.jpg

[P21] Test de confirmation

Écrivez cette expression en python

u=w_1x_1+w_2x_2+w_3x_3+w_4x_4+b=Wx+b..(1.2)

⇒ [Discussion]

pyhon


u1=np.dot(x,W1)+b1

[P23] Test de confirmation Extraire le code qui représente la couche intermédiaire

⇒ [Discussion]

pyhon


#Entrée totale de la couche cachée
u1 = np.dot(x, W1) + b1
#Sortie totale de la couche cachée
z1 = functions.relu(u1)

[P26] Test de confirmation Expliquez la différence entre linéaire et non linéaire avec un diagramme.

IMG_0101.jpg

[P34] Test de confirmation NN-monocouche entièrement couplé, plusieurs nœuds nn03.jpg Extrayez la partie appropriée du code source distribué. ⇒ [Discussion] C'est la partie car la fonction d'activation f (u) est une fonction sigmoïde.

python


z1 = functions.sigmoid(u)

[P34] Test de confirmation Calcul d'erreur Fonction d'erreur = erreur carrée

En(w)=\frac{1}{2}\sum_{j=1}^{I} (y_j-d_j)^2 = \frac{1}{2}||(y-d)||^2

・ Décrivez pourquoi vous mettez au carré au lieu de soustraire ・ Décrivez ce que signifie la moitié de la formule ci-dessous.

⇒ [Discussion] ・ Pour exprimer la dispersion comme un plus ・ 1/2 est la valeur moyenne (Référence) Le site ici était facile à comprendre Signification de la méthode des moindres carrés et de la méthode de calcul-Comment trouver la ligne de régression

[P51] Test de confirmation (fonction layer_activation de sortie S3_2) Fonction Softmax

①f(i,u)=\frac{e^{u_i}②}{\sum_{k=1}^{k}e^{u_k}③}

Montrez le code source correspondant aux formules (1) à (3) et expliquez ligne par ligne.

python


def softmax(x):
   if x.ndim == 2:#Si c'était bidimensionnel
     x = x.Tx
     x = x-np.max(x, axis=0)
     y = np.exp(x) /np.sum(np.exp(x), axis=0)
      return y.T
 x = x -np.max(x) #Mesures de débordement
      return np.exp(x) / np.sum(np.exp(x))

① ・ ・ ・ ・ y (retour du retour y.T) ② ・ ・ ・ ・ np.exp (x) partie ③ ・ ・ ・ ・ np.sum (np.exp (x), axis = 0) partie

(Référence d'apprentissage) Que signifient l'axe de NumPy et le nombre de dimensions (ndim)

[P53] Test de confirmation(S3_2 Couche de sortie_Fonction d'activation)
Entropie croisée
①~Montrez le code source qui correspond à la formule en 2 et expliquez le processus ligne par ligne.

```math
En(w)=-\sum_{i=1}^Id_ilog y_i

En(w)・ ・ ・ Partie ① -\sum_{i=1}^Id_ilog y_i・ ・ ・ Partie ②

⇒ [Discussion] · Revenir-np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size · 1/2 prend la valeur moyenne

python


# Entropie croisée
def cross_entropy_error(d, y):
    if y.ndim == 1:
        d = d.reshape(1, d.size)
        y = y.reshape(1, y.size)
        
 # Si les données de l'enseignant sont un vecteur chaud, convertissez-les en index de l'étiquette de réponse correcte
    if d.size == y.size:
        d = d.argmax(axis=1)
             
    batch_size = y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size

En(w)・ ・ ・ Part ① est la valeur de retour -\sum_{i=1}^Id_ilog y_i・ ・ ・ Partie ② -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_La partie taille.

[P56] Test de confirmation(Méthode de descente de gradient S4) Trouvez le code source approprié pour la fonction de descente de gradient.

W^{(t+1)} =W^{(t)}-\varepsilon\nabla E_n (\varepsilon a un taux d'apprentissage)・ ・ ・ ・ ① \nabla E=\frac{\partial E}{\partial W}=[\frac{\partial E}{\partial w_1}・ ・ ・\frac{\partial E}{\partial w_M}]・ ・ ・ ・ ②

⇒ [Discussion]

python


# Erreur
loss = functions.cross_entropy_error(d, y)

 grad = backward (x, d, z1, y) # Correspond à la partie ②
for key in ('W1', 'W2', 'b1', 'b2'):
 réseau [clé] - = taux_apprentissage * grad [clé] # ①

[P65] Test de confirmation(Méthode de descente de gradient S4) Résumez ce qu'est l'apprentissage en ligne. ⇒ [Discussion] L'apprentissage en ligne signifie qu'un modèle d'apprentissage peut être créé en utilisant uniquement des données nouvellement acquises. Il peut être tourné sans utiliser les données existantes.

[P69] Test de confirmation(Méthode de descente de gradient S4) Expliquez la signification de cette formule dans un diagramme. + W^{(t+1)} =W^{(t)}-\varepsilon\nabla Et (\varepsilon a un taux d'apprentissage)・ ・ ・ Méthode de descente de gradient par mini lot
⇒ [Discussion] (〇〇〇) (〇〇〇) (〇〇〇) Ensemble 1 Ensemble 2 Ensemble 3 Dans ce cas, additionnez les erreurs en utilisant un ensemble de données comme un ensemble de mini-lots, et 1/3   E_t=\frac{1}{N_t}\sum_{n\in D_t}E_n    N_t=|D_t|
[P78] Test de confirmation(Méthode de propagation de l'erreur S5) La méthode de propagation de retour d'erreur peut éviter un traitement récursif inutile. Extrayez le code source qui contient les résultats des calculs que vous avez déjà effectués.

python



# Erreur de propagation de retour
def backward(x, d, z1, y):
 print ("\ n ##### Erreur de début de propagation de retour #####")

    grad = {}

    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']
 #Delta dans la couche de sortie ## Ici, calculez la dérivée de la fonction qui combine la fonction sigmoïde et l'entropie croisée, et remplacez-la par "delta2".
    delta2 = functions.d_sigmoid_with_loss(d, y)
 # b2 gradient ## Utilisation de "delta2"
    grad['b2'] = np.sum(delta2, axis=0)
 # W2 gradient ## Utilisation de "delta2"
    grad['W2'] = np.dot(z1.T, delta2)
 # Delta dans la couche intermédiaire ## Utilisation de "delta2"
    delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)
 Gradient de # b1
    grad['b1'] = np.sum(delta1, axis=0)
 # W1 dégradé
    grad['W1'] = np.dot(x.T, delta1)
        
 print_vec ("partiellement différencié_dE / du2", delta2)
 print_vec ("partiellement différencié_dE / du2", delta1)

 print_vec ("poids_ partiellement différencié 1", grad ["W1"])
 print_vec ("poids_ partiellement différencié 2", grad ["W2"])
 print_vec ("biais_partiellement différencié 1", grad ["b1"])
 print_vec ("biais_partiellement différencié 2", grad ["b2"])

    return grad

[P83] Trouvez le code source qui correspond aux deux blancs(Méthode de propagation de l'erreur S5) \frac{\partial E}{\partial y} \frac{\partial y}{\partial u}

python


# Delta à la couche de sortie
    delta2 = functions.d_mean_squared_error(d, y)

\frac{\partial E}{\partial y} \frac{\partial y}{\partial u} \frac{\partial u}{\partial w _{ji}^{(2)}}

python


# Delta à la couche de sortie
 # W2 dégradé
    grad['W2'] = np.dot(z1.T, delta2)

#Exercice

DN06_Exercice Jupyter

python



# Essayons #


# Propagation vers l'avant (monocouche / unité unique)

# poids
W = np.array([[0.1], [0.2]])

## Essayons l'initialisation du tableau _
W = np.zeros(2)
 W = np.ones (2) # Sélectionnez ici
W = np.random.rand(2)
W = np.random.randint(5, size=(2))

 print_vec ("poids", W)


# biais
b = 0.5

## Essayons _ Initialisation numérique
 b = np.random.rand () # Nombre aléatoire de 0 à 1 # Sélectionnez ici
# b = np.random.rand () * 10-5 # -5 ~ 5 nombres aléatoires

 print_vec ("biais", b)

# Valeur d'entrée
x = np.array([2, 3])
 print_vec ("entrée", x)


# Entrée totale
u = np.dot(x, W) + b
 print_vec ("entrée totale", u)

# Sortie de couche intermédiaire
z = functions.relu(u)
 print_vec ("sortie couche intermédiaire", z)

poids [1. 1.]

biais 0.15691869859919338

contribution [2 3]

Entrée totale 5.156918698599194

Sortie de couche intermédiaire 5.156918698599194

python



# Essayons #

# Propagation vers l'avant (une seule couche / plusieurs unités)

# poids
W = np.array([
  [0.1, 0.2, 0.3],
  [0.2, 0.3, 0.4], 
  [0.3, 0.4, 0.5],
  [0.4, 0.5, 0.6]
  ])

## Essayons l'initialisation du tableau _
W = np.zeros((4,3))
 W = np.ones ((4,3)) # Sélectionnez ici
W = np.random.rand(4,3)
W = np.random.randint(5, size=(4,3))

 print_vec ("poids", W)

# biais
b = np.array([0.1, 0.2, 0.3])
 print_vec ("biais", b)

# Valeur d'entrée
x = np.array([1.0, 5.0, 2.0, -1.0])
 print_vec ("entrée", x)


# Entrée totale
u = np.dot(x, W) + b
 print_vec ("entrée totale", u)

# Sortie de couche intermédiaire
z = functions.sigmoid(u)
 print_vec ("sortie couche intermédiaire", z)

poids [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]

biais [0.1 0.2 0.3]

contribution [ 1. 5. 2. -1.]

Entrée totale [7.1 7.2 7.3]

Sortie de couche intermédiaire [0.99917558 0.99925397 0.99932492]

python



# Essayons #

# Classification multi-classes
# 2-3-4 réseau

# !! Essayons _ Changeons la configuration du nœud en 3-5-4

# Définir le poids et le biais
# Créer Natework
def init_network():
 print ("##### Initialisation du réseau #####")

 #Essayons
 #_ Afficher la forme de chaque paramètre
 #_ Génération aléatoire de la valeur initiale du réseau

    network = {}
    network['W1'] = np.array([
        [0.1, 0.4, 0.7, 0.1, 0.3],
        [0.2, 0.5, 0.8, 0.1, 0.4],
        [0.3, 0.6, 0.9, 0.2, 0.5]
    ])
    network['W2'] = np.array([
        [0.1, 0.6, 0.1, 0.6],
        [0.2, 0.7, 0.2, 0.7],
        [0.3, 0.8, 0.3, 0.8],
        [0.4, 0.9, 0.4, 0.9],
        [0.5, 0.1, 0.5, 0.1]
    ])
    network['b1'] = np.array([0.1, 0.2, 0.3, 0.4, 0.5])
    network['b2'] = np.array([0.1, 0.2, 0.3, 0.4])
    
 print_vec ("poids 1", réseau ['W1'])
 print_vec ("poids 2", réseau ['W2'])
 print_vec ("biais 1", réseau ['b1'])
 print_vec ("biais 2", réseau ['b2'])

    return network

# Créer un processus
# x: valeur d'entrée
def forward(network, x):
    
 print ("##### Démarrer la propagation #####")
    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']
    
 Entrée totale de la couche n ° 1
    u1 = np.dot(x, W1) + b1

 Sortie totale de la couche n ° 1
    z1 = functions.relu(u1)

 # 2 couches d'entrée totale
    u2 = np.dot(z1, W2) + b2
    
 # Valeur de sortie
    y = functions.softmax(u2)
    
 print_vec ("entrée totale 1", u1)
 print_vec ("Sortie couche intermédiaire 1", z1)
 print_vec ("entrée totale 2", u2)
 print_vec ("sortie 1", y)
 print ("sortie totale:" + str (np.sum (y)))
        
    return y, z1

## Données préliminaires
# Valeur d'entrée
x = np.array([1., 2., 3.])

# Sortie cible
d = np.array([0, 0, 0, 1])

# Initialisation du réseau
network =  init_network()

# production
y, z1 = forward(network, x)

# Erreur
loss = functions.cross_entropy_error(d, y)

## afficher
 print ("\ n ##### Affichage des résultats #####")
 print_vec ("sortie", y)
 print_vec ("données d'apprentissage", d)
 print_vec ("erreur", perte)

#####Initialisation du réseau##### Poids 1 [[0.1 0.4 0.7 0.1 0.3] [0.2 0.5 0.8 0.1 0.4] [0.3 0.6 0.9 0.2 0.5]]

Poids 2 [[0.1 0.6 0.1 0.6] [0.2 0.7 0.2 0.7] [0.3 0.8 0.3 0.8] [0.4 0.9 0.4 0.9] [0.5 0.1 0.5 0.1]]

Biais 1 [0.1 0.2 0.3 0.4 0.5]

Biais 2 [0.1 0.2 0.3 0.4]

#####Commencer la propagation vers l'avant##### Total entrée 1 [1.5 3.4 5.3 1.3 3.1]

Sortie de couche intermédiaire 1 [1.5 3.4 5.3 1.3 3.1]

Total entrée 2 [4.59 9.2 4.79 9.4 ]

Sortie 1 [0.00443583 0.44573018 0.00541793 0.54441607]

Total de sortie: 1.0

#####Affichage des résultats##### production [0.00443583 0.44573018 0.00541793 0.54441607]

Données d'entraînement [0 0 0 1]

Erreur 0.6080413107681358

python



# Essayons #


# Revenir
# 2-3-2 Réseau

# !! Essayons _ Changeons la configuration du nœud en 3-5-4

# Définir le poids et le biais
# Créer Natework
def init_network():
 print ("##### Initialisation du réseau #####")

    network = {}
    network['W1'] = np.array([
        [0.1, 0.4, 0.7, 0.1, 0.3],
        [0.2, 0.5, 0.8, 0.1, 0.4],
        [0.3, 0.6, 0.9, 0.2, 0.5] 
    ])
    network['W2'] = np.array([
       [0.1, 0.6, 0.1, 0.6],
        [0.2, 0.7, 0.2, 0.7],
        [0.3, 0.8, 0.3, 0.8],
        [0.4, 0.9, 0.4, 0.9],
        [0.5, 0.1, 0.5, 0.1]
    ])
    network['b1'] = np.array([0.1, 0.2, 0.3, 0.4, 0.5])
    network['b2'] = np.array([0.1, 0.2, 0.3, 0.4])
    
 print_vec ("poids 1", réseau ['W1'])
 print_vec ("poids 2", réseau ['W2'])
 print_vec ("biais 1", réseau ['b1'])
 print_vec ("biais 2", réseau ['b2'])

    return network

# Créer un processus
def forward(network, x):
 print ("##### Démarrer la propagation #####")
    
    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']
 # Entrée totale de la couche masquée
    u1 = np.dot(x, W1) + b1
 # Sortie totale de la couche cachée
    z1 = functions.relu(u1)
 # Entrée totale de la couche de sortie
    u2 = np.dot(z1, W2) + b2
 # Sortie totale de la couche de sortie
    y = u2
    
 print_vec ("entrée totale 1", u1)
 print_vec ("Sortie couche intermédiaire 1", z1)
 print_vec ("entrée totale 2", u2)
 print_vec ("sortie 1", y)
 print ("Sortie totale:" + str (np.sum (z1)))
    
    return y, z1

# Valeur d'entrée
x = np.array([1., 2., 3.])
network =  init_network()
y, z1 = forward(network, x)
# Sortie cible
d = np.array([2., 3.,4.,5.])
# Erreur
loss = functions.mean_squared_error(d, y)
## afficher
 print ("\ n ##### Affichage des résultats #####")
 print_vec ("sortie couche intermédiaire", z1)
 print_vec ("sortie", y)
 print_vec ("données d'apprentissage", d)
 print_vec ("erreur", perte)

#####Initialisation du réseau##### Poids 1 [[0.1 0.4 0.7 0.1 0.3] [0.2 0.5 0.8 0.1 0.4] [0.3 0.6 0.9 0.2 0.5]]

Poids 2 [[0.1 0.6 0.1 0.6] [0.2 0.7 0.2 0.7] [0.3 0.8 0.3 0.8] [0.4 0.9 0.4 0.9] [0.5 0.1 0.5 0.1]]

Biais 1 [0.1 0.2 0.3 0.4 0.5]

Biais 2 [0.1 0.2 0.3 0.4]

#####Commencer la propagation vers l'avant##### Total entrée 1 [1.5 3.4 5.3 1.3 3.1]

Sortie de couche intermédiaire 1 [1.5 3.4 5.3 1.3 3.1]

Total entrée 2 [4.59 9.2 4.79 9.4 ]

Sortie 1 [4.59 9.2 4.79 9.4 ]

Total de sortie: 14.6

#####Affichage des résultats##### Sortie de couche intermédiaire [1.5 3.4 5.3 1.3 3.1]

production [4.59 9.2 4.79 9.4 ]

Données d'entraînement [2. 3. 4. 5.]

Erreur 8.141525

python



# Essayons #


# Classification binaire
# 2-3-1 réseau

# !! Essayons _ Changeons la configuration du nœud en 5-10-1

# Définir le poids et le biais
# Créer Natework
def init_network():
 print ("##### Initialisation du réseau #####")

    network = {}
    network['W1'] = np.array([
        [0.1, 0.3, 0.5,0.1, 0.3, 0.5,0.1, 0.3, 0.5, 0.6],
        [0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.7],
        [0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.7],
        [0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.7],
        [0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.2, 0.4, 0.6,0.7]
    ])
    network['W2'] = np.array([
       [0.1],
       [0.1],
       [0.1],
       [0.1],
       [0.1],
       [0.1],
       [0.1],
       [0.1],
       [0.1],
       [0.1]
    ])
    network['b1'] = np.array([0.1, 0.3, 0.5,0.1, 0.3, 0.5,0.1, 0.3, 0.5, 0.6])
    network['b2'] = np.array([0.1])
    return network


# Créer un processus
def forward(network, x):
 print ("##### Démarrer la propagation #####")
    
    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']    

 # Entrée totale de la couche masquée
    u1 = np.dot(x, W1) + b1
 # Sortie totale de la couche cachée
    z1 = functions.relu(u1)
 # Entrée totale de la couche de sortie
    u2 = np.dot(z1, W2) + b2
 # Sortie totale de la couche de sortie
    y = functions.sigmoid(u2)
            
 print_vec ("entrée totale 1", u1)
 print_vec ("Sortie couche intermédiaire 1", z1)
 print_vec ("entrée totale 2", u2)
 print_vec ("sortie 1", y)
 print ("Sortie totale:" + str (np.sum (z1)))

    return y, z1


# Valeur d'entrée
x = np.array([1., 2., 3., 4., 5.])
# Sortie cible
d = np.array([1])
network =  init_network()
y, z1 = forward(network, x)
# Erreur
loss = functions.cross_entropy_error(d, y)

## afficher
 print ("\ n ##### Affichage des résultats #####")
 print_vec ("sortie couche intermédiaire", z1)
 print_vec ("sortie", y)
 print_vec ("données d'apprentissage", d)
 print_vec ("erreur", perte)

#####Initialisation du réseau##### #####Commencer la propagation vers l'avant##### Total entrée 1 [ 3. 6.2 9.4 3. 6.2 9.4 3. 6.2 9.4 11. ]

Sortie de couche intermédiaire 1 [ 3. 6.2 9.4 3. 6.2 9.4 3. 6.2 9.4 11. ]

Total entrée 2 [6.78]

Sortie 1 [0.99886501]

Total de sortie: 66.8

#####Affichage des résultats##### Sortie de couche intermédiaire [ 3. 6.2 9.4 3. 6.2 9.4 3. 6.2 9.4 11. ]

production [0.99886501]

Données d'entraînement [1]

Erreur 0.0011355297129812408 ⇒ [Discussion] Il a été constaté que le résultat de sortie change considérablement en fonction de la taille de la couche intermédiaire. Comment décidez-vous du nombre d'unités? J'ai eu du mal à choisir la classe moyenne. N'hésitez pas car le nombre d'unités dans la couche d'entrée doit correspondre à la dimension des données. Et vous n'avez pas à penser au nombre d'unités dans la couche de sortie lorsque vous en préparez autant que le nombre de classes classées. Je voudrais savoir si l'approximation fonctionne si le nombre de couches intermédiaires augmente énormément. J'ai également trouvé difficile de fixer des pondérations et des biais.

DN15_Exercice Jupyter 2

python



# Essayons #


# Exemple de fonction
# IA qui prédit la valeur de y

def f(x):
    y = 3 * x[0] + 2 * x[1]
    return y

# Réglage initial
def init_network():
 # print ("##### Initialisation du réseau #####")
    network = {}
    nodesNum = 10
    network['W1'] = np.random.randn(2, nodesNum)
    network['W2'] = np.random.randn(nodesNum)
    network['b1'] = np.random.randn(nodesNum)
    network['b2'] = np.random.randn()

 # print_vec ("poids 1", réseau ['W1'])
 # print_vec ("poids 2", réseau ['W2'])
 # print_vec ("biais 1", réseau ['b1'])
 # print_vec ("biais 2", réseau ['b2'])

    return network

# Propagation vers l'avant
def forward(network, x):
 # print ("##### Début de propagation séquentielle #####")
    
    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']
    u1 = np.dot(x, W1) + b1
    #z1 = functions.relu(u1)
    
 ## Essayons
 z1 = functions.sigmoid (u1) # Sélectionnez et essayez sigmoid
    
    u2 = np.dot(z1, W2) + b2
    y = u2

 # print_vec ("entrée totale 1", u1)
 # print_vec ("Sortie couche intermédiaire 1", z1)
 # print_vec ("entrée totale 2", u2)
 # print_vec ("sortie 1", y)
 # print ("Sortie totale:" + str (np.sum (y)))
    
    return z1, y

# Erreur de propagation de retour
def backward(x, d, z1, y):
 # print ("\ n ##### Erreur de début de propagation de retour #####")

    grad = {}
    
    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']

 #Delta dans la couche de sortie
    delta2 = functions.d_mean_squared_error(d, y)
 Dégradé de # b2
    grad['b2'] = np.sum(delta2, axis=0)
 # W2 dégradé
    grad['W2'] = np.dot(z1.T, delta2)
 # Delta dans la couche intermédiaire
    #delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)

 ## Essayons #Select Sigmaid et essayez
    delta1 = np.dot(delta2, W2.T) * functions.d_sigmoid(z1)

    delta1 = delta1[np.newaxis, :]
 Gradient de # b1
    grad['b1'] = np.sum(delta1, axis=0)
    x = x[np.newaxis, :]
 # W1 dégradé
    grad['W1'] = np.dot(x.T, delta1)
    
 # print_vec ("poids_ partiellement différencié 1", grad ["W1"])
 # print_vec ("poids_ partiellement différencié 2", grad ["W2"])
 # print_vec ("biais_partiellement différencié 1", grad ["b1"])
 # print_vec ("biais_partiellement différencié 2", grad ["b2"])

    return grad

# Créer des exemples de données
data_sets_size = 100000
data_sets = [0 for i in range(data_sets_size)]

for i in range(data_sets_size):
    data_sets[i] = {}
 # Définir une valeur aléatoire
    # data_sets[i]['x'] = np.random.rand(2)
    
 ## Essayons _ Réglage de la valeur d'entrée # Sélectionnez ceci pour essayer
 data_sets [i] ['x'] = np.random.rand (2) * 10 -5 # -5 à 5 nombres aléatoires
    
 # Définir la sortie cible
    data_sets[i]['d'] = f(data_sets[i]['x'])
    
losses = []
# Taux d'apprentissage
learning_rate = 0.07

# Nombre d'extraits
epoch = 1000

# Initialisation des paramètres
network = init_network()
# Extraction aléatoire de données
random_datasets = np.random.choice(data_sets, epoch)

# Descente de pente répétée
for dataset in random_datasets:
    x, d = dataset['x'], dataset['d']
    z1, y = forward(network, x)
    grad = backward(x, d, z1, y)
 #Apply gradient to parameter
    for key in ('W1', 'W2', 'b1', 'b2'):
        network[key]  -= learning_rate * grad[key]

 #Erreur
    loss = functions.mean_squared_error(d, y)
    losses.append(loss)

 print ("##### Affichage des résultats #####")
lists = range(epoch)


plt.plot(lists, losses, '.')
# Affichage du graphique
plt.show()
Capture d'écran 2019-12-31 6.16.29.png ⇒ [Discussion] En passant de la fonction Relu à la fonction sigmoïde, la variance plus proche de 0 dans le graphique s'est étendue. Aussi,-En sélectionnant un nombre aléatoire de 5 à 5, #Mission d'achèvement

DN16_Mission d'achèvement (mission de production)

+(Problème) Créer un apprentissage approfondi à l'aide des données IRIS

###conception Créez un modèle qui prédit en entraînant les données IRIS dans une division 2: 1 entre les données d'entraînement et les données de test.

  • Couche d'entrée: 4 dimensions *Couche cachée: 6 dimensions *Couche de sortie: 3D (en raison d'un problème de classification de 3 classes) *Collage entre les couches: dense *Couche d'entrée → fonction d'activation de la couche cachée: relu *Couche cachée → Fonction d'activation de la couche de sortie: softmax *Optimisation: méthode de descente de gradient *Fonction de perte: entropie croisée
Capture d'écran 2020-01-01 16.46.51.png Capture d'écran 2020-01-01 16.47.10.png

python


import numpy as np

# Hyper paramètres
 INPUT_SIZE = 4 # nombre de nœuds d'entrée
 HIDDEN_SIZE = 6 # Nombre de neurones dans la couche intermédiaire (couche cachée)
 OUTPUT_SIZE = 3 # Nombre de neurones dans la couche de sortie
 TRAIN_DATA_SIZE = 50 # Utilisez TRAIN_DATA_SIZE comme données d'entraînement sur 150 données. Le reste est utilisé comme données sur les enseignants.
 LEARNING_RATE = 0,1 # Taux d'apprentissage
 EPOCH = 1000 # Nombre d'apprentissage répété (nombre d'époques)

# Lire les données

# Obtenez le jeu de données Iris ici. Étant donné que les données sont organisées par type avec un en-tête, préparez les données CSV de sorte que 150 données soient mélangées en 3 types et 10 cas chacun.
 https://gist.github.com/netj/8836201

x = np.loadtxt('/content/drive/My Drive/DNN_code/data/iris.csv', delimiter=',',skiprows=1, usecols=(0, 1, 2, 3))
raw_t = np.loadtxt('/content/drive/My Drive/DNN_code/data/iris.csv',  delimiter=',',skiprows=1,dtype="unicode", usecols=(4,))

t = np.zeros([150])

for i in range(0,150):
  vari = raw_t[i]
  #print(vari,raw_t[i],i)
  if ("Setosa" in vari):
      t[i] = int(0)
  elif ("Versicolor" in vari):
      t[i] = int(1)
  elif ("Virginica" in vari):
      t[i] = int(2)
  else:
 print ("erreur", i)

a = [3, 0, 8, 1, 9]
a = t.tolist()
a_int = [int(n) for  n in a]
print(a_int)

a_one_hot = np.identity(10)[a_int]
a_one_hot = np.identity(len(np.unique(a)))[a_int]

print(a_one_hot)

train_x = x[:TRAIN_DATA_SIZE]
train_t = a_one_hot[:TRAIN_DATA_SIZE]
test_x = x[TRAIN_DATA_SIZE:]
test_t = a_one_hot[TRAIN_DATA_SIZE:]

print("train=",TRAIN_DATA_SIZE,train_x,train_t)
print("test=",test_x,test_t)

# Initialisation poids / biais #He valeur initiale (pour utiliser ReLU)
W1 = np.random.randn(INPUT_SIZE, HIDDEN_SIZE) / np.sqrt(INPUT_SIZE) * np.sqrt(2)  
W2 = np.random.randn(HIDDEN_SIZE, OUTPUT_SIZE)/ np.sqrt(HIDDEN_SIZE) * np.sqrt(2)
# Ajuster à partir de la valeur initiale zéro
b1 = np.zeros(HIDDEN_SIZE) 
b2 = np.zeros(OUTPUT_SIZE)

# Fonction ReLU
def relu(x):
    return np.maximum(x, 0)

# Fonction Softmax
def softmax(x):
    if x.ndim == 2:
        x = x.T
        x = x - np.max(x, axis=0)
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T

 x = x --np.max (x) # Mesures de débordement
    return np.exp(x) / np.sum(np.exp(x))

# Erreur d'entropie croisée
def cross_entropy_error(y, t):
    if y.shape != t.shape:
        raise ValueError
    if y.ndim == 1:
        return - (t * np.log(y)).sum()
    elif y.ndim == 2:
        return - (t * np.log(y)).sum() / y.shape[0]
    else:
        raise ValueError

# Propagation vers l'avant
def forward(x):
    global W1, W2, b1, b2
    return softmax(np.dot(relu(np.dot(x, W1) + b1), W2) + b2)

# Résultats des données de test
test_y = forward(test_x)
 print ("Avant l'apprentissage =", (test_y.argmax (axis = 1) == test_t.argmax (axis = 1)). Sum (), '/', 150 --TRAIN_DATA_SIZE)

# Boucle d'apprentissage
for i in range(EPOCH):
 # Propagation en avant avec stockage de données
    y1 = np.dot(train_x, W1) + b1
    y2 = relu(y1)
    train_y = softmax(np.dot(y2, W2) + b2)

 # Calcul de la fonction de perte
    L = cross_entropy_error(train_y, train_t)

 si i% 100 == 0: # 100 reste
        print("L=",L)

 # Calcul du gradient
    a1 = (train_y - train_t) / TRAIN_DATA_SIZE
    b2_gradient = a1.sum(axis=0)
    W2_gradient = np.dot(y2.T, a1)
    a2 = np.dot(a1, W2.T)
    a2[y1 <= 0.0] = 0
    b1_gradient = a2.sum(axis=0)
    W1_gradient = np.dot(train_x.T, a2)

 # Mise à jour des paramètres
    W1 = W1 - LEARNING_RATE * W1_gradient
    W2 = W2 - LEARNING_RATE * W2_gradient
    b1 = b1 - LEARNING_RATE * b1_gradient
    b2 = b2 - LEARNING_RATE * b2_gradient

# Affichage des résultats

# Valeur L des données d'entraînement finales
L = cross_entropy_error(forward(train_x), train_t)
 print ("Valeur L des données d'entraînement finales =", L)

# Résultats des données de test
test_y = forward(test_x)
 print ("Après apprentissage =", (test_y.argmax (axis = 1) == test_t.argmax (axis = 1)). Sum (), '/', 150 --TRAIN_DATA_SIZE)

(résultat) Avant d'apprendre = 42/ 100 L= 4.550956552060894 L= 0.3239415165787326 L= 0.2170679838829666 L= 0.04933110713361697 L= 0.0273865499319481 L= 0.018217122389043848 L= 0.013351028977015358 L= 0.010399165844496665 L= 0.008444934117102367 L= 0.007068429052588092 Valeur L des données d'entraînement finales= 0.0060528995955394386 Après l'apprentissage = 89/ 100

⇒ [Discussion]

  • Q1.Quel est le but de la mission? Quel type d'appareil peut être fait
    Le but de la tâche est d'apprendre tout au long du mécanisme de base de l'apprentissage profond. Il peut être conçu en ajustant le nombre de couches intermédiaires et d'hyper paramètres.
  • Q2.Quelle est la signification de résoudre une tâche avec une tâche de classification?
    Pour les tâches de classification, vous pouvez apprendre à générer des données d'entraînement et de test.
  • Q3.Que sont les données IRIS? Deux lignes
    Données préparées pour l'apprentissage automatique et le deep learning.
    Quatre quantités de caractéristiques sont fournies en fonction de la classification de trois types d'iris.

Recommended Posts

<Cours> Apprentissage en profondeur: Jour 1 NN
<Cours> Apprentissage en profondeur: Day2 CNN
<Cours> Deep Learning Day4 Renforcement de l'apprentissage / flux de tension
Sujets> Deep Learning: Day3 RNN
L'apprentissage en profondeur
Étudiez en profondeur le Deep Learning [DW Day 0]
Les débutants en apprentissage automatique suivent le cours d'apprentissage en profondeur de Coursera
[Rabbit Challenge (E qualification)] Apprentissage en profondeur (jour2)
[Rabbit Challenge (E qualification)] Apprentissage en profondeur (jour3)
Mémorandum d'apprentissage profond
Commencer l'apprentissage en profondeur
Apprentissage Python jour 4
Apprentissage en profondeur Python
Apprentissage profond × Python
[Rabbit Challenge (E qualification)] Deep learning (day4)
Premier apprentissage profond ~ Lutte ~
Python: pratique du Deep Learning
Fonctions d'apprentissage en profondeur / d'activation
Apprentissage profond à partir de zéro
Fiche d'apprentissage 4 (8e jour)
Fiche d'apprentissage 9 (13e jour)
Fiche d'apprentissage 3 (7e jour)
Deep learning 1 Pratique du deep learning
Apprentissage profond / entropie croisée
Fiche d'apprentissage 5 (9e jour)
Fiche d'apprentissage 6 (10e jour)
Premier apprentissage profond ~ Préparation ~
Enregistrement d'apprentissage de la programmation 2ème jour
Première solution d'apprentissage en profondeur ~
Fiche d'apprentissage 8 (12e jour)
[AI] Apprentissage métrique profond
Fiche d'apprentissage 1 (4e jour)
Fiche d'apprentissage 7 (11e jour)
J'ai essayé le deep learning
Mémo du cours d'apprentissage automatique
Python: réglage du Deep Learning
Fiche d'apprentissage 2 (6e jour)
Technologie d'apprentissage en profondeur à grande échelle
Fiche d'apprentissage 16 (20e jour)
Dossier d'apprentissage 22 (26e jour)
Fonction d'apprentissage profond / softmax
Cours de Deep Learning pouvant être écrasé sur place
Dossier d'apprentissage n ° 21 (25e jour)
Essayez l'apprentissage en profondeur avec TensorFlow
Fiche d'apprentissage 13 (17e jour) Kaggle3
Deep Learning Gaiden ~ Programmation GPU ~
Dossier d'apprentissage n ° 10 (14e jour)
Dossier d'apprentissage n ° 17 (21e jour)
Fiche d'apprentissage 12 (16e jour) Kaggle2
Reconnaissance d'image par apprentissage profond 1 théorie
Dossier d'apprentissage n ° 18 (22e jour)
Deep running 2 Réglage de l'apprentissage profond
Apprentissage profond / code de travail LSTM
Apprentissage profond du noyau avec Pyro