J'ai implémenté RNN en python. J'ai utilisé ["Deep Learning"](http://www.amazon.co.jp/ Deep Learning-Machine Learning Professional Series-Okaya-Takayuki / dp / 4061529021) comme manuel.
Structure de cet article
RNN
RNN est un réseau neuronal récursif qui gère les données en série. Des exemples de données de série comprennent la voix, la langue et les images en mouvement. La caractéristique de ces données en série est que la longueur de la série diffère pour chaque échantillon et que l'ordre des éléments de la série est significatif. RNN permet de bien gérer les caractéristiques des données en série.
Tout d'abord, définissez les caractères. Les index de chaque unité de la couche d'entrée, de la couche intermédiaire et de la couche de sortie sont respectivement représentés par $ i, j et k $. De plus, l'entrée au temps $ t $, l'entrée / sortie de la couche intermédiaire, l'entrée / sortie de la couche de sortie et l'enseignant sont exprimées comme suit.
En outre, les poids entre la couche d'entrée-intermédiaire, les poids du chemin de rétroaction entre les couches intermédiaires-intermédiaires et les poids entre les couches intermédiaire-sortie sont exprimés comme suit.
La structure du réseau comprenant la définition ci-dessus est illustrée dans la figure ci-dessous.
Maintenant, je vais expliquer le calcul de la propagation vers l'avant. Les entrées / sorties $ u_j ^ t $ et $ z_j ^ t $ de l'unité $ j $ dans la couche intermédiaire sont l'entrée $ \ boldsymbol x ^ t $ et la valeur de la couche intermédiaire à l'instant précédent $ \ boldsymbol z ^ {t Il peut être exprimé comme suit en utilisant -1} $. $ f $ est la fonction d'activation.
\begin{align}
& u_j^t = \sum_i w_{ji}^{(in)}x_i^t + \sum_{j'} w_{jj'}z_{j'}^{t-1} \tag{1} \\
& z_j^t = f(u_j^t) \tag{2}
\end{align}
Cependant, lorsque $ t = 1 $, il n'y a pas d'entrée pour l'instant, donc $ \ boldsymbol z ^ 0 = \ boldsymbol 0 $. Lorsque les équations (1) et (2) sont résumées et exprimées dans une matrice, la sortie $ \ boldsymbol z ^ t $ de la couche intermédiaire est la suivante.
\boldsymbol z^t = \boldsymbol f(\boldsymbol W^{(in)}\boldsymbol x^t + \boldsymbol W \boldsymbol z^{t-1}) \tag{3}
L'entrée / sortie $ v_k ^ t $ et $ y_k ^ t $ de l'unité $ k $ de la couche de sortie peut être exprimée comme suit en utilisant la sortie $ \ boldsymbol z ^ t $ de la couche intermédiaire.
\begin{align}
& v_k^t = \sum_j w_{kj}^{(out)}z_j^t \tag{4} \\
& y_k^t = f^{(out)}(v_k^t) \tag{5}
\end{align}
Lorsque les équations (4) et (5) sont rassemblées et exprimées dans une matrice, la sortie $ \ boldsymbol y ^ t $ est la suivante.
\boldsymbol y^t = \boldsymbol f^{(out)}(\boldsymbol W^{(out)}\boldsymbol z^t) \tag{6}
Le gradient est calculé à partir de l'erreur dans chaque unité de chaque couche par la méthode de propagation de retour d'erreur. Cette fois, j'expliquerai la ** méthode BPTT (rétropropagation dans le temps) **. Dans la méthode BPTT, le RNN est étendu dans le sens du temps, comme indiqué dans la figure ci-dessous, et la rétro-propagation d'erreur est calculée.
** Pente intermédiaire entre les couches de sortie **
\begin{align}
\frac{\partial E}{\partial w_{kj}^{(out)}} &= \sum_{t=1}^T \frac{\partial E}{\partial v_k^t} \frac{\partial v_k^t}{\partial w_{kj}^{(out)}} \\
&= \sum_{t=1}^T \frac{\partial E}{\partial y_k^t} \frac{\partial y_k^t}{\partial v_k^t} \frac{\partial v_k^t}{\partial w_{kj}^{(out)}} \\
&= \sum_{t=1}^T \frac{\partial E}{\partial y_k^t} f^{(out)'}(v_k^t)z_j^t \\
&= \sum_{t=1}^T \delta_k^{(out), t} z_j^t \tag{7}
\end{align}
** Pente intermédiaire dans le chemin de retour de la couche intermédiaire **
\begin{align}
\frac{\partial E}{\partial w_{jj'}} &= \sum_{t=1}^T \frac{\partial E}{\partial u_j^t} \frac{\partial u_j^t}{\partial w_{jj'}} \\
&= \sum_{t=1}^T \biggl(\sum_{k'} \frac{\partial E}{\partial v_{k'}^t} \frac{\partial v_{k'}^t}{\partial z_j^t} \frac{\partial z_j^t}{\partial u_j^t} + \sum_{j''} \frac{\partial E}{\partial u_{j''}^{t+1}} \frac{\partial u_{j''}^{t+1}}{\partial z_j^t} \frac{\partial z_j^t}{\partial u_j^t} \biggr) \frac{\partial u_j^t}{\partial w_{jj'}} \\
&= \sum_{t=1}^T \biggl(\sum_{k'} \frac{\partial E}{\partial v_{k'}^t} \frac{\partial v_{k'}^t}{\partial z_j^t} + \sum_{j''} \frac{\partial E}{\partial u_{j''}^{t+1}} \frac{\partial u_{j''}^{t+1}}{\partial z_j^t} \biggr) \frac{\partial z_j^t}{\partial u_j^t} \frac{\partial u_j^t}{\partial w_{jj'}} \\
&= \sum_{t=1}^T \biggl(\sum_{k'} \delta_{k'}^{(out), t} w_{k'j} + \sum_{j''} \delta_{j''}^{t+1} w_{j''j} \biggr) f'(u_j^t) z_j^{t-1} \\
&= \sum_{t=1}^T \delta_j^t z_j^{t-1} \tag{8}
\end{align}
** Input-Slope entre les couches intermédiaires **
\begin{align}
\frac{\partial E}{\partial w_{ji}^{(in)}} &= \sum_{t=1}^T \frac{\partial E}{\partial u_j^t} \frac{\partial u_j^t}{\partial w_{ji}^{(in)}} \\
&= \sum_{t=1}^T \delta_j^t x_i^t \tag{9}
\end{align}
Intermédiaire - Dans le dégradé du chemin de retour de la couche intermédiaire, il y a un terme de l'erreur $ \ boldsymbol \ delta ^ {t + 1} $ de la couche intermédiaire à la prochaine fois. Si $ t = T $, alors $ \ boldsymbol \ delta ^ {T + 1} = \ boldsymbol 0 $. Propagez l'erreur $ \ delta $ dans l'ordre $ t = T, T-1, \ cdots, 2, 1 $, et prenez la somme des gradients à chaque instant. Le poids est mis à jour en utilisant la somme de ce gradient.
À partir des équations (7), (8) et (9), le gradient entre chaque couche peut être obtenu. À l'aide de ce dégradé, mettez à jour le poids à partir de la formule suivante.
w_{new} = w_{old} - \varepsilon \frac{\partial E}{\partial w_{old}} \tag{10}
Implémentation de la prédiction sinusoïdale. Le code peut être trouvé à ici. $ x ^ t = \ sin \ bigl (\ theta + (t -1) \ cdot \ Delta \ theta \ bigr) $ Entrez $ x ^ t $ et $ y ^ t = \ à la prochaine fois Prédisez $ y ^ t $, qui est sin \ bigl (\ theta + t \ cdot \ Delta \ theta \ bigr) $. Lors de la sortie de $ y ^ t $ pour une certaine entrée $ x ^ t $, la direction de prédiction ne peut pas être déterminée uniquement par l'entrée $ x ^ t $. Cependant, si vous entrez $ x ^ t $ et $ z ^ {t-1} $, vous pouvez utiliser les informations de l'heure précédente pour déterminer la direction de la prédiction.
Les données d'apprentissage sont un échantillon $ 1 $ des données de série de $ \ boldsymbol x = (x ^ 1, x ^ 2, \ cdots, x ^ T) $. $ \ theta $ est déterminé par un nombre aléatoire de la plage de $ [0, \ pi] $.
\begin{align}
& \{\theta \,|\, 0 \leq \theta \leq \pi\}, \Delta \theta = \frac{\pi}{6} \\
& x^1 = \sin \theta \\
& x^2 = \sin \bigl(\theta + \Delta \theta\bigr) \\
& \cdots \\
& x^t = \sin \bigl(\theta + (t - 1)\cdot \Delta \theta\bigr) \tag{11} \\
& \cdots \\
& x^T = \sin \bigl(\theta + (T - 1)\cdot \Delta \theta\bigr) \\
\end{align}
Les paramètres d'apprentissage sont les suivants. Données d'entraînement: 7000 $ Échantillon Taux d'apprentissage: $ \ varepsilon = 0,05 $ Coefficient de régularisation: $ \ lambda = 0,001 $ Époque: 30 $ $
La perte pendant l'apprentissage est la suivante.
Ensuite, vérifiez si la prédiction était correcte lorsque les données de la série chronologique ont été entrées. L'entrée est représentée par $ x $, la sortie est représentée par $ y $ et la sortie idéale est représentée par $ d $.
\begin{align}
& x^1 = \sin\Bigl(\frac{1}{6}\pi\Bigr) \to y^1 = 0.43831960 \ \ (d^1 = 0.86602540) \tag{12} \\
& x^1 = \sin\Bigl(\frac{5}{6}\pi\Bigr) \to y^1 = 0.43831960 \ \ (d^1 = 0.0) \tag{13}
\end{align}
Les valeurs de $ y $ correspondent car les valeurs de $ x $ sont égales. De plus, la prédiction $ y $ est loin d'être la sortie idéale $ d $ car il n'y a aucune information de séquence. Par conséquent, je vais également entrer les données de la fois précédente.
\begin{align}
& \boldsymbol x = (x^1, x^2) = \biggl(\sin\Bigl(\frac{0}{6}\pi\Bigr), \sin\Bigl(\frac{1}{6}\pi\Bigr)\biggr) \to y^2 = 0.84290507 \ \ (d^2 = 0.86602540) \tag{14} \\
& \boldsymbol x = (x^1, x^2) = \biggl(\sin\Bigl(\frac{4}{6}\pi\Bigr), \sin\Bigl(\frac{5}{6}\pi\Bigr)\biggr) \to y^2 = -0.02663726 \ \ (d^2 = 0.0) \tag{15}
\end{align}
Si vous les entrez en tant que données de série chronologique, le résultat de la prédiction correct est obtenu. Cela est possible car le RNN a une structure récursive qui contient des informations de série chronologique.
Enfin, nous prédisons la vague de péché. Un algorithme simple est présenté ci-dessous.
La figure ci-dessous montre le résultat. Les données de série avec de courts points bleus et des points verts sont les résultats obtenus par prédiction. Si vous regardez le graphique, vous pouvez voir que l'onde de péché peut être prédite correctement.
J'ai pu implémenter RNN. Ensuite, j'aimerais étudier le LSTM.
Recommended Posts