[PYTHON] Principes de base et mise en œuvre de Perceptron

Apprendre Perceptron

Réseau à utiliser

-Un réseau composé de trois couches: une couche d'entrée, une couche intermédiaire et une couche de sortie. ・ Les couches sont entièrement connectées. -Tous les neurones produisent 1 $ ou 0 $.

image.png

Le but de Perceptron est d'apprendre le poids (charge synaptique) entre la couche intermédiaire et la couche de sortie et de générer le motif de sortie correspondant au motif d'entrée.

Couche d'entrée

Supposons que vous ayez des neurones $ M $. Il reçoit l'entrée de l'extérieur telle quelle et la délivre. La sortie du $ i $ ème neurone est exprimée par la formule suivante. $output_i = input_i$

Couche intermédiaire

Supposons que vous ayez des neurones $ N $. L'entrée donnée au $ j $ ème neurone dans la couche intermédiaire est la somme des valeurs de sortie de tous les neurones de la couche d'entrée multipliée par la charge synaptique $ w_ {i, j} . $input_j=\sum_{i=1}^{M}{w_{i,j}output_i}$$

Ensuite, définissez le seuil $ \ theta_j $ pour le signal reçu par chaque neurone de la couche intermédiaire et réduisez-le de ce montant. $input_j-\theta_j$

Puisque la sortie est seulement $ 0 $ ou $ 1 $, définissez la fonction de sortie $ f (x) $. Par conséquent, la valeur de sortie du neurone $ j $ th dans la couche intermédiaire est exprimée par la formule suivante. $output_j = f(input_j-\theta_j)$

f(u) = \left\{
\begin{array}{ll}
1 & (u \gt 0) \\
0 & (u \leq 0)
\end{array}
\right.

Couche de sortie

L'entrée de la couche de sortie, comme l'entrée de la couche intermédiaire, est la valeur de sortie de tous les neurones de la couche précédente multipliée par la charge synaptique. Soit le nombre de neurones de la couche de sortie égale à 1 $.

input_o=\sum_{j=1}^{N}{w_{j,o}output_j}

Et la sortie de la couche de sortie est le résultat de l'application de $ f (x) $ à la valeur obtenue en soustrayant le seuil de l'entrée, comme dans la couche intermédiaire.

output_o=f(input_o-\theta_o)
f(u) = \left\{
\begin{array}{ll}
1 & (u \gt 0) \\
0 & (u \leq 0)
\end{array}
\right.

Apprentissage

Pendant l'entraînement, seule la charge synaptique $ w_ {j, o} $ entre la couche de sortie et la couche intermédiaire est mise à jour sans changer les autres paramètres.

\Delta w_{j,o}=\eta(t_o-output_o)output_j
w^{t+1}=w^{t}+\Delta w_{j,o}

$ \ eta $ est le taux d'apprentissage, et il est courant de définir une petite valeur positive. $ t_o-output_o $ est la différence entre la sortie $ t_o $ des données de l'enseignant et les données de sortie réelles $ output_o $. Par conséquent, on peut voir que la charge synaptique n'est mise à jour que lorsque le résultat calculé et le signal de l'enseignant sont différents.

L'explication et la preuve du théorème de convergence de Perceptron sont omises ici. Si vous êtes intéressé, veuillez le vérifier.

la mise en oeuvre

réglages des paramètres

code

Installation de la bibliothèque et configuration du chemin d'entrée

import numpy as np
import matplotlib.pyplot as plt

PATH_X = "./../input_x.npy"
PATH_Y = "./../input_y.npy"

Convertir les données d'entrée de $ (x, y) $ en $ 0 $ et $ 1 $ colonnes de longueur 8 $ $

def to_input(data):
    x = data[0]
    y = data[1]
    n = x * 16 + y
    return np.array([int(k) for k in format(n, '08b')])

Classe Perceptron __Mise en garde! __ Le calcul de la charge dans le programme est calculé en considérant la formule expliquée ci-dessus comme un vecteur.

class Perceptron:
    def __init__(self, m, n, o):
        # decide initial weight [-0.005,0.005)
        #J'ai ajouté 1 pour gérer le seuil facilement
        self.w_IM = np.random.rand(n,m+1) - 0.5
        self.w_IM = self.w_IM / 100
        self.w_MO = np.random.rand(o,n+1) - 0.5
        self.w_MO = self.w_MO / 100

    # calculate accuracy
    def get_acc(self, x, y):
        ok = 0
        for i in range(len(x)):
            #J'ajoute un neurone qui produit toujours 1
            mid_in = np.inner(np.append(x[i],1.), self.w_IM)
            mid_out = np.array([int(k > 0) for k in mid_in])
            #J'ajoute un neurone qui produit toujours 1
            out_in = np.inner(np.append(mid_out,1.), self.w_MO)
            ok += int(int(out_in[0] > 0) == y[i])
        return ok / len(x)

    def learn(self, train_x, train_y, eta = 0.00001):
        #J'ajoute un neurone qui produit toujours 1
        mid_in = np.inner(np.append(train_x,1.), self.w_IM)
        mid_out = np.array([int(k > 0) for k in mid_in])
        #J'ajoute un neurone qui produit toujours 1
       out_in = np.inner(np.append(mid_out,1.), self.w_MO)
        out = int(out_in[0] > 0)

        #Mise à jour de la charge à partir des valeurs de sortie et des données de l'enseignant
        self.w_MO[0,:-1] = self.w_MO[0,:-1] + eta * (train_y - out) * mid_out

Définition des paramètres et graphique des résultats du dessin

def main():
    # read datas
    x = np.load(PATH_X)
    y = np.load(PATH_Y)
    # split datas
    train_x, test_x = np.split(x, 2)
    train_y, test_y = np.split(y, 2)
    # preprocess - transfer data into inputs
    datas = np.array([to_input(k) for k in train_x])
    tests = np.array([to_input(k) for k in test_x])
    # number of neurons input layer
    m = 8
    # number of neurons mid layer
    n = 10
    # number of neurons output layer
    o = 1
    # define the perceptron
    P = Perceptron(m,n,o)
    
    # learning time
    N = 10
    cnt = 0

    x = np.linspace(0,200,200)
    acc_train = np.copy(x)
    acc_test = np.copy(x)
    while True:
        acc = P.get_acc(datas, train_y)
        acc_train[cnt] = acc
        acc = P.get_acc(tests, test_y)
        acc_test[cnt] = acc
        print("Try ", cnt, ": ", acc)
        cnt += 1
        for i in range(len(datas)):
            P.learn(datas[i], train_y[i])
        if cnt >= 200:
            break
    plt.plot(x,acc_train,label="train")
    plt.plot(x,acc_test,label="test")
    plt.savefig("result.png ")

if __name__ == "__main__":
    main()

Il est également téléchargé sur Github. https://github.com/xuelei7/NeuralNetwork/tree/master/Perceptron

résultat

Pour les neurones de la couche intermédiaire de 30 $:

Pour 100 $ le nombre de neurones de la couche intermédiaire:

en conclusion

S'il y a des points incorrects, je voudrais les corriger. Nous nous excusons pour la gêne occasionnée, mais veuillez contacter l'auteur.

Matériel de référence

"Réseau neuronal", Yasunari Yoshitomi, Asakura Shoten,

Recommended Posts

Principes de base et mise en œuvre de Perceptron
Bases de l'exploration et de l'implémentation / mesure Java
Explication et mise en œuvre du perceptron simple
La fondation de la fondation Perceptron
Explication et mise en œuvre de SocialFoceModel
Normalisation de la théorie et de la mise en œuvre des flux
bases de python: conditions et itérations
Description et implémentation de Maxout (Python)
Explication et mise en œuvre de PRML Chapitre 4
Introduction et mise en œuvre de JoCoR-Loss (CVPR2020)
Explication et implémentation de l'algorithme ESIM
Introduction et mise en œuvre de la fonction d'activation
Théorie et implémentation simples des réseaux neuronaux
Construction et bases de l'environnement de reconnaissance d'image
perceptron
Les bases d'Open3D et la boxe de groupe
Mise en œuvre et expérience de la méthode de clustering convexe
Bases statistiques et Python, graphisme, etc. (mémo)
Module d'implémentation de file d'attente et Python "deque"
Théorie et implémentation de PointNet (données de groupe de points)
Implémentation et description à l'aide de XGBoost pour les débutants
Résumé de la classification et de la mise en œuvre des algorithmes d'apprentissage automatique
Matplotlib Basics / Différence entre fig et axes
Régression de processus gaussien Implémentation Numpy et GPy
Apprenez en implémentant avec Scipy Les bases de la régression logistique et du perceptron multicouche