[PYTHON] Deep Learning / Deep Learning à partir de Zero 2 Chapitre 8 Mémo

1.Tout d'abord

Je lis un chef-d'œuvre, ** "Deep Learning from Zero 2" **. Cette fois, c'est un mémo du chapitre 8. Pour exécuter le code, téléchargez le code complet depuis Github et utilisez le notebook jupyter dans ch08.

2.Attention Vous trouverez ci-dessous un diagramme schématique de Attention dans le modèle Seq2seq.

スクリーンショット 2020-05-27 17.43.40.png

Mettez ** Attention ** entre ** LSTM ** et ** Affine ** à tout moment du ** Decoder **. Ensuite, entrez ** hs **, qui est une collection de ** vecteurs cachés (hs0 à hs4) ** à chaque fois de ** Encoder **, dans toutes les Attentions.

Dans chaque Attention, la similitude (produit vectoriel) entre l'entrée de LSTM et hs est calculée, et l'importance des vecteurs cachés (hs0 à hs4) est calculée par une distribution de probabilité. Ensuite, le vecteur caché est pondéré par sa distribution de probabilité, et le composite est envoyé à Affine.

スクリーンショット 2020-05-28 10.14.46.png

Il s'agit d'un diagramme schématique à l'intérieur de la couche Attention et de l'image d'opération de la matrice (lorsque la taille du lot N = 1) y est effectuée.

Tout d'abord, la partie ** Attention_weight **. Trouvez le ** produit ** des ** vecteurs hs0 à hs4 ** du codeur et du ** vecteur h ** du décodeur, et ajoutez-les dans la ** direction de la colonne (axe = 2) **, respectivement, pour obtenir les deux vecteurs. Plus la ** similarité de ** est élevée, plus la **. Passer Softmax à travers ce nombre donne un ** vecteur a ** qui représente la ** pondération des vecteurs hs0 à hs4 **.

Vient ensuite la partie ** Weight_Sum **. Le ** produit ** des ** vecteurs hs0 à hs4 ** et ** vecteur a ** est calculé, et ** vecteur C ** ajouté par ** direction de ligne (axe = 1) ** est ** attention ( Les informations à (voir) sont pondérées et combinées (ajoutées) pour former un vecteur **. En envoyant cela à Affine, Affine peut obtenir ** des informations côté Encodeur auxquelles il faut se référer à ce moment-là en plus des informations du LSTM ** conventionnel.

À propos, lors du calcul de np.sum (x, axis =?) Of x = (N, T, H), sum (addition dans le sens du batch) de sorte que l'axe N soit effacé lorsque ** axis = 0. Ensuite, lorsque ** axis = 1, additionnez (addition dans le sens des lignes) pour effacer l'axe T **, et lorsque ** axis = 2, effacez l'axe H ** (addition dans le sens des colonnes). Faire.

Jetons un coup d'œil au code de Attention_weight.

class AttentionWeight:
    def __init__(self):
        self.params, self.grads = [], []
        self.softmax = Softmax()
        self.cache = None

    def forward(self, hs, h):
        N, T, H = hs.shape

        #Puisque hr est utilisé pour la diffusion, seule la dimension est ajustée sans se répéter.
        hr = h.reshape(N, 1, H)  #.repeat(T, axis=1)
        t = hs * hr  #Prenez le produit des vecteurs
        s = np.sum(t, axis=2)  #Ajout dans le sens des colonnes
        a = self.softmax.forward(s)  #Calculez la distribution de probabilité a qui représente l'importance de chaque vecteur caché
        self.cache = (hs, hr)
        return a

    def backward(self, da):
        hs, hr = self.cache
        N, T, H = hs.shape

        ds = self.softmax.backward(da)
        dt = ds.reshape(N, T, 1).repeat(H, axis=2)  # (N, T, H)Conversion en
        dhs = dt * hr
        dhr = dt * hs
        dh = np.sum(dhr, axis=1)

        return dhs, dh

Pour la propagation aller, t = hs * hr est calculé par diffusion, donc hr n'est pas répété. Ensuite, jetons un coup d'œil à Weight_sum.

class WeightSum:
    def __init__(self):
        self.params, self.grads = [], []
        self.cache = None

    def forward(self, hs, a):
        N, T, H = hs.shape

        #Comme ar est utilisé pour la diffusion, seules les dimensions sont ajustées sans répétition.
        ar = a.reshape(N, T, 1) #.repeat(T, axis=1)
        t = hs * ar  #Prenez le produit des vecteurs
        c = np.sum(t, axis=1)  #Ajout de direction de ligne
        self.cache = (hs, ar)
        return c

    def backward(self, dc):
        hs, ar = self.cache
        N, T, H = hs.shape
        dt = dc.reshape(N, 1, H).repeat(T, axis=1)
        dar = dt * hs
        dhs = dt * ar
        da = np.sum(dar, axis=2)

        return dhs, da

Pour la propagation vers l'avant, t = hs * ar est calculé par diffusion, donc ar n'est pas répété. Mettez ces deux classes ensemble pour former une «classe Attention».

class Attention:
    def __init__(self):
        self.params, self.grads = [], []
        self.attention_weight_layer = AttentionWeight()
        self.weight_sum_layer = WeightSum()
        self.attention_weight = None

    def forward(self, hs, h):
        a = self.attention_weight_layer.forward(hs, h)
        out = self.weight_sum_layer.forward(hs, a)
        self.attention_weight = a
        return out

    def backward(self, dout):
        dhs0, da = self.weight_sum_layer.backward(dout)
        dhs1, dh = self.attention_weight_layer.backward(da)
        dhs = dhs0 + dhs1
        return dhs, d

De plus, il est résumé dans class TimeAttention pour correspondre à l'heure.

class TimeAttention:
    def __init__(self):
        self.params, self.grads = [], []
        self.layers = None
        self.attention_weights = None

    def forward(self, hs_enc, hs_dec):
        N, T, H = hs_dec.shape
        out = np.empty_like(hs_dec)
        self.layers = []
        self.attention_weights = []

        for t in range(T):
            layer = Attention()
            out[:, t, :] = layer.forward(hs_enc, hs_dec[:,t,:])
            self.layers.append(layer)
            self.attention_weights.append(layer.attention_weight)

        return out

    def backward(self, dout):
        N, T, H = dout.shape
        dhs_enc = 0
        dhs_dec = np.empty_like(dout)

        for t in range(T):
            layer = self.layers[t]
            dhs, dh = layer.backward(dout[:, t, :])
            dhs_enc += dhs
            dhs_dec[:,t,:] = dh

        return dhs_enc, dhs_dec

Maintenant, exécutons l'exemple de code (conversion de format de date) ** train.py ** de seq2seq en utilisant ce mécanisme Attention.

import sys
sys.path.append('..')
import numpy as np
import matplotlib.pyplot as plt
from dataset import sequence
from common.optimizer import Adam
from common.trainer import Trainer
from common.util import eval_seq2seq
from attention_seq2seq import AttentionSeq2seq
from ch07.seq2seq import Seq2seq

#Lire les données
(x_train, t_train), (x_test, t_test) = sequence.load_data('date.txt')
char_to_id, id_to_char = sequence.get_vocab()

#Inverser l'instruction d'entrée
x_train, x_test = x_train[:, ::-1], x_test[:, ::-1]

#Paramètres des hyper paramètres
vocab_size = len(char_to_id)
wordvec_size = 16
hidden_size = 256
batch_size = 128
max_epoch = 10
max_grad = 5.0

model = AttentionSeq2seq(vocab_size, wordvec_size, hidden_size)
# model = Seq2seq(vocab_size, wordvec_size, hidden_size)
# model = PeekySeq2seq(vocab_size, wordvec_size, hidden_size)

optimizer = Adam()
trainer = Trainer(model, optimizer)

acc_list = []
for epoch in range(max_epoch):
    trainer.fit(x_train, t_train, max_epoch=1,
                batch_size=batch_size, max_grad=max_grad)

    correct_num = 0
    for i in range(len(x_test)):
        question, correct = x_test[[i]], t_test[[i]]
        verbose = i < 10
        correct_num += eval_seq2seq(model, question, correct,
                                    id_to_char, verbose, is_reverse=True)

    acc = float(correct_num) / len(x_test)
    acc_list.append(acc)
    print('val acc %.3f%%' % (acc * 100))

model.save_params()

#Dessiner un graphique
x = np.arange(len(acc_list))
plt.plot(x, acc_list, marker='o')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.ylim(-0.05, 1.05)
plt.show()

out.PNG Après 2 époques, la précision est de 100%. Comme prévu, c'est le pouvoir de l'attention.

Recommended Posts

Deep learning / Deep learning from scratch 2 Chapitre 4 Mémo
Deep learning / Deep learning made from scratch Chapitre 3 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 5 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 7 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 8 Mémo
Deep learning / Deep learning made from scratch Chapitre 5 Mémo
Deep learning / Deep learning made from scratch Chapitre 4 Mémo
Deep learning / Deep learning from scratch 2 Chapitre 3 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 6 Mémo
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 7]
Deep learning / Deep learning made from scratch Chapitre 6 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [Chapitre 5]
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 6]
Deep learning / Deep learning made from scratch Chapitre 7 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [~ Chapitre 4]
Deep Learning from scratch Chapter 2 Perceptron (lecture du mémo)
Apprentissage amélioré pour apprendre de zéro à profond
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 12) Deep learning
Apprentissage profond à partir de zéro
Mémo d'auto-apprentissage "Deep Learning from scratch" (glossaire illisible)
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 9) Classe MultiLayerNet
Deep Learning from scratch ① Chapitre 6 "Techniques liées à l'apprentissage"
[Mémo d'apprentissage] Apprentissage profond à partir de zéro ~ Mise en œuvre de l'abandon ~
Mémo d'auto-apprentissage «Deep Learning from scratch» (10) Classe MultiLayerNet
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 11) CNN
Apprentissage profond à partir de zéro 1 à 3 chapitres
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 19) Augmentation des données
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer du chapitre 2
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 1
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 5
Apprentissage profond à partir de zéro (calcul des coûts)
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 3
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 7
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 5
Un amateur a trébuché dans le Deep Learning ❷ fait de zéro Note: Chapitre 1
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 4
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 18) One! Miaou! Grad-CAM!
Un amateur a trébuché dans le Deep Learning à partir de zéro.
Mémo d'apprentissage profond créé à partir de zéro
L'apprentissage en profondeur
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 2
Mémo d'auto-apprentissage "Deep Learning from scratch" (n ° 15) Tutoriel pour débutants TensorFlow
Tutoriel d'apprentissage en profondeur de la construction d'environnement
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 14) Exécutez le programme du chapitre 4 sur Google Colaboratory
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 8) J'ai dessiné le graphique du chapitre 6 avec matplotlib
Mémo d'auto-apprentissage "Deep Learning from scratch" (n ° 13) Essayez d'utiliser Google Colaboratory
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 10-2) Valeur initiale du poids
Apprentissage profond à partir de zéro (propagation vers l'avant)
Apprentissage profond / Apprentissage profond à partir de zéro 2-Essayez de déplacer GRU
Alignement d'image: du SIFT au deep learning
"Deep Learning from scratch" avec Haskell (inachevé)
[Windows 10] Construction de l'environnement "Deep Learning from scratch"
Enregistrement d'apprentissage de la lecture "Deep Learning from scratch"
[Deep Learning from scratch] À propos de l'optimisation des hyper paramètres
Apprentissage profond à partir des bases mathématiques (pendant la fréquentation)
Note d'étude LPIC201
Mémorandum d'apprentissage profond