[PYTHON] J'ai créé mon propre réseau de neurones à propagation directe à 3 couches et j'ai essayé de comprendre le calcul en profondeur.

introduction

L'apprentissage automatique et l'apprentissage en profondeur sont riches en bibliothèques, vous pouvez donc faire des prédictions avec un simple copier-coller. J'ai moi-même exécuté des programmes créés par de nombreux ancêtres et suis arrivé à un niveau où je peux comprendre les grandes lignes. En particulier, l'apprentissage en profondeur (réseau neuronal) est appliqué au GAN et au traitement du langage naturel. C'est un genre où les nouvelles technologies sont créées à un rythme vertigineux, et je crois que son application à la société et à l'industrie progresse rapidement. Par conséquent, nous la reconnaissons comme la technologie au centre d'une telle transformation et aimerions avoir une compréhension très intéressante et approfondie de ces domaines! Il y a un motif.

Actuellement, nous commençons à apprendre des bases ici, qui est célèbre comme un manuel d'apprentissage en profondeur. https://www.oreilly.co.jp/books/9784873117584/ Cette fois, en construisant un réseau de neurones à partir de presque rien (bien que j'utilise numpy), j'aimerais avoir une idée réelle des calculs qui y sont effectués.

Le résumé est ci-dessous.

Comprendre Perceptron

Perceptron signifie qu'il reçoit plusieurs signaux en tant qu'entrées et sort un signal. Dans le domaine de l'apprentissage automatique, ne pas émettre de signal est traité comme 0 et sortir un signal est traité comme 1.

image.png

La figure ci-dessus est un simple schéma de cette idée. x est le signal d'entrée, y est le signal de sortie et w est le poids. Ce 〇 s'appelle un neurone. Le neurone reçoit la somme du poids multipliée par la valeur d'entrée. A ce moment, la sortie 1 est sortie lorsque la somme totale dépasse le seuil θ. La formule est la suivante.

image.png

Vérifiez avec le circuit ET

Maintenant, faisons un programme. J'ai reproduit le modèle simple montré dans la figure ci-dessus. Tout d'abord, calculons quand le seuil est de 0,4.

NN.ipynb



def AND(x1,x2):
    w1,w2,theta = 0.5,0.5,0.4
    tmp = x1*w1 + x2*w2
    b = -0.5
    if tmp <= theta:
        return 0
    elif tmp > theta:
        return 1

python


print(AND(0,0))
print(AND(1,0))
print(AND(0,1))
print(AND(1,1))

0
1
1
1

En conséquence, il a été constaté que si x1 ou x2 est égal à 1, 1 est sorti en sortie. En revanche, si le seuil est de 0,7, ce sera le suivant.


print(AND(0,0))
print(AND(1,0))
print(AND(0,1))
print(AND(1,1))
0
0
0
1

Si un seul de x1 et x2 vaut 1, la sortie ne crachera plus 1. Vous pouvez voir que la sortie obtenue change en fonction du réglage du seuil.

Étendez-vous à un réseau neuronal

Un perceptron multicouche est un réseau qui a une couche appelée couche intermédiaire entre la couche d'entrée et la couche de sortie. La description peut différer selon le livre, mais dans le cas de la figure ci-dessous, la couche d'entrée est appelée couche 0, la couche intermédiaire est appelée 1 couche et la couche de sortie est appelée 2 couches. image.png

Comment compter les couches du réseau neuronal

image.png

Ici, il semble y avoir un style (personnalisé?) Dans la façon de compter en l'appelant un réseau de neurones à 〇 couches. Il semble que nous puissions compter la couche de poids ou appeler la couche de neurones. Je n'ai pas beaucoup d'expérience avec ce qui est le plus courant, mais j'aimerais suivre le manuel d'O'Reilly et le nommer en fonction du poids.

Comprendre les préjugés

image.png image.png

Ensuite, nous introduisons une valeur appelée biais b. En réarrangeant l'équation ci-dessus avec le seuil précédent θ comme -b, il est possible de déterminer la sortie de y à 0 ou 1 avec 0 comme référence, comme dans l'équation ci-dessus. Le biais est la signification d'une valeur de correction qui "bloque" dans l'industrie du petit travail (industrie manufacturière), et il est possible d'augmenter ou de réduire la valeur sur l'axe y dans son ensemble.

Comprendre la fonction d'activation

image.png image.png

La fonction qui détermine si y vaut 0 ou 1 est appelée fonction d'activation. Comme la valeur obtenue par cette fonction d'activation peut être une valeur proche de 0 ou 1, il existe également une fonction qui peut empêcher le calcul de diverger. Il existe plusieurs types de cette fonction d'activation.

C'est l'une des fonctions souvent utilisées dans la fonction d'activation. C'est une fraction de la fonction du nombre de Napier e, qui est la base du logarithme naturel comme indiqué ci-dessous. La forme de cette fonction est difficile à trouver, mais elle ressemble à ce qui suit.

image.png

NN.ipynb



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


xxx = np.arange(-5.0,5.0,0.1)#Afficher la fonction sigmoïde
yyy = sigmoid(xxx)
plt.plot(xxx,yyy)
plt.ylim(-0.1,1.1)
plt.show

001.png

On peut voir que lorsque x> 0 avec x = 0 comme limite, il s'approche progressivement de y = 1. Au contraire, lorsque x <0, il s'approche progressivement de y = 0. Vous pouvez voir que c'est très pratique car la valeur d'entrée peut être sortie entre 0 et 1 car elle joue le rôle de la fonction d'activation.

Ensuite, il y a une fonction pas à pas en tant que fonction qui produit 0,1 à l'extrême de la fonction sigmoïde. Cela s'écrirait comme suit.

NN.ipynb


def step_function(x):
    return np.array(x > 0, dtype=np.int)

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.plot(xxx,yyy)
plt.plot(x, y)
plt.ylim(-0.1, 1.1) 
plt.show()

003.png

Le bleu est la fonction d'étape et l'orange est la fonction sigmoïde. Vous pouvez voir que la valeur de sortie n'est que de 0 ou 1. Je ne sais pas comment utiliser correctement cette fonction, alors laissez-moi en faire mes futurs devoirs. ** En tant que sentiment, je comprends que la fonction sigmoïde a pour fonction de distinguer la différence même avec une légère différence d'entrée car elle peut prendre la valeur plus finement. Par contre, s'il y a plusieurs couches et que la charge de calcul est élevée, je pense qu'il est possible de distinguer tout en réduisant la charge en utilisant la fonction step selon le cas. ** **

Enfin, je voudrais parler de la fonction ReLU (Rectified Linear Unit), qui a également l'impression d'être souvent utilisée. Si x dépasse 0, la valeur est sortie sous la forme y telle quelle, et si elle est égale ou inférieure à 0, 0 est sortie.

NN.ipynb


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

xx = np.arange(-5.0,5.0,0.1)
yy = relu(xx)
plt.plot(xx,yy)
plt.ylim(-0.1,5)
plt.show

004.png

Quel est le type de propagation directe

Cette fois, nous allons créer un réseau neuronal de type propagation directe. Ce type de propagation vers l'avant indique que le flux circule de l'entrée vers la sortie dans une direction. Lorsque vous envisagez de former un modèle, le calcul est effectué de la sortie à l'entrée. C'est ce qu'on appelle la méthode de rétropropagation.

Implémenter un réseau neuronal à 3 couches

Maintenant, je voudrais vraiment décrire un réseau neuronal à trois couches.

image.png Envisagez de créer un réseau neuronal à trois couches, comme illustré dans la figure ci-dessus. Tout d'abord, supprimons uniquement les calculs qui ressortent en gras dans la figure ci-dessus ci-dessous.

NN.ipynb


def init_network():
    network = {}
    network['W1'] = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
    network['b1'] = np.array([0.1,0.2,0.3])
    return network

def forword(network,x):
    W1= network['W1']
    b1= network['b1']
    
    a1 = np.dot(x,W1)+b1
    z1 = sigmoid(a1)
    
    return y

network = init_network()
x = np.array([2,1])
z1 = forword(network,x)
print(z1)
[0.40442364 0.59557636]

Je laisse la fonction init_network () définir les poids et les biais, et la fonction forword () définir les formules qui calculent réellement. Après cela, la fonction est appelée et la valeur initiale x est attribuée afin que la réponse puisse être crachée. C'est plus facile à comprendre que d'écrire sans définir une fonction d'affilée.

** Notez également la fonction qui représente le produit interne de la matrice décrite ici comme np.dot. Soyez prudent lorsque vous décrivez le produit des matrices, car les dimensions de la matrice obtenue dans l'ordre de multiplication changent. ** **

image.png

Réseau neuronal à 3 couches

NN.ipynb


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

def forword(network,x):
    W1,W2,W3 = network['W1'],network['W2'],network['W3']
    b1,b2,b3 = network['b1'],network['b2'],network['b3']
    
    a1 = np.dot(x,W1)+b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1,W2)+b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2,W3)+b3
    y = softmax(a3)
    
    return y

Si vous laissez les deux fonctions décrire jusqu'à la fin, cela s'écrira ainsi. Eh bien, je l'ai mentionné plus tôt ici, mais il y a une description écrite comme softmax à la fin. Ceci est résumé ci-dessous.

Fonction égale et fonction softmax

Après cela, nous pouvons voir que nous devons ajouter des couches à ces deux fonctions. Ensuite, considérez la valeur y comme sortie à la fin. Lorsqu'il est nécessaire de classer des problèmes tels que l'estimation de 0 à 9 types de nombres, la probabilité correspondant à chaque type est sortie et celle avec la probabilité la plus élevée est utilisée comme valeur prédite. Une fonction pratique pour exprimer une telle probabilité est la fonction softmax. image.png

La somme des valeurs prises pour tous les éléments d'une certaine catégorie peut être utilisée comme dénominateur, et les valeurs individuelles prises peuvent être utilisées comme numérateur pour représenter la probabilité. En terminant par cette fonction softmax, le problème de classification est réduit à la probabilité, et la valeur la plus élevée est la valeur prédite.   image.png

En termes d'implémentation, puisqu'il s'agit d'une fonction exponentielle de exp, il existe un problème en ce que la valeur est très facile à diverger. Par conséquent, il semble que c'est souvent fait pour des raisons de commodité qu'il devient difficile de diverger en multipliant une certaine constante par le dénominateur et la molécule et en l'insérant dans l'exposant de exp.

NN.ipynb



def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a-c)
    sum_exp_a = np.sum(exp_a)
    y = exp_a/sum_exp_a
    return y

Entrez les conditions initiales et sortez la réponse

NN.ipynb


network = init_network()
x = np.array([2,1])
y = forword(network,x)
print(y)
[0.40442364 0.59557636]

En guise de test, j'ai mis une valeur appropriée dans x et la réponse a été renvoyée comme suit. Une valeur indiquant que y1 a une probabilité de 40% et y2 a une probabilité de 60% a été sortie. Après cela, je comprends qu'une classification compliquée deviendra possible à mesure que la matrice d'entrée deviendra plus grande et que les couches deviendront plus profondes (≈ augmenter).

À la fin

Cette fois, j'ai créé à la main un réseau de neurones très basique. Juste en bougeant ma main, j'ai approfondi ma compréhension. ** J'ai finalement compris les bases de l'algorithme GAN que j'ai copié et déplacé. ** En mettant ici des idées telles que l'apprentissage de modèle et la convolution, il sera connecté au réseau neuronal de convolution et ensuite au GAN. C'est peut-être un début pour atteindre les dernières technologies, mais j'espère qu'en approfondissant régulièrement ma compréhension de cette manière, j'améliorerai sûrement mes capacités techniques.

Le programme complet est ici. Il est divisé en un fichier que vous venez de jouer avec la fonction et un fichier qui est un réseau neuronal à 3 couches. https://github.com/Fumio-eisan/neuralnetwork_20200318

Recommended Posts

J'ai créé mon propre réseau de neurones à propagation directe à 3 couches et j'ai essayé de comprendre le calcul en profondeur.
J'ai essayé d'améliorer la précision de mon propre réseau neuronal
Ce à quoi j'étais accro lorsque j'ai construit mon propre réseau de neurones en utilisant les poids et les biais que j'ai obtenus avec le classificateur MLP de scikit-learn.
J'ai essayé de contrôler la bande passante et le délai du réseau avec la commande tc
J'ai essayé de comprendre attentivement la fonction d'apprentissage dans le réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique (deuxième moitié)
J'ai essayé de comprendre comment utiliser les pandas et la colinéarité multiple en utilisant l'ensemble de données Affaires comme thème.
J'ai essayé de résumer quatre méthodes d'optimisation de réseau neuronal
J'ai essayé de bien le comprendre en implémentant l'algorithme Adaboost en machine learning (+ j'ai approfondi ma compréhension du calcul de tableaux)
J'ai essayé de prédire le genre de musique à partir du titre de la chanson sur le réseau neuronal récurrent
J'ai essayé de mettre en œuvre le modèle de base du réseau neuronal récurrent
Réseau de neurones pour comprendre et mettre en œuvre en mathématiques au secondaire
J'ai essayé d'illustrer le temps et le temps du langage C
J'ai essayé d'afficher l'heure et la météo d'aujourd'hui w
J'ai essayé d'énumérer les différences entre java et python
J'ai essayé de classer la musique en majeur / mineur sur Neural Network
J'ai fait ma propre langue. (1)
J'ai fait ma propre langue (2)
J'ai fait ma propre AML
Je ne suis pas sûr de la différence entre les modules, les packages et les bibliothèques, alors j'ai essayé de les organiser.
J'ai créé ma propre bibliothèque Python
J'ai essayé de comprendre la normalisation spectrale et la décomposition de valeurs singulières qui contribuent à la stabilité du GAN.
J'ai essayé de déplacer le ballon
J'ai essayé d'estimer la section.
J'ai créé mon propre outil de recherche à l'aide de l'API Law [Smart Roppo]
J'ai essayé de résumer jusqu'à ce que je quitte la banque et devienne ingénieur
J'ai essayé de déplacer l'image vers le dossier spécifié en faisant un clic droit et un clic gauche
J'ai essayé de visualiser la tranche d'âge et la distribution des taux d'Atcoder
J'ai essayé d'exprimer de la tristesse et de la joie face au problème du mariage stable.
[Deep Learning from scratch] J'ai essayé d'implémenter la couche sigmoïde et la couche Relu
J'ai essayé d'apprendre l'angle du péché et du cos avec le chainer
J'ai créé un réseau pour convertir des images noir et blanc en images couleur (pix2pix)
J'ai essayé d'extraire et d'illustrer l'étape de l'histoire à l'aide de COTOHA
Je n'ai ni les compétences ni la force, mais j'ai créé mon propre compilateur
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
J'ai essayé de comprendre l'arbre de décision (CART) pour classer soigneusement
J'ai implémenté le modèle VGG16 avec Keras et essayé d'identifier CIFAR10
Introduction à la création d'IA avec Python! Partie 3 J'ai essayé de classer et de prédire les images avec un réseau de neurones convolutifs (CNN)
J'ai essayé de comprendre attentivement la fonction d'apprentissage dans le réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique (première moitié)
Introduction à la création d'IA avec Python! Partie 2 J'ai essayé de prédire le prix de l'immobilier dans la ville de Boston avec un réseau neuronal
J'ai essayé de résumer la commande umask
J'ai essayé de reconnaître le mot de réveil
J'ai essayé de résumer la modélisation graphique.
J'ai essayé d'estimer le rapport de circonférence π de manière probabiliste
J'ai essayé de toucher l'API COTOHA
J'ai fait de mon mieux pour retourner au Lasso
J'ai essayé de notifier la mise à jour de "Hameln" en utilisant "Beautiful Soup" et "IFTTT"
J'ai essayé de publier mon propre module pour pouvoir l'installer
[Ansible] Je souhaite appeler ma propre fonction à partir du module de modèle (macro)
J'ai essayé de rendre mon propre code source compatible avec Chainer v2 alpha
J'ai fait un modèle de classification d'images et essayé de le déplacer sur mobile
J'ai essayé de traiter et de transformer l'image et d'élargir les données pour l'apprentissage automatique
[EN DIRECT] J'ai essayé de fournir les heures de lever et de coucher du soleil dans tout le pays chaque jour
[Introduction à AWS] J'ai essayé de porter une application de conversation et de jouer avec text2speech @ AWS ♪
Je n'ai pas compris le redimensionnement de TensorFlow, alors je l'ai résumé visuellement.
J'ai essayé de passer le test G et la qualification E en m'entraînant à partir de 50
[Pas de code] J'ai écrit sur les courbes elliptiques et la blockchain dans ma thèse de fin d'études, alors j'ai essayé de résumer la méthode d'étude