[PYTHON] [Windows Edition] Keras Course, une bibliothèque où vous pouvez essayer le Deep Learning immédiatement - Partie 2

introduction

La dernière fois, nous avons présenté la bibliothèque Deep Learning Keras à Windows et effectué une classification binaire indiquant si le carré est portrait ou paysage. Si vous ne l'avez pas encore lu, il sera peut-être plus facile de le comprendre à partir de là. En passant, cette fois, je pense que la classification binaire n'est pas intéressante jusqu'à ce que vous utilisiez l'apprentissage en profondeur, donc comme prochaine étape, je vais effectuer une classification multi-classe des nombres en utilisant un ensemble de données de caractères manuscrits de 0 à 9 appelé MNIST. .. Dans cet article également, le réseau continuera à utiliser Multilayer Perceptron (MLP). Je n'ai pas parlé de perceptrons multicouches, alors parlons brièvement d'abord. La valeur initiale et l'explication des paramètres d'optimisation seront abordées séparément dans environ 5.

Environnement d'exécution

Qu'est-ce que le Perceptron multicouche?

perceptron

Qu'est-ce que Perceptron exactement? D'après le premier livre de la bibliographie

Perceptron est un algorithme mis au point en 1957 par un chercheur américain nommé Rosen Blood, qui est à l'origine du réseau neuronal (deep learning).

Il semble que (l'expression a un peu changé). Je ne pense pas pouvoir dire exactement ce que c'est, alors je vais expliquer ce qu'est le Perceptron lui-même. Pour expliquer avec des mots, c'est "un appareil qui reçoit plusieurs signaux comme entrées et qui sort un signal", et le signal de sortie prend deux valeurs, 0 ou 1. perceptron3.png Le neurone calcule la somme des signaux envoyés et ne délivre 1 que lorsque la somme dépasse une certaine valeur limite. On dit que cela est parfois exprimé par "** le feu des neurones **". La valeur limite est appelée valeur seuil, et lorsqu'elle est exprimée par $ \ theta $, la sortie $ y $ peut être exprimée par la formule suivante.

\begin{eqnarray}
y=\left\{ \begin{array}{ll}
0 & (\omega_1 x_1 + \omega_2 x_2 \leq \theta) \\
1 & (\omega_1 x_1 + \omega_2 x_2 > \theta) \\
\end{array} \right.
\end{eqnarray}

En d'autres termes, le ** poids $ \ omega $ de Perceptron représente l'importance du signal **, et ** biais $ b $ est un ** paramètre qui ajuste la facilité de déclenchement. Le biais $ b $ est $ b = - \ theta $. Dans certains contextes, ce biais est également appelé poids. Cependant, comme vous pouvez le voir à partir de l'équation ci-dessus, un seul perceptron peut être identifié par une ligne droite. Par conséquent, il n'est pas possible de traiter des événements non linéaires.

Perceptron multicouche

Les perceptrons simples ne peuvent être utilisés que dans des problèmes linéaires. Cependant, Perceptron peut également être superposé, ce qui lui permet de gérer également des problèmes non linéaires. C'est ce qu'on appelle un perceptron multicouche. Il y a quelques choses à savoir ici. Ce que l'on appelle communément un perceptron multicouche est différent du perceptron simple décrit précédemment. La valeur de sortie du perceptron multicouche est 0 ou 1 pour le perceptron, tandis que la valeur de sortie est un nombre réel de 0 à 1 lorsque la fonction d'activation est sigmoïde. Eh bien, tout à coup, je suis venu avec la fonction d'activation de mot. La fonction d'activation est que le perceptron simple détermine si la sortie est 0 ou 1 par la valeur de seuil, alors que dans le perceptron multicouche, elle est sortie en passant la fonction d'activation non linéaire $ h $ avec la somme des entrées comme variable. Détermine le nombre réel de.

\begin{eqnarray}
  a =& \omega_1 x_1 + \omega_2 x_2 + b\\
  y =& h(a)
\end{eqnarray}

Par exemple, la fonction sigmoïde est la fonction suivante, qui génère une valeur réelle entre 0 et 1 en fonction de la valeur de la variable d'entrée. sigmoïde

\begin{equation}
h(x) = \frac{1}{1+\exp(-x)}
\end{equation}

sigmoid2.png

Enfin, le Perceptron multicouche peut être résumé comme suit.

Identification des caractères manuscrits

Pourriez-vous en quelque sorte comprendre le Perceptron multicouche? À ce stade, nous identifions enfin les caractères manuscrits à l'aide d'un perceptron multicouche.

Apprentissage

MNIST peut lire les données d'entraînement et de test sous la forme d'un ensemble de données dans Keras. Vous n'avez donc pas à télécharger l'ensemble de données comme vous l'avez fait la dernière fois. Vous pouvez afficher la formation et ses résultats avec un script comme celui-ci: J'ai utilisé la fonction sigmoïde pour la fonction d'activation du perceptron multicouche la dernière fois, mais cette fois j'utilise la fonction ReLU. La raison de l'utilisation de la fonction ReLU est qu'elle est plus précise, mais j'expliquerai la raison en détail dans un autre article. Veillez également à définir la fonction d'activation de la couche finale sur Softmax lorsque vous souhaitez classer. Sinon, il ne sera pas classé. Le bloc-notes Jupyter a été téléchargé sur Gist.

mnist_detect_class10.py


import numpy as np
import matplotlib.pyplot as plt

from keras.utils import np_utils
from scipy.misc import toimage

#Requis pour lire l'ensemble de données MNIST
from keras.datasets import mnist

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation

#Définition du nombre de classes à classer
class_num = 10

#Charger le jeu de données mnist
(X_train, y_train),(X_test, y_test) = mnist.load_data()

#Normaliser les données d'entraînement
X_train = X_train/255
X_test = X_test/255

#Formater les données pour l'entrée
#Convertissez un tableau bidimensionnel de 28 pixels x 28 pixels par image en un vecteur de 784 dimensions
X_train = X_train.reshape(-1,784)
X_test = X_test.reshape(-1,784)

#Changer l'étiquette en un tableau correspondant au nombre de classes
#Exemple: y_train:[0 1 7 5] -> Y_train:[[1 0 0 0 0 0 0 0 0 0],[0 1 0 0 0 0 0 0 0 0],[0 0 0 0 0 0 0 1 0 0],[0 0 0 0 0 1 0 0 0 0]]
Y_train = np_utils.to_categorical(y_train,class_num)
Y_test = np_utils.to_categorical(y_test,class_num)

#Création d'un réseau Perceptron multicouche
#Dimensions d'entrée 784(28x28)Et définissez la sortie finale sur le nombre de classes
model = Sequential()
model.add(Dense(512, input_dim=784, init='uniform'))
#Utilisez la fonction ReLU pour la fonction d'activation
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(512, init='uniform'))
#Utilisez la fonction ReLU pour la fonction d'activation
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(class_num, input_dim=512, init='uniform'))
#Dans le cas de la classification, utilisez toujours Softmax pour la couche finale
model.add(Activation('softmax'))

#Sélectionnez catégoriel car il s'agit d'une classification à valeurs multiples, sélectionnez RMSprop comme algorithme d'optimisation
model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

#Former le modèle avec un nombre fixe d'essais (itérations de jeux de données)
model.fit(X_train, Y_train,
          nb_epoch=5,
          batch_size=100)
#Évaluer les paramètres post-apprentissage
score = model.evaluate(X_test, Y_test, batch_size=100)
print(score)
#Estimer l'étiquette des données de test, la valeur de retour sera l'étiquette
classified_label = model.predict_classes(X_test[0:10,:])

#Affichage de l'étiquette et de l'image estimées
for i in range(10):
    #Convertir les données vectorielles en tableau et les convertir en données d'image
    img = toimage(X_test[i,:].reshape(28,28))
    plt.subplot(2,5,i+1)
    plt.imshow(img, cmap='gray')
    plt.title("Class {0}".format(classified_label[i]))
    plt.axis('off')
plt.show()

#Enregistrer le modèle et le poids
model_json = model.to_json()
open('mnist_architecture.json', 'w').write(model_json)
model.save_weights('mnist_weights.h5', overwrite=True)

résultat

Les 10 étiquettes et images estimées depuis le début des données de test sont les suivantes. Vous pouvez voir que la classe et le personnage correspondent. À propos, le résultat du test de cette image était un niveau suffisamment pratique avec un taux de réponse correcte de 97,7%. En regardant l'image de test, il semble que 5 soit confondu avec 8, mais il peut être classé correctement. À propos, avec Sigmaid, le taux de réponse correct n'était que d'environ 80%, il est donc important de définir les paramètres appropriés. mnist_result.png

Expérimentez avec les nombres que vous avez écrits

À ce stade, l'apprentissage semble être assez précis. Cependant, je veux toujours tester avec les personnages que j'ai écrits. Par conséquent, j'ai créé une image avec des nombres de 0 à 9 écrits sur une toile de 56 pixels x 56 pixels avec de la peinture. J'ai essayé de prédire la classe en lisant les poids entraînés avec le code suivant. Le bloc-notes Jupyter a été téléchargé sur Gist.

my_mnist.py


import numpy as np
import matplotlib.pyplot as plt

from keras.utils import np_utils

from keras.models import Sequential,model_from_json
from keras.preprocessing import image
from keras.applications.imagenet_utils import preprocess_input, decode_predictions

#Nombre d'images préparées pour le test
test_num = 10

#Modèle de charge
model = model_from_json(open('mnist_architecture.json').read())
#Poids du modèle de charge
model.load_weights('mnist_weights.h5')

for i in range(test_num):
    #Spécifiez le nom du fichier
    img_path = str(i)+".jpg "
    #28 pixels x 28 pixels, charge l'image en échelle de gris
    img = image.load_img(img_path, grayscale=True, target_size=(28, 28))
    #Convertir l'image chargée en tableau
    x = image.img_to_array(img)
    #Vérification de la taille de la baie
    print(x.shape)
    
    #Formez un tableau bidimensionnel 28x28 en un vecteur de taille 784 pour l'entrée dans le modèle
    x = x[:,:,0].reshape(-1,784)

    #Prédiction de classe
    classified_label = model.predict_classes(x)
    
    #Graphique des résultats de prédiction
    plt.subplot(2,5,i+1)
    plt.imshow(img, cmap='gray')
    plt.title("Class {0}".format(classified_label[0]))
    plt.axis('off')
plt.show()

Résultat de la prédiction de mes caractères manuscrits

Je pensais que tous les résultats de prédiction étaient corrects, mais le nombre que j'ai écrit montrait que le taux de réponse correcte était de 70%. C'est probablement parce qu'il est différent de l'écriture manuscrite de l'ensemble de données. Ce n'est pas très soigné, donc je publierai ce que j'ai appris dans CNN ici dans un post-scriptum plus tard. mnist_result2.png

Environnement d'exécution et code source pendant l'apprentissage CNN

Environnement d'exécution

Cela prend trop de temps pour un PC normal avec seulement un CPU pour former CNN, donc je l'ai formé sur le cloud avec un environnement GPU. L'environnement d'exécution à ce moment-là était comme ça. L'apprentissage de MNIST dans cet environnement a pris moins d'une minute.

Code source au moment de l'apprentissage

my_mnist_cnn_learning.py


import numpy as np

from keras.utils import np_utils

from keras.datasets import mnist

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras import backend as K

#Nombre de lots
batch_size = 128
#Nombre de classes à classer
nb_classes = 10
#Nombre d'époques
nb_epoch = 12

#Nombre de dimensions de l'image à saisir
img_rows, img_cols = 28, 28
#Nombre de filtres utilisés pour la convolution
nb_filters = 32
#Spécifiez la taille de la couche de regroupement
pool_size = (2, 2)
#Spécifie la taille du noyau de convolution
kernel_size = (3, 3)

#Lire les données mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()

if K.image_dim_ordering() == 'th':
        X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
        X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
        input_shape = (1, img_rows, img_cols)
else:
        X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
        X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
        input_shape = (img_rows, img_cols, 1)

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')

#Normalisation
X_train /= 255
X_test /= 255

#Convertir en matrice binaire
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

#Modélisation CNN
model = Sequential()

model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1],
                                                border_mode='valid',
                                                input_shape=input_shape))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))

#Compiler le modèle
model.compile(loss='categorical_crossentropy',
                            optimizer='adadelta',
                            metrics=['accuracy'])

#Apprentissage
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch,
                    verbose=1, validation_data=(X_test, Y_test))
#Évaluation du modèle
score = model.evaluate(X_test, Y_test, verbose=0)
print(score)

#Enregistrer le modèle et le poids
model_json = model.to_json()
open('mnist_cnn_architecture.json', 'w').write(model_json)
model.save_weights('mnist_cnn_weights.h5', overwrite=True)

Résultats d'apprentissage dans CNN

Je l'exécutais dans le cloud plus tôt, mais le script suivant est dans le premier environnement Windows Fonctionnement

my_mnist_cnn.py


# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt

from keras.utils import np_utils

from keras.models import Sequential,model_from_json
from keras.preprocessing import image
from keras.applications.imagenet_utils import preprocess_input, decode_predictions

from keras.datasets import mnist

#Nombre de classes classées
nb_classes = 10
#Nombre d'images préparées pour le test
test_num = 10
#Lire les données mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()

X_test = X_test.astype('float32')
#Normaliser les données
X_test /= 255

#Convertir en un tableau binaire
Y_test = np_utils.to_categorical(y_test, nb_classes)

#Modèle de charge
model = model_from_json(open('mnist_cnn_architecture.json').read())
#Poids du modèle de charge
model.load_weights('mnist_cnn_weights.h5')
#Après avoir chargé l'architecture et les poids, vous devez compiler si vous souhaitez évaluer le modèle
model.compile(loss='categorical_crossentropy',
              optimizer='adadelta',
              metrics=['accuracy'])
#Évaluation du modèle
score = model.evaluate(X_test.reshape(-1,28,28,1), Y_test, verbose=0)
print(score)

for i in range(test_num):
    #Spécifiez le nom du fichier
    img_path = str(i)+".jpg "
    #28 pixels x 28 pixels, charge l'image en échelle de gris
    img = image.load_img(img_path, grayscale=True, target_size=(28, 28))
    #Convertir l'image chargée en tableau
    x = image.img_to_array(img)
    #Vérification de la taille de la baie
    print(x.shape)

    #Prédiction de classe
    classified_label = model.predict_classes(x.reshape(-1,28,28,1))

    #Graphique des résultats de prédiction
    plt.subplot(2,5,i+1)
    plt.imshow(img, cmap='gray')
    plt.title("Class {0}".format(classified_label[0]))
    plt.axis('off')
plt.show()

Maintenant, qu'arrive-t-il au résultat avec un réseau neuronal convolutif? Le résultat de l'exécution dans Jupyter Notebook est téléchargé sur Gist.

mnist_result_cnn.png

Le taux de réponse correcte est de 80%, mais comparé aux résultats de ce que j'ai appris en MLP, dans le cas des nombres que j'ai écrits, 6 et 8,7 et 1 ont des caractéristiques similaires, il peut donc être facile de se tromper. De plus, si j'ajoute ce que j'ai écrit en plus des données d'entraînement existantes, la réponse peut être correcte, mais je n'ai pas l'intention de le faire.

en conclusion

Cette fois, nous avons classé les caractères manuscrits MNIST. Bien que les résultats de l'apprentissage et des tests aient été bons, le taux de réponse correct pour les images que j'ai écrites n'était pas bon. La prochaine fois, je parlerai du réseau de neurones convolutifs (CNN).

Les références

Recommended Posts

[Windows Edition] Keras Course, une bibliothèque où vous pouvez essayer le Deep Learning immédiatement - Partie 2
Créez un environnement sur Windows10 où vous pouvez essayer MXNet
Une scène où le GPU est utile pour le deep learning?
Essayez de créer un réseau de neurones / d'apprentissage en profondeur avec scratch
Prédiction des ondes sinusoïdales à l'aide de RNN dans la bibliothèque d'apprentissage en profondeur Keras
Résumé du site où vous pouvez apprendre gratuitement le machine learning
[Utilisation gratuite] 7 sites d'apprentissage où vous pouvez étudier Python
Je n'ai pas de GPU, mais je vais essayer le Deep Learning
Essayez l'apprentissage en profondeur avec TensorFlow
Essayez le Deep Learning avec FPGA
Avec l'apprentissage en profondeur, vous pouvez dépasser le taux de récupération de 100% dans les courses de chevaux
J'ai fait un tampon LINE où vous pouvez étudier les commandes Linux
Quoi qu'il en soit, nous avons mis en place un site où vous pouvez apprendre Python gratuit et l'apprentissage automatique de base.