Dans "Deep Learning from scratch", la position d'implémentation du contenu de Tensorflow avec Numpy est prise. Dans cet article, nous ferons de même et examinerons le problème de la mise en œuvre d'un problème de classification simple avec Numpy.
Suppose we want to classify some data (4 samples) into 3 distinct classes: 0, 1, and 2. We have set up a network with a pre-activation output z in the last layer. Applying softmax will give the final model output. input X ---> some network --> z --> y_model = softmax(z)
We quantify the agreement between truth (y) and model using categorical cross-entropy. J = - sum_i (y_i * log(y_model(x_i))
In the following you are to implement softmax and categorical cross-entropy and evaluate them values given the values for z.
Nous utiliserons y_cl = np.array ([0, 0, 2, 1])
comme valeur d'entrée, et ne considérerons pas la couche cachée en détail cette fois. Autrement dit, supposons que le tableauy_cl
devienne un autre tableauz
lorsque cette valeur d'entrée sort de la couche cachée après un certain calcul. Lorsque vous regardez la valeur de sortie via la fonction softmax en utilisant z
, cela donne-t-il le même tableau que y_cl
? Veuillez également discuter de son exactitude.
Tensorflow a déjà été implémenté comme suit, veuillez donc implémenter un programme qui se comporte de la même manière avec uniquement Numpy. (Je pense que la section 3.5 du livre de référence sera utile.) Il y a des problèmes de 1) à 5).
from __future__ import print_function
import numpy as np
import tensorflow as tf
# Data: 4 samples with the following class labels (input features X irrelevant here)
y_cl = np.array([0, 0, 2, 1])
# output of the last network layer before applying softmax
z = np.array([
[ 4, 5, 1],
[ -1, -2, -3],
[0.1, 0.2, 0.3],
[ -1, 100, 1]
])
# TensorFlow implementation as reference. Make sure you get the same results!
print('\nTensorFlow ------------------------------ ')
with tf.Session() as sess:
z_ = tf.constant(z, dtype='float64')
y_ = tf.placeholder(dtype='float64', shape=(None,3))
y = np.array([[1., 0., 0.], [1., 0., 0.], [0., 0., 1.], [0., 1., 0.]])
print('one-hot encoding of data labels')
print(y)
y_model = tf.nn.softmax(z)
crossentropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_model), reduction_indices=[1]))
print('softmax(z)')
print(sess.run(y_model))
print('cross entropy = %f' % sess.run(crossentropy, feed_dict={y_: y}))
print('\nMy solution ------------------------------ ')
# 1) Write a function that turns any class labels y_cl into one-hot encodings y. (2 points)
# 0 --> (1, 0, 0)
# 1 --> (0, 1, 0)
# 2 --> (0, 0, 1)
# Make sure that np.shape(y) = (4, 3) for np.shape(y_cl) = (4).
def to_onehot(y_cl, num_classes):
y = np.zeros((len(y_cl), num_classes))
return y
# 2) Write a function that returns the softmax of the input z along the last axis. (2 points)
def softmax(z):
return None
# 3) Compute the categorical cross-entropy between data and model (2 points)
# 4) Which classes are predicted by the model (maximum entry). (1 point)
# 5) How many samples are correctly classified (accuracy)? (1 point)
from __future__ import print_function
import numpy as np
import tensorflow as tf
# Data: 4 samples with the following class labels (input features X irrelevant here)
y_cl = np.array([0, 0, 2, 1])
# output of the last network layer before applying softmax
z = np.array([
[ 4, 5, 1],
[ -1, -2, -3],
[0.1, 0.2, 0.3],
[ -1, 100, 1]
])
#Partie Tensorflow omise
print('\n☆My solution ------------------------------ ')
# 1) Write a function that turns any class labels y_cl into one-hot encodings y. (2 points)
# 0 --> (1, 0, 0)
# 1 --> (0, 1, 0)
# 2 --> (0, 0, 1)
# Make sure that np.shape(y) = (4, 3) for np.shape(y_cl) = (4).
def to_onehot(num_classes, y_cl):
y_one = np.eye(num_classes)[y_cl]
return y_one
print('one-hot encoding of data labels by Numpy')
y_one = (to_onehot(3,y_cl)).astype(np.float32)
print(y_one)
#2) Write a function that returns the softmax of the input z along the last axis. (2 points)
def softmax(z):
e = np.exp(z)
dist = e / np.sum(e, axis=1, keepdims=True)
return dist
print('softmax(z) by Numpy')
y_my = softmax(z)
print(y_my)
# 3) Compute the categorical cross-entropy between data and model (2 points)
crossentropy_my = np.mean(-np.sum(y_one*np.log(y_my),axis=1))
print('cross entropy by Numpy: %f' % crossentropy_my)
# 4) Which classes are predicted by the model (maximum entry). (1 point)
print('The predicted class by Numpy:')
y_pre_cl= np.argmax(y_my,axis=1)
print(y_pre_cl)
# 5) How many samples are correctly classified (accuracy)? (1 point)
accuracy_my = np.mean(y_pre_cl == y_cl)
print('accuracy by Numpy: %f' % accuracy_my)
production
■Input data with 4 samples:[0 0 2 1]
☆TensorFlow ------------------------------
one-hot encoding of data labels
[[ 1. 0. 0.]
[ 1. 0. 0.]
[ 0. 0. 1.]
[ 0. 1. 0.]]
softmax(z)
[[ 2.65387929e-01 7.21399184e-01 1.32128870e-02]
[ 6.65240956e-01 2.44728471e-01 9.00305732e-02]
[ 3.00609605e-01 3.32224994e-01 3.67165401e-01]
[ 1.36853947e-44 1.00000000e+00 1.01122149e-43]]
cross entropy: 0.684028
The predicted class:
[1 0 2 1]
accuracy: 0.750000
☆My solution ------------------------------
one-hot encoding of data labels by Numpy
[[ 1. 0. 0.]
[ 1. 0. 0.]
[ 0. 0. 1.]
[ 0. 1. 0.]]
softmax(z) by Numpy
[[ 2.65387929e-01 7.21399184e-01 1.32128870e-02]
[ 6.65240956e-01 2.44728471e-01 9.00305732e-02]
[ 3.00609605e-01 3.32224994e-01 3.67165401e-01]
[ 1.36853947e-44 1.00000000e+00 1.01122149e-43]]
cross entropy by Numpy: 0.684028
The predicted class by Numpy:
[1 0 2 1]
accuracy by Numpy: 0.750000
Les réponses et les questions peuvent être téléchargées depuis ici.
- Write a function that turns any class labels y_cl into one-hot encodings y. (2 points) 0 --> (1, 0, 0) 1 --> (0, 1, 0) 2 --> (0, 0, 1) Make sure that np.shape(y) = (4, 3) for np.shape(y_cl) = (4).
def to_onehot(num_classes, y_cl):
y_one = np.eye(num_classes)[y_cl]
return y_one
En lisant le tableau Numpyy_cl
, vous pouvez obtenir un tableau avec "1" à la position de l'élément de y_cl
. «num_class» doit être la valeur maximale de «y_cl» - la valeur minimale + 1. (Cette fois, il est de 0,1,2, donc il y en a trois.) C'est un vecteur one-hot.
- Write a function that returns the softmax of the input z along the last axis. (2 points)
def softmax(z):
e = np.exp(z)
dist = e / np.sum(e, axis=1, keepdims=True)
return dist
Implémentez la fonction softmax telle que définie. Surtout pour les grandes entrées, la soustraction utilisant la valeur maximale ne change pas (P.69), elle peut donc être utilisée. Notez également que si l'option «keepdims» n'est pas «True», «[1]» sera «1». (Le premier est un tableau à 1 dimension, le second est un tableau à 0 dimension (juste un nombre))
- Compute the categorical cross-entropy between data and model (2 points)
crossentropy_my = np.mean(-np.sum(y_one*np.log(y_my),axis=1))
print('cross entropy by Numpy: %f' % crossentropy_my)
Définition de l'entropie croisée catégorique
Il doit être mis en œuvre selon. Où $ t_k $ est un vecteur one-hot et $ y_k $ est une sortie.
De plus, «tf.reduce_mean» et «np.mean» sont les mêmes, et pour l'axe dans Numpy, reportez-vous à ici. Cette fois, nous examinerons le problème de classification, donc si vous utilisez un tableau dans un tableau (par exemple, [[A, B, C], [D, E, F]]
, alors [A, B, C]
et [D, Array) correspondant à E, F]
doit être considéré séparément. Dans ce cas, si ʻaxis = 1` est spécifié, l'opération dans cette plage devient possible.
Si vous organisez les choses jusqu'à ce point
--Changement de y_cl
(valeur d'entrée) en vecteur one-hot. -> y_one
--Le tableauz
qui est sorti à travers les couches a été passé à travers la fonction softmax-> y_my
Ceux-ci sont séparés et correspondent respectivement à $ t_k $ et $ y_k $.
- Which classes are predicted by the model (maximum entry). (1 point)
print('The predicted class by Numpy:')
y_pre_cl = np.argmax(y_my,axis=1)
print(y_pre_cl)
Voir page 70 pour plus de détails. Dans le tableau (par exemple «[A, B, C]», «[D, E, F]») traité ci-dessus, le degré de précision de la classification dans la classe est inclus en tant qu'élément. Pour récupérer cela, prenez l'indice avec la plus grande valeur. Ceci est possible avec np.argmax
. De même, spécifiez ʻaxis = 1`.
Pour les problèmes de classification, utilisez softmax pour l'activation finale. En effet, en regardant les indices dans la liste des valeurs de sortie, vous pouvez voir dans quelle catégorie les données peuvent être classées (son ratio ou sa probabilité). Par exemple, si vous considérez trois problèmes de catégorie appropriés
[0.10, 0.05, 0.85]
Supposons que vous obteniez une liste de (Cela correspond à l'un des tableaux correctement extraits de softmax (z) en question maintenant.) Où np.argmax ([0.10, 0.05, 0.85]) = [2]
Comme vous pouvez le voir, "l'étiquette pointée par ce tableau semble avoir une probabilité d'appartenir à la catégorie 2 d'environ 0,85x100 = 85%."
Si vous prenez le plus grand indice comme celui-ci, vous pouvez voir la catégorie. Pour le dire autrement, si vous attribuez un nombre arbitraire à l'étiquette de réponse correcte et la rendez spéciale, vous pouvez trouver cette étiquette et l'ordinateur saura qu'il s'agit d'une catégorie. Si vous pensez que, si vous déposez 1 sur l'étiquette de réponse correcte et 0 autre que cela, vous pouvez dire si c'est la bonne réponse en regardant l'indice où 1 est. C'est ce qu'on appelle un vecteur one-hot.
Ensuite, envisagez de convertir la valeur d'entrée y_cl
en un vecteur one-hot. Puisqu'il suffit de définir un tableau tel que 1 soit à la position de chaque élément 0,0,2,1 de y_cl
, le vecteur one-hot à ce moment est
[ [1, 0, 0], # 0
[1, 0, 0], # 0
[0, 0, 1], # 2
[0, 1, 0] ] # 1
Ce sera. (Ignorez les petites notifications.)
- How many samples are correctly classified (accuracy)? (1 point)
accuracy_my = np.mean(y_pre_cl == y_cl)
print('accuracy by Numpy: %f' % accuracy_my)
Comme brièvement résumé ci-dessus, la sortie softmax montre avec quelle précision l'étiquette est classée dans sa position (classe). Pour savoir dans quelle mesure le tableau finaly_pre_cl
correspond à la valeur d'entrée y_cl
, faites la moyenne du nombre de valeurs True
.
Le problème de classification est également une tâche importante dans l'apprentissage automatique, mais je pense qu'il est difficile à comprendre. (Pourquoi utiliser un vecteur unique?) Je serais très heureux si cet article pouvait répondre ne serait-ce qu'à l'une de ces questions.
Recommended Posts