[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)
Ce que vous pouvez faire avec Neural Network (NN)
Retour
Résultats attendus
Prévision du cours de l'action
Prévisions de ventes
Classement
Prévisions du classement des courses de chevaux
Prévisions de classement de popularité
Classement
Identification des photos de chats
Reconnaissance des caractères manuscrits
Classification des types de fleurs
Réseau neuronal Régression (approximation de la fonction qui prend des valeurs réelles continues)
[Analyse des retours] • Régression linéaire • Arbre de retour • Forêt aléatoire • Réseau neuronal (NN)
Réseau de neurones Classification (sexe (mâle ou femelle) et type d'animal Analyse pour prédire des résultats discrets)
[Analyse de classification] • Classification bayésienne • Régression logistique • Forêt aléatoire • Réseau neuronal (NN)
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é.
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
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?
(Référence) Site d'explication de la méthode de descente de gradient
Méthode de descente de gradient probabiliste
$ W ^ {(t + 1)} = W ^ {(t)} - \ varepsilon \ nabla E (\ varepsilon est le taux d'apprentissage) $ ・ ・ ・ Méthode de descente de gradient Erreur
+
$ W ^ {(t + 1)} = W ^ {(t)} - \ varepsilon \ nabla En (\ varepsilon est le taux d'apprentissage) $ ・ ・ ・ Méthode probabiliste de descente de gradient
La méthode de descente de gradient probabiliste est l'erreur d'échantillons sélectionnés au hasard
Avantages de la méthode de descente de gradient probabiliste
Réduction du coût de calcul lorsque les données sont longues
Réduire le risque de convergence vers des solutions minimales locales indésirables
Vous pouvez étudier en ligne
[(Référence) Site explicatif de la méthode de descente de gradient stochastique](https://qiita.com/YudaiSadakuni/items/ece07b04c685a64eaa01#%E7%A2%BA%E7%8E%87%E7%9A%84%E5% 8B% BE% E9% 85% 8D% E9% 99% 8D% E4% B8% 8B% E6% B3% 95)
Méthode de descente de gradient mini batch
+
$ W ^ {(t + 1)} = W ^ {(t)} - \ varepsilon \ nabla En (\ varepsilon est le taux d'apprentissage) $ ・ ・ ・ Méthode probabiliste de descente de gradient
La méthode de descente de gradient probabiliste est l'erreur d'échantillons sélectionnés au hasard
$ W ^ {(t + 1)} = W ^ {(t)} - \ varepsilon \ nabla Et (\ varepsilon est le taux d'apprentissage) $ ・ ・ ・ Méthode de descente de gradient en mini batch
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
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 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.
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
[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] 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]
[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.
[P34] Test de confirmation NN-monocouche entièrement couplé, plusieurs nœuds 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
⇒ [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
[P56] Test de confirmation(Méthode de descente de gradient S4) Trouvez le code source approprié pour la fonction de descente de gradient.
⇒ [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.
+
⇒ [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
[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)
python
# Delta à la couche de sortie
delta2 = functions.d_mean_squared_error(d, y)
python
# Delta à la couche de sortie
# W2 dégradé
grad['W2'] = np.dot(z1.T, delta2)
#Exercice
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.
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()
⇒ [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, +(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.
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]
Recommended Posts