Poursuivant depuis la dernière fois, j'ai essayé d'étudier les réseaux neuronaux.
Cette fois, nous avons lancé le défi de construire un modèle de classification simple. Préparez les deux variables suivantes.
0 \le x_1,x_2 \le 1
Ensuite, classons comme suit en fonction de la somme des deux.
t(x_1,x_2) =
\left\{
\begin{matrix}
0 & (x_1 + x_2 < 1) \\
1 & (x_1 + x_2 \ge 1)
\end{matrix}
\right.
Implémentons un modèle aussi simple. En tant que concept neuronal à 0 couche, considérons la formule suivante.
y(x_1,x_2) = \sigma(w_1 x_1 + w_2 x_2 + w_0)
Cependant, σ est une fonction sigmoïde, et sa sortie est limitée à [0,1]. C'est vraiment caractéristique, et il semble que cela ait une signification telle que la classification A si y <0,5 et la classification B si y> 0,5. En fait, je pense que cela fait vraiment partie du foie. Dans le réseau neuronal, un mécanisme qui donne une réponse en ajustant w1, w2, w0. Donc, compte tenu de la fonction qui estime l'erreur, il semble s'agir d'entropie croisée dans ce cas. Plus précisément, lorsque la bonne réponse t est donnée à x1 et x2, l'entropie d'intersection est exprimée comme suit.
E(w_1,w_2,w_0) = - (t \ln y + (1-t) \ln (1-y) )
Pour plus de détails, reportez-vous à "Reconnaissance de formes et apprentissage automatique" (vers la page 235), mais à titre d'image approximative ... Faites attention à 0 <y <1
Ensuite, la probabilité p (t) lorsque t est donnée est en unifiant la formule en utilisant X ^ 0 = 1.
p(t)= y^t (1-y)^{1-t}
Il semble que. Après cela, si vous vous connectez, la formule de E (w1, w2, w0) sera dérivée. Ceci est multiplié pour chaque échantillon, donc pour chaque yi
p(t)= \prod_i y_i^t (1-y_i)^{1-t}
Alors prends un journal
\ln p(t)= \sum_i (t \ln y_i + (1-t) \ln (1-y_i) )
Ce sera. C'est comme la somme des taux de réponse corrects, donc plus vous correspondez, plus la valeur est élevée. Par conséquent, nous avons défini E en inversant le signe pour le résoudre comme un problème d'optimisation (minimisation). Encore une fois, l'entropie croisée est: (Plusieurs exemples de versions)
E(w_1,w_2,w_0) = - \sum_i (t \ln y_i + (1-t) \ln (1-y_i) )
Maintenant, écrivons réellement le code source. Tout d'abord, la partie variable.
# make placeholder
x_ph = tf.placeholder(tf.float32, [None, 3])
t_ph = tf.placeholder(tf.float32, [None, 1])
x_ph est la partie d'entrée, elle devrait être deux, mais j'ai mis une variable factice (fixée à 1) pour w0. Vous n'avez peut-être pas besoin de ça? t_ph est la partie sortie et sert à donner la bonne réponse. Contient 0 ou 1.
Ensuite, les données d'échantillon à inclure dans ceci sont définies de manière appropriée avec des nombres aléatoires.
# deta making???
N = 1000
x = np.random.rand(N,2)
# sum > 1.0 -> 1 : else -> 0
t = np.floor(np.sum(x,axis=1))
# ext x
x = np.hstack([x,np.ones(N).reshape(N,1)])
Après avoir créé deux x, créez y, puis ajoutez une variable factice. En conséquence, x est tridimensionnel dans un échantillon. y est créé à l'aide de la troncature fractionnaire de sorte que x1 + x2 est 1 lorsqu'il est 1 ou plus et 0 lorsqu'il est inférieur à 1.
Et, pour le moment, préparez environ deux couches du réseau neuronal.
# create newral parameter(depth=2,input:3 > middle:30 > output:1)
hidden1 = tf.layers.dense(x_ph, 30, activation=tf.nn.relu)
newral_out = tf.layers.dense(hidden1, 1, activation=tf.nn.sigmoid)
Définissons maintenant l'entropie croisée et définissons l'apprentissage pour la minimiser. C'est juste une copie. Je ne suis toujours pas sûr des paramètres de l'algorithme de convergence.
# Minimize the cross entropy
ce = -tf.reduce_sum(t_ph * tf.log(newral_out) + (1-t_ph)*tf.log(1-newral_out) )
optimizer = tf.train.AdamOptimizer()
train = optimizer.minimize(ce)
Donc, j'ai essayé de faire la source entière en combinant ce qui précède de manière appropriée.
import numpy as np
import tensorflow as tf
# deta making???
N = 1000
x = np.random.rand(N,2)
# sum > 1.0 > 1 : else > 0
t = np.floor(np.sum(x,axis=1))
# ext x
x = np.hstack([x,np.ones(N).reshape(N,1)])
train_x = x
train_t = t
# make placeholder
x_ph = tf.placeholder(tf.float32, [None, 3])
t_ph = tf.placeholder(tf.float32, [None, 1])
# create newral parameter(depth=2,input:3 > middle:30 > output:1)
hidden1 = tf.layers.dense(x_ph, 30, activation=tf.nn.relu)
newral_out = tf.layers.dense(hidden1, 1, activation=tf.nn.sigmoid)
# Minimize the cross entropy
ce = -tf.reduce_sum(t_ph * tf.log(newral_out) + (1-t_ph)*tf.log(1-newral_out) )
optimizer = tf.train.AdamOptimizer()
train = optimizer.minimize(ce)
# initialize tensorflow session
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for k in range(1001):
if np.mod(k,100) == 0:
# get Newral predict data
y_newral = sess.run( newral_out
,feed_dict = {
x_ph: x, #Je mets les données d'entrée dans x
})
ce_newral = sess.run( ce
,feed_dict = {
x_ph: x, #Je mets les données d'entrée dans x
t_ph: t.reshape(len(t),1) #J'ai mis les bonnes données de réponse dans y
})
sign_newral = np.sign(np.array(y_newral).reshape([len(t),1]) - 0.5)
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
# check predict NewralParam
print('[%d] loss %.2f hit_per:%.2f' % (k,ce_newral,(N-NGCNT)/N))
# shuffle train_x and train_t
n = np.random.permutation(len(train_x))
train_x = train_x[n]
train_t = train_t[n].reshape([len(train_t), 1])
# execute train process
sess.run(train,feed_dict = {
x_ph: train_x, # x is input data
t_ph: train_t # t is true data
})
#Pour le test
x = np.array([0.41,0.5,1]).reshape([1,3])
loss_newral = sess.run( newral_out
,feed_dict = {
x_ph: x, #Je mets les données d'entrée dans x
})
# <0.Le 5 est-il un succès?
print(loss_newral)
Si vous déplacez ceci, ce sera comme suit.
[0] loss 727.36 hit_per:0.35
[100] loss 587.68 hit_per:0.78
[200] loss 465.78 hit_per:0.89
[300] loss 358.70 hit_per:0.93
[400] loss 282.45 hit_per:0.94
[500] loss 230.54 hit_per:0.96
[600] loss 194.34 hit_per:0.97
[700] loss 168.11 hit_per:0.98
[800] loss 148.34 hit_per:0.98
[900] loss 132.93 hit_per:0.99
[1000] loss 120.56 hit_per:0.99
[[0.27204064]]
Là où la perte est écrite, vous pouvez voir que la valeur d'entropie croisée diminue progressivement. (Changer le nom de la variable ...) Et hit_per est le taux de réponse correct pour les données d'entraînement. À 1,00, il devient 100%, mais il semble que le taux de réussite soit de 99%. Enfin, la sortie du réseau neuronal lorsqu'un test approprié, x1 = 0,45, x2 = 0,5 est entré. Dans ce cas, il doit être de classe B t = 0, donc si la sortie est inférieure à 0,5, elle est correcte, et si elle est plus proche de 0,5, on peut lire qu'elle est perdue. Cette fois, il est de 0,27, donc je suis assez confiant pour y répondre.
Enfin, j'écrirai un peu comment obtenir la bonne réponse. Je pense que le fait est que nous donnons le nombre de NG. Quelques micros ci-dessous.
# get Newral predict data
y_newral = sess.run( newral_out
,feed_dict = {
x_ph: x, #Je mets les données d'entrée dans x
})
sign_newral = np.sign(np.array(y_newral).reshape([len(t),1]) - 0.5)
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
y_newral contient des informations de classification estimées à partir de x dans la plage [0,1]. Ce nombre signifie s'il appartient à la catégorie supérieure ou inférieure à 0,5, il est donc nécessaire de le convertir en une forme qui peut être discriminée. Par conséquent, j'ai soustrait la valeur de 0,5, je l'ai déplacée en parallèle à la plage de [-0,5, 0,5], puis j'ai extrait uniquement le code de sorte que +1 ou -1 soit sélectionné. Le même processus est effectué pour t (réponse correcte) pour générer une valeur de réponse correcte + 1 / -1. Ces deux sont corrects lorsqu'ils ont la même valeur et incorrects lorsqu'ils ont des valeurs différentes, mais lorsque le modèle est écrit, ils ont la relation suivante.
Valeur estimée | Valeur de réponse correcte | Exactitude estimée | Valeur estimée-Valeur de réponse correcte |
---|---|---|---|
1 | 1 | OK | 0 |
1 | -1 | NG | 2 |
-1 | 1 | NG | -2 |
-1 | -1 | OK | 0 |
Par conséquent, le nombre de NG peut être compté en calculant la somme (abs (valeur estimée-valeur de réponse correcte)) / 2. En utilisant ceci, le taux de réponse correct ??? taux de HIT pourrait être calculé.
Cela fonctionnait si bien, mais si je définissais le réseau de neurones plus simplement et sans la couche intermédiaire, il semblait que cela prenait beaucoup de temps pour converger, ou c'était exagéré et quelque chose comme zéro pour cent ??? s'est produit en cours de route. Par exemple, si vous utilisez les paramètres suivants ...
newral_out = tf.layers.dense(x_ph, 1, activation=tf.nn.sigmoid)
Le résultat est ???
[0] loss 761.80 hit_per:0.50
[100] loss 732.66 hit_per:0.50
[200] loss 706.48 hit_per:0.50
[300] loss 682.59 hit_per:0.50
[400] loss 660.61 hit_per:0.50
[500] loss 640.24 hit_per:0.54
[600] loss 621.26 hit_per:0.62
[700] loss 603.52 hit_per:0.70
[800] loss 586.88 hit_per:0.76
[900] loss 571.22 hit_per:0.80
[1000] loss 556.44 hit_per:0.84
[[0.52383685]]
Il semble que ce ne soit pas assez bon. Qu'est-ce qui est bon et comment ça marche ??? Je manque encore de compréhension, mais il semble que quelque chose s'est passé et se passe bien avec une classe moyenne. De combien devrions-nous augmenter pour que cela ressemble? J'aimerais également étudier la théorie à ce sujet.