-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 $.
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.
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.
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}
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.
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.
f(u) = \left\{
\begin{array}{ll}
1 & (u \gt 0) \\
0 & (u \leq 0)
\end{array}
\right.
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 $.
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.
f(u) = \left\{
\begin{array}{ll}
1 & (u \gt 0) \\
0 & (u \leq 0)
\end{array}
\right.
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.
$ \ 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.
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
Pour les neurones de la couche intermédiaire de 30 $:
Pour 100 $ le nombre de neurones de la couche intermédiaire:
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.
"Réseau neuronal", Yasunari Yoshitomi, Asakura Shoten,
Recommended Posts