[PYTHON] Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 5

introduction

Du coup, j'ai commencé à étudier au chapitre 5 de "Deep Learning from scratch-The Theory and implementation of deep learning appris with Python". C'est un mémo du voyage.

L'environnement d'exécution est macOS Mojave + Anaconda 2019.10, et la version Python est 3.7.4. Pour plus de détails, reportez-vous au Chapitre 1 de ce mémo.

(Vers d'autres chapitres de ce mémo: Chapitre 1 / Chapitre 2 / Chapitre 3 / Chapitre 4 / Chapitre 5 / [Chapitre 6](https: / /qiita.com/segavvy/items/ca4ac4c9ee1a126bff41) / Chapitre 7 / Chapitre 8 / Résumé)

Chapitre 5 Méthode de propagation de retour d'erreur

Ce chapitre décrit la méthode de rétropropagation des erreurs pour accélérer le calcul des paramètres de poids dans l'apprentissage des réseaux de neurones.

Au fait, le mot «propagation» (denpa) est une traduction de Propagetion, mais il est également traduit par «propagation» (denpan), et le japonais est chaotique. J'ai trouvé un article sur un blog qui explorait ce domaine, donc si vous êtes intéressé, repos après avoir marché> [apprentissage automatique] La traduction de "Propagation" est "propagation" ou "propagation"? S'il vous plaît.

5.1 Graphique de calcul

L'explication par le graphe de calcul est très facile à comprendre lors de l'apprentissage de la méthode de propagation des erreurs. Le secret de la popularité de ce livre peut être le chapitre 5.

L'apprentissage est essentiel pour les réseaux neuronaux, ce qui nécessite de trouver le gradient des paramètres de poids et de calculer la différenciation de chaque paramètre. En utilisant le graphe de calcul, nous pouvons voir que le calcul du différentiel peut être fait très efficacement en rétropropageant le différentiel local de l'arrière vers l'avant.

5.2 Règle de chaîne

Il s'agit d'un examen de la formule différentielle de la fonction composite et de l'explication de la rétropropagation. Je ne pense pas que ce soit un problème de le lire, mais si vous voulez le comprendre correctement, vous avez besoin d'un examen de la différenciation au secondaire.

Je ne me souvenais pas du tout de la formule différentielle, alors j'ai décidé de la revoir après un long moment. Cependant, j'étudie souvent après la fin de mon activité principale, et quand il s'agit de livres et de sites Web, la somnolence m'attaque et j'ai du mal à entrer dans mon esprit. Il est assez difficile pour un salarié d'étudier dans l'intervalle de temps.

Ce que j'ai trouvé là-bas était Triit, qui est fait par un professeur au foyer, Try. Bien qu'il s'agisse d'un cours vidéo, il est très facile à comprendre même s'il est gratuit, et il est divisé en environ 15 minutes, il est donc idéal pour étudier avec un smartphone en voyage ou en pause. C'est un service pour les étudiants, mais je pense que c'est aussi très approprié pour évaluer les travailleurs.

Pour référence, voici un lien vers une vidéo sur la partie introductive de la différenciation. Veuillez noter qu'il est limité à la visualisation privée.

5.3 Rétropropagation

Une description de la rétropropagation des nœuds d'ajout et de multiplication. La rétropropagation est facile à calculer car la différenciation est simple pour l'addition et la multiplication.

5.4 Implémentation de couche simple

Il s'agit de l'implémentation de la couche d'addition et de la couche de multiplication dans la section précédente. La différenciation étant simple, elle est facile à mettre en œuvre.

5.5 Implémentation de la couche de fonction d'activation

Une implémentation de la couche de fonction d'activation.

5.5.1 Couche ReLU

Comme ReLU a un calcul simple de différenciation, il est facile à mettre en œuvre et est susceptible de conduire à un apprentissage plus rapide. Voici le code implémenté.

relu.py


# coding: utf-8


class ReLU:
    def __init__(self):
        """Couche ReLU
        """
        self.mask = None

    def forward(self, x):
        """Propagation vers l'avant
        
        Args:
            x (numpy.ndarray):contribution
            
        Returns:
            numpy.ndarray:production
        """
        self.mask = (x <= 0)
        out = x.copy()
        out[self.mask] = 0

        return out

    def backward(self, dout):
        """Rétropropagation
        
        Args:
            dout (numpy.ndarray):Valeur de différenciation transmise depuis la bonne couche
        
        Returns:
            numpy.ndarray:Valeur de différenciation
        """
        dout[self.mask] = 0
        dx = dout

        return dx

5.5.2 Couche sigmoïde

La différenciation de la fonction sigmoïde est un peu compliquée, mais elle peut être calculée petit à petit à l'aide du graphe de calcul. Cependant, la différenciation de $ y = \ frac {1} {x} $ requise pour le premier nœud "/" et la différenciation de $ y = exp (x) $ pour le nœud "$ exp $" ne vérifient pas la formule. C'est épicé. Quant aux formules dans ce domaine, il est recommandé que Mathématiques apprises à partir d'exemples concrets> Intégration mineure> Organiser les 59 formules différentielles avec importance soit simplement organisé.

Après le calcul par le graphe de calcul, il se transforme en formule (5.12) du livre, mais au début je n'ai pas compris le flux de transformation de la deuxième ligne de la fin à la dernière ligne. Il sera plus facile à comprendre si vous insérez une ligne entre les deux comme suit.

\begin{align}
\frac{\partial L}{\partial y}y^2exp(-x) &= \frac{\partial L}{\partial y} \frac{1}{(1+exp(-x))^2} exp(-x) \\
&=\frac{\partial L}{\partial y} \frac{1}{1+exp(-x)} \frac{exp(-x)}{1+exp(-x)} \\
&=\frac{\partial L}{\partial y} \frac{1}{1+exp(-x)} \biggl(\frac{1+exp(-x)}{1+exp(-x)} - \frac{1}{1+exp(-x)}\biggr)← Ligne ajoutée\\
&=\frac{\partial L}{\partial y} y(1-y)

\end{align}

Ce qui est surprenant dans ce résultat, c'est qu'il est très facile à calculer avec $ y $, qui est la sortie de la propagation directe. Dans la méthode de propagation des erreurs en retour, la propagation vers l'avant est calculée en premier, donc si vous avez le résultat, cela conduira à un apprentissage plus rapide. La caractéristique que même si $ e ^ x $ est différencié, il devient $ e ^ x $ est également importante, et c'est vraiment incroyable pour ceux qui pensent à la fonction sigmoïde.

La couche sigmoïde n'est pas utilisée dans ce chapitre, donc le code est omis.

5.6 Implémentation de la couche Affine / Softmax

5.6.1 Couche affine

Le processus de calcul est omis dans la formule de rétropropagation de la couche Affine (5.13), mais @yuyasat [calcule régulièrement les composants de la rétropropagation de la couche Affine](https://qiita.com/yuyasat/items/ Le processus de calcul est résumé dans d9cdd4401221df5375b6) pour votre référence.

5.6.2 Version batch Couche affine

Voici le code implémenté. De plus, dans le code du livre, on tient compte du moment où les données d'entrée sont tenseur (données 4D), mais elles ne sont pas incluses car l'usage n'est pas encore connu.

affine.py


# coding: utf-8
import numpy as np


class Affine:

    def __init__(self, W, b):
        """Couche affine
        
        Args:
            W (numpy.ndarray):poids
            b (numpy.ndarray):biais
        """
        self.W = W      #poids
        self.b = b      #biais
        self.x = None   #contribution
        self.dW = None  #Valeur différentielle du poids
        self.db = None  #Valeur différentielle du biais

    def forward(self, x):
        """Propagation vers l'avant
        
        Args:
            x (numpy.ndarray):contribution
            
        Returns:
            numpy.ndarray:production
        """
        self.x = x
        out = np.dot(x, self.W) + self.b

        return out

    def backward(self, dout):
        """Rétropropagation
        
        Args:
            dout (numpy.ndarray):Valeur de différenciation transmise depuis la bonne couche

        Returns:
            numpy.ndarray:Valeur de différenciation
        """
        dx = np.dot(dout, self.W.T)
        self.dW = np.dot(self.x.T, dout)
        self.db = np.sum(dout, axis=0)

        return dx

5.6.3 Couche Softmax-with-Loss

Rétropropagation d'une couche avec une fonction softmax et une erreur d'entropie croisée en tant qu'ensemble. Le processus de calcul est décrit en détail dans l'annexe A du livre, mais même si $ e ^ x $ est différencié, il devient $ e ^ x $, et lorsque tous les vecteurs one-hot de l'étiquette enseignant sont ajoutés, il devient 1. Etc. contribuent à simplifier la formule.

Le résultat final de $ (y_1-t_1, y_2-t_2, y_3-t_3) $ est également surprenant. Il montre la différence entre la sortie du réseau de neurones et l'étiquette de l'enseignant, et peut être calculé rapidement. Il semble que l'erreur d'entropie croisée soit conçue pour être «propre» lorsqu'elle est utilisée comme fonction de perte de la fonction softmax, et c'est vraiment étonnant pour ceux qui pensent à l'erreur d'entropie croisée.

De plus, il est nécessaire de diviser la valeur de la rétro-propagation par le nombre de lots pour correspondre aux lots. Dans le livre, il y avait seulement une explication que "en divisant la valeur à propager par le nombre de lots (batch_size), l'erreur par données est propagée à la couche précédente", et je ne comprenais pas pourquoi il était nécessaire de diviser par le nombre de lots. Cependant, j'ai pu le comprendre grâce à l'explication du code de @ Yoko303 Deep Learning from scratch ~ Softmax-with-Loss layer ~. Dans la version batch de propagation directe, les erreurs d'entropie croisée sont finalement additionnées et divisées par le nombre de lots (batch_size) pour obtenir une valeur. La rétropropagation nécessite également le calcul de cette pièce, et sa valeur différentielle est $ \ frac {1} {batch_size} $. Ci-dessous, j'ai écrit le graphique de calcul pour cette partie.

計算グラフ.png

Je pense que cette compréhension est correcte, mais veuillez signaler toute erreur. Voici le code implémenté.

softmax_with_loss.py


# coding: utf-8
from functions import softmax, cross_entropy_error


class SoftmaxWithLoss:
    def __init__(self):
        """Softmax-with-Couche de perte
        """
        self.loss = None    #perte
        self.y = None       #sortie de softmax
        self.t = None       #Données de l'enseignant (une-hot vector)

    def forward(self, x, t):
        """Propagation vers l'avant
        
        Args:
            x (numpy.ndarray):contribution
            t (numpy.ndarray):Données des enseignants

        Returns:
            float:Erreur d'entropie croisée
        """
        self.t = t
        self.y = softmax(x)
        self.loss = cross_entropy_error(self.y, self.t)

        return self.loss

    def backward(self, dout=1):
        """Rétropropagation
        
        Args:
            dout (float, optional):La valeur différentielle transmise depuis la couche droite. La valeur par défaut est 1.

        Returns:
            numpy.ndarray:Valeur de différenciation
        """
        batch_size = self.t.shape[0]    #Nombre de lots
        dx = (self.y - self.t) * (dout / batch_size)

        return dx

Notez que le code du livre n'utilise pas dout in backward. Puisque dout est utilisé uniquement avec 1 spécifié, il n'y a pas de problème de fonctionnement, mais je pense que c'est probablement une erreur.

5.7 Mise en œuvre de la méthode de propagation des erreurs

5.7.1 Vue d'ensemble de l'apprentissage des réseaux neuronaux

Il s'agit d'un examen du flux de mise en œuvre. Il n'y a pas d'obstacle particulier.

5.7.2 Implémentation d'un réseau neuronal prenant en charge la méthode de propagation de retour d'erreur

Le premier est la mise en œuvre de fonctions à usage général. J'ai apporté seulement ce dont j'avais besoin de ce que j'avais écrit dans le chapitre précédent.

functions.py


# coding: utf-8
import numpy as np


def softmax(x):
    """Fonction Softmax
    
    Args:
        x (numpy.ndarray):contribution
    
    Returns:
        numpy.ndarray:production
    """
    #Pour le traitement par lots, x est(Nombre de lots, 10)Il devient un tableau bidimensionnel de.
    #Dans ce cas, il est nécessaire de bien calculer pour chaque image en utilisant la diffusion.
    #Ici, np afin qu'il puisse être partagé en 1 et 2 dimensions..max()Et np.sum()Est axe=-Calculé par 1
    #Keepdims pour qu'il puisse être diffusé tel quel=Vrai pour maintenir la dimension.
    c = np.max(x, axis=-1, keepdims=True)
    exp_a = np.exp(x - c)  #Mesures de débordement
    sum_exp_a = np.sum(exp_a, axis=-1, keepdims=True)
    y = exp_a / sum_exp_a
    return y


def numerical_gradient(f, x):
    """Calcul du gradient
    
    Args:
        f (function):Fonction de perte
        x (numpy.ndarray):Un tableau de paramètres de poids pour lesquels vous souhaitez vérifier le dégradé
    
    Returns:
        numpy.ndarray:Pente
    """
    h = 1e-4
    grad = np.zeros_like(x)

    # np.Énumérer les éléments d'un tableau multidimensionnel avec nditer
    it = np.nditer(x, flags=['multi_index'])
    while not it.finished:

        idx = it.multi_index  # it.multi_index est le numéro de l'élément dans la liste
        tmp_val = x[idx]  #Enregistrer la valeur d'origine

        # f(x + h)Calculs de
        x[idx] = tmp_val + h
        fxh1 = f()

        # f(x - h)Calculs de
        x[idx] = tmp_val - h
        fxh2 = f()

        #Calculer le gradient
        grad[idx] = (fxh1 - fxh2) / (2 * h)
    
        x[idx] = tmp_val  #Valeur de retour
        it.iternext()

    return grad


def cross_entropy_error(y, t):
    """Calcul de l'erreur d'entropie croisée
    
    Args:
        y (numpy.ndarray):Sortie de réseau neuronal
        t (numpy.ndarray):Étiquette de réponse correcte
    
    Returns:
        float:Erreur d'entropie croisée
    """

    #S'il y a une donnée, formez-la (faites une ligne de données)
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)

    #Calculer l'erreur et normaliser par le nombre de lots
    batch_size = y.shape[0]
    return -np.sum(t * np.log(y + 1e-7)) / batch_size

Et puis il y a la classe de réseau neuronal. Puisqu'il est basé sur le code du chapitre précédent, il y a beaucoup des mêmes parties.

two_layer_net.py


# coding: utf-8
import numpy as np
from affine import Affine
from functions import numerical_gradient
from relu import ReLU
from softmax_with_loss import SoftmaxWithLoss


class TwoLayerNet:

    def __init__(self, input_size, hidden_size, output_size,
                 weight_init_std=0.01):
        """Réseau neuronal à deux couches
        
        Args:
            input_size (int):Nombre de neurones dans la couche d'entrée
            hidden_size (int):Nombre de neurones de couche cachée
            output_size (int):Nombre de neurones dans la couche de sortie
            weight_init_std (float, optional):Paramètre de réglage de la valeur initiale du poids. La valeur par défaut est 0.01。
        """

        #Initialisation du poids
        self.params = {}
        self.params['W1'] = weight_init_std * \
            np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * \
            np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)

        #Génération de couches
        self.layers = {}    # Python 3.OrderedDict n'est pas nécessaire car l'ordre de stockage du dictionnaire est conservé à partir de 7
        self.layers['Affine1'] = \
            Affine(self.params['W1'], self.params['b1'])
        self.layers['Relu1'] = ReLU()
        self.layers['Affine2'] = \
            Affine(self.params['W2'], self.params['b2'])
    
        self.lastLayer = SoftmaxWithLoss()

    def predict(self, x):
        """Inférence par réseau neuronal
        
        Args:
            x (numpy.ndarray):Entrée dans le réseau neuronal
        
        Returns:
            numpy.ndarray:Sortie de réseau neuronal
        """
        #Propager les couches vers l'avant
        for layer in self.layers.values():
            x = layer.forward(x)

        return x

    def loss(self, x, t):
        """Calcul de la valeur de la fonction de perte
        
        Args:
            x (numpy.ndarray):Entrée dans le réseau neuronal
            t (numpy.ndarray):Étiquette de réponse correcte

        Returns:
            float:Valeur de la fonction de perte
        """
        #inférence
        y = self.predict(x)

        # Softmax-with-Calculé par propagation directe de la couche de perte
        loss = self.lastLayer.forward(y, t)

        return loss

    def accuracy(self, x, t):
        """Calcul de la précision de la reconnaissance
        
        Args:
            x (numpy.ndarray):Entrée dans le réseau neuronal
            t (numpy.ndarray):Étiquette de réponse correcte
        
        Returns:
            float:Précision de reconnaissance
        """
        y = self.predict(x)
        y = np.argmax(y, axis=1)
        t = np.argmax(t, axis=1)
        
        accuracy = np.sum(y == t) / x.shape[0]
        return accuracy

    def numerical_gradient(self, x, t):
        """Calculer le gradient du paramètre de poids par différenciation numérique
        
        Args:
            x (numpy.ndarray):Entrée dans le réseau neuronal
            t (numpy.ndarray):Étiquette de réponse correcte
        
        Returns:
            dictionary:Un dictionnaire qui stocke les dégradés
        """
        grads = {}
        grads['W1'] = \
            numerical_gradient(lambda: self.loss(x, t), self.params['W1'])
        grads['b1'] = \
            numerical_gradient(lambda: self.loss(x, t), self.params['b1'])
        grads['W2'] = \
            numerical_gradient(lambda: self.loss(x, t), self.params['W2'])
        grads['b2'] = \
            numerical_gradient(lambda: self.loss(x, t), self.params['b2'])

        return grads

    def gradient(self, x, t):
        """Calculer le gradient pour le paramètre de poids par la méthode de propagation de l'erreur en retour
        
         Args:
            x (numpy.ndarray):Entrée dans le réseau neuronal
            t (numpy.ndarray):Étiquette de réponse correcte
        
        Returns:
            dictionary:Un dictionnaire qui stocke les dégradés
        """
        #Propagation vers l'avant
        self.loss(x, t)     #Propager vers l'avant pour calculer la valeur de la perte

        #Rétropropagation
        dout = self.lastLayer.backward()
        for layer in reversed(list(self.layers.values())):
            dout = layer.backward(dout)

        #Extraire la valeur différentielle de chaque couche
        grads = {}
        grads['W1'] = self.layers['Affine1'].dW
        grads['b1'] = self.layers['Affine1'].db
        grads['W2'] = self.layers['Affine2'].dW
        grads['b2'] = self.layers['Affine2'].db

        return grads

Le code dans le livre utilise ʻOrderedDict, mais ici nous utilisons l'habituel dict. Ceci est dû au fait qu'à partir de Python 3.7, l'ordre d'insertion des objets dict` est enregistré [^ 1].

5.7.3 Confirmation de gradient de la méthode de propagation de l'erreur

Ce code compare le gradient obtenu par la méthode de rétro-propagation d'erreur avec le gradient obtenu par différenciation numérique.

gradient_check.py


# coding: utf-8
import os
import sys
import numpy as np
from two_layer_net import TwoLayerNet
sys.path.append(os.pardir)  #Ajouter le répertoire parent au chemin
from dataset.mnist import load_mnist


#Lire les données d'entraînement MNIST et les données de test
(x_train, t_train), (x_test, t_test) = \
    load_mnist(normalize=True, one_hot_label=True)

#Génération de travail neuronal à deux couches
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

#Préparation des données pour vérification
x_batch = x_train[:3]
t_batch = t_train[:3]

#Calcul du gradient par différenciation numérique et méthode de propagation des erreurs
grad_numerical = network.numerical_gradient(x_batch, t_batch)
grad_backprop = network.gradient(x_batch, t_batch)

#Vérifiez la différence entre chaque poids
for key in grad_numerical.keys():
    #Calcul de la différence absolue
    diff = np.abs(grad_backprop[key] - grad_numerical[key])
    #Afficher la moyenne et le maximum
    print(f"{key}: [Différence moyenne]{np.average(diff):.10f} [Différence maximale]{np.max(diff):.10f}")

Dans le livre, je n'ai vérifié que la moyenne des différences de valeur absolue, mais j'ai également vérifié la valeur maximale des différences de valeur absolue.

W1: [Différence moyenne]0.0000000003 [Différence maximale]0.0000000080
b1: [Différence moyenne]0.0000000021 [Différence maximale]0.0000000081
W2: [Différence moyenne]0.0000000063 [Différence maximale]0.0000000836
b2: [Différence moyenne]0.0000001394 [Différence maximale]0.0000002334

Puisque «b2» est une valeur d'environ 7 chiffres après la virgule décimale, il semble que l'erreur soit un peu plus grande que le livre. Il peut y avoir un mauvais point dans la mise en œuvre. Si vous avez des questions, n'hésitez pas à me le faire savoir: transpiration:

5.7.4 Apprentissage en utilisant la méthode de propagation de retour d'erreur

Voici le code d'apprentissage.

mnist.py


# coding: utf-8
import os
import sys
import matplotlib.pylab as plt
import numpy as np
from two_layer_net import TwoLayerNet
sys.path.append(os.pardir)  #Ajouter le répertoire parent au chemin
from dataset.mnist import load_mnist


#Lire les données d'entraînement MNIST et les données de test
(x_train, t_train), (x_test, t_test) = \
    load_mnist(normalize=True, one_hot_label=True)

#Paramètres des hyper paramètres
iters_num = 10000       #Nombre de mises à jour
batch_size = 100        #Taille du lot
learning_rate = 0.1     #Taux d'apprentissage

#Enregistrer la liste des résultats
train_loss_list = []    #Modifications de la valeur de la fonction de perte
train_acc_list = []     #Précision de reconnaissance des données d'entraînement
test_acc_list = []      #Précision de reconnaissance des données de test

train_size = x_train.shape[0]  #Taille des données d'entraînement
iter_per_epoch = max(int(train_size / batch_size), 1)    #Nombre d'itérations par époque

#Génération de travail neuronal à deux couches
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

#Commencer à apprendre
for i in range(iters_num):

    #Mini génération de lots
    batch_mask = np.random.choice(train_size, batch_size, replace=False)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]

    #Calcul du gradient
    grad = network.gradient(x_batch, t_batch)

    #Mise à jour des paramètres de poids
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]
    
    #Calcul de la valeur de la fonction de perte
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)

    #Calcul de la précision de la reconnaissance pour chaque époque
    if i % iter_per_epoch == 0:
        train_acc = network.accuracy(x_train, t_train)
        test_acc = network.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)

        #Affichage de la progression
        print(f'[Nombre de mises à jour]{i:>4} [Valeur de la fonction de perte]{loss:.4f} '
              f'[Reconnaissance de l'exactitude des données d'entraînement]{train_acc:.4f} [Précision de reconnaissance des données de test]{test_acc:.4f}')

#Tracez la transition de la valeur de la fonction de perte
x = np.arange(len(train_loss_list))
plt.plot(x, train_loss_list, label='loss')
plt.xlabel('iteration')
plt.ylabel('loss')
plt.xlim(left=0)
plt.ylim(bottom=0)
plt.show()

#Dessinez la transition de la précision de reconnaissance des données d'entraînement et des données de test
x2 = np.arange(len(train_acc_list))
plt.plot(x2, train_acc_list, label='train acc')
plt.plot(x2, test_acc_list, label='test acc', linestyle='--')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.xlim(left=0)
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()

Et c'est le résultat de l'exécution de la même forme que le chapitre précédent.

[Nombre de mises à jour]   0 [Valeur de la fonction de perte]2.3008 [Reconnaissance de l'exactitude des données d'entraînement]0.0926 [Précision de reconnaissance des données de test]0.0822
[Nombre de mises à jour] 600 [Valeur de la fonction de perte]0.2575 [Reconnaissance de l'exactitude des données d'entraînement]0.9011 [Précision de reconnaissance des données de test]0.9068
[Nombre de mises à jour]1200 [Valeur de la fonction de perte]0.2926 [Reconnaissance de l'exactitude des données d'entraînement]0.9219 [Précision de reconnaissance des données de test]0.9242
[Nombre de mises à jour]1800 [Valeur de la fonction de perte]0.2627 [Reconnaissance de l'exactitude des données d'entraînement]0.9324 [Précision de reconnaissance des données de test]0.9341
[Nombre de mises à jour]2400 [Valeur de la fonction de perte]0.0899 [Reconnaissance de l'exactitude des données d'entraînement]0.9393 [Précision de reconnaissance des données de test]0.9402
[Nombre de mises à jour]3000 [Valeur de la fonction de perte]0.1096 [Reconnaissance de l'exactitude des données d'entraînement]0.9500 [Précision de reconnaissance des données de test]0.9483
[Nombre de mises à jour]3600 [Valeur de la fonction de perte]0.1359 [Reconnaissance de l'exactitude des données d'entraînement]0.9559 [Précision de reconnaissance des données de test]0.9552
[Nombre de mises à jour]4200 [Valeur de la fonction de perte]0.1037 [Reconnaissance de l'exactitude des données d'entraînement]0.9592 [Précision de reconnaissance des données de test]0.9579
[Nombre de mises à jour]4800 [Valeur de la fonction de perte]0.1065 [Reconnaissance de l'exactitude des données d'entraînement]0.9639 [Précision de reconnaissance des données de test]0.9600
[Nombre de mises à jour]5400 [Valeur de la fonction de perte]0.0419 [Reconnaissance de l'exactitude des données d'entraînement]0.9665 [Précision de reconnaissance des données de test]0.9633
[Nombre de mises à jour]6000 [Valeur de la fonction de perte]0.0393 [Reconnaissance de l'exactitude des données d'entraînement]0.9698 [Précision de reconnaissance des données de test]0.9649
[Nombre de mises à jour]6600 [Valeur de la fonction de perte]0.0575 [Reconnaissance de l'exactitude des données d'entraînement]0.9718 [Précision de reconnaissance des données de test]0.9663
[Nombre de mises à jour]7200 [Valeur de la fonction de perte]0.0850 [Reconnaissance de l'exactitude des données d'entraînement]0.9728 [Précision de reconnaissance des données de test]0.9677
[Nombre de mises à jour]7800 [Valeur de la fonction de perte]0.0403 [Reconnaissance de l'exactitude des données d'entraînement]0.9749 [Précision de reconnaissance des données de test]0.9686
[Nombre de mises à jour]8400 [Valeur de la fonction de perte]0.0430 [Reconnaissance de l'exactitude des données d'entraînement]0.9761 [Précision de reconnaissance des données de test]0.9685
[Nombre de mises à jour]9000 [Valeur de la fonction de perte]0.0513 [Reconnaissance de l'exactitude des données d'entraînement]0.9782 [Précision de reconnaissance des données de test]0.9715
[Nombre de mises à jour]9600 [Valeur de la fonction de perte]0.0584 [Reconnaissance de l'exactitude des données d'entraînement]0.9777 [Précision de reconnaissance des données de test]0.9707

スクリーンショット 2020-01-19 1.20.06.png スクリーンショット 2020-01-19 1.20.59.png

Par rapport aux résultats du chapitre précédent, la précision de la reconnaissance augmente plus rapidement. En fin de compte, c'était environ 97%. La seule différence entre la différenciation numérique et la méthode de propagation de l'erreur en retour devrait être la méthode de calcul du gradient, il semble donc que le changement de la fonction sigmoïde à la fonction ReLU a conduit à une amélioration.

5.8 Résumé

Le graphique de calcul doit être facile à comprendre. Il était également bien entendu que la couche de sortie et la fonction de perte étaient conçues de manière à ce que la valeur différentielle puisse être facilement obtenue.

C'est tout pour ce chapitre. Si vous avez des erreurs, je vous serais reconnaissant de bien vouloir les signaler. (Vers d'autres chapitres de ce mémo: Chapitre 1 / Chapitre 2 / Chapitre 3 / Chapitre 4 / Chapitre 5 / [Chapitre 6](https: / /qiita.com/segavvy/items/ca4ac4c9ee1a126bff41) / Chapitre 7 / Chapitre 8 / Résumé)

[^ 1]: Voir «Amélioration du modèle de données Python» dans Nouveautés de Python 3.7.

Recommended Posts

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 à 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 à partir de zéro.
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 2
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 5
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 2
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
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 from scratch" avec Haskell (inachevé)
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 ① Chapitre 6 "Techniques liées à l'apprentissage"
Deep Learning from scratch Chapter 2 Perceptron (lecture du mémo)
Apprentissage profond à partir de zéro 1 à 3 chapitres
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
Créez un environnement pour "Deep Learning from scratch" avec Docker
Apprentissage profond à partir de zéro (calcul des coûts)
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
Mémo d'apprentissage profond créé à partir de zéro
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 6 Mémo
[Deep Learning from scratch] J'ai essayé d'expliquer la confirmation du gradient d'une manière facile à comprendre.
"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
Pourquoi ModuleNotFoundError: Aucun module nommé'dataset.mnist 'n'apparaît dans "Deep Learning from scratch".
Écrivez vos impressions sur l'édition du framework Deep Learning 3 créée à partir de zéro
Apprentissage profond à partir de zéro (propagation vers l'avant)
Apprentissage profond / Apprentissage profond à partir de zéro 2-Essayez de déplacer GRU
[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
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 12) Deep learning
Python vs Ruby «Deep Learning from scratch» Chapitre 2 Circuit logique par Perceptron
Python vs Ruby "Deep Learning from scratch" Chapitre 4 Implémentation de la fonction de perte
Mémo d'auto-apprentissage "Deep Learning from scratch" (glossaire illisible)
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 9) Classe MultiLayerNet
Un amateur a essayé le Deep Learning avec Caffe (Introduction)
GitHub du bon livre "Deep Learning from scratch"
Un amateur a essayé le Deep Learning en utilisant Caffe (Practice)
[Mémo d'apprentissage] Apprentissage profond à partir de zéro ~ Mise en œuvre de l'abandon ~
Un amateur a essayé le Deep Learning avec Caffe (Vue d'ensemble)
Résumé Python vs Ruby "Deep Learning from scratch"
Mémo d'auto-apprentissage «Deep Learning from scratch» (10) Classe MultiLayerNet
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 11) CNN
Python vs Ruby "Deep Learning from scratch" Chapitre 3 Implémentation d'un réseau neuronal à 3 couches
[Python] [Traitement du langage naturel] J'ai essayé le Deep Learning ❷ fait de toutes pièces en japonais ①
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
Version Lua Deep Learning from scratch Part 5.5 [Rendre les fichiers pkl disponibles dans Lua Torch]
[Pour les débutants] Après tout, qu'est-ce qui est écrit dans Deep Learning fait à partir de zéro?