Réseaux de neurones utilisant Keras sur Rescale

Modèle de blog 39

blog de marque
Rescale prend désormais en charge l'exécution d'un certain nombre de progiciels de réseaux neuronaux, notamment Keras basé sur Theano. Keras est un package Python qui permet à un utilisateur de définir un réseau neuronal couche par couche, de l'entraîner, de le valider, puis de l'utiliser pour étiqueter de nouvelles images. Dans cet article, nous formerons un réseau neuronal convolutif (CNN) classer les images en fonction de CIFAR10 base de données. Nous utiliserons ensuite ce modèle entraîné pour classer de nouvelles images.

Nous utiliserons une version modifiée du Exemple de formation Keras CIFAR10 CNN et commencerons par parcourir étape par étape notre version modifiée du script de formation.

Ensemble de données CIFAR10

L'ensemble de données de classification d'images CIFAR10 peut être téléchargé ici. Il se compose d’environ 60000 32 images de 32 × 10 pixels, chacune étant classée dans XNUMX catégories. Vous pouvez soit télécharger directement la version python de l'ensemble de données, soit utiliser le téléchargeur d'ensemble de données intégré de Keras (nous en parlerons plus tard).

Nous allons charger cet ensemble de données avec le code suivant :

from keras.datasets import cifar10 from keras.utils import np_utils nb_classes = 10 def load_dataset() : # les données, mélangées et réparties entre les ensembles d'entraînement et de test (X_train, y_train), (X_test, y_test) = cifar10.load_data() print ('X_train shape:', X_train.shape) print(X_train.shape[0], 'train samples') print(X_test.shape[0], 'test samples') # convertir les vecteurs de classe en matrices de classe binaires Y_train = np_utils .to_categorical(y_train, nb_classes) Y_test = np_utils.to_categorical(y_test, nb_classes) X_train = X_train.astype('float32') X_test = X_test.astype('float32') X_train /= 255 X_test /= 255 retour X_train, Y_train, X_test, Y_test

Nous utilisons le cifar10 chargeur de données ici, convertissant les étiquettes de catégorie en un encodage à chaud, puis mettant à l'échelle les valeurs RVB 8 bits dans une plage de 0 à 1.0.
Le X_train et X_test les sorties sont des matrices numpy de valeurs de pixels RVB pour chaque image de l'ensemble de formation et de test. Puisqu'il y a 50000 10000 images d'entraînement et 32 32 images de test et que chaque image mesure 3 × XNUMX pixels avec XNUMX canaux de couleur, la forme de chaque matrice est la suivante :

X_train(50000, 3, 32, 32)
Y_train(50000)
X_test(10000, 3, 32, 32)
Y_test(10000)

Les matrices Y correspondent à une valeur ordinale représentant l'une des 10 classes d'images pour les groupes d'images 50000 et 10000 :

avion0
automobile1
oiseau2
cat3
cerf4
chien5
grenouille6
cheval7
navire8
camion9

Par souci de simplicité, nous n'effectuons aucun prétraitement supplémentaire sur les images correctement dimensionnées dans cet exemple. Dans un vrai problème de reconnaissance d'image, nous ferions une sorte de normalisation, Blanchiment ZCA, et/ou instabilité. Keras intègre une partie de ce prétraitement avec le Générateur de données d'image classe.
Définir le réseau
L'étape suivante consiste à définir l'architecture du réseau de neurones que nous souhaitons entraîner :

depuis keras.models import Séquentiel depuis keras.layers.core import Dense, Dropout, Activation, Flatten depuis keras.layers.convolutional import Convolution2D, MaxPooling2D def make_network(): model = Sequential() model.add(Convolution2D(32, 3, 3, border_mode='même', input_shape=(img_channels, img_rows, img_cols))) model.add(Activation('relu')) model.add(Convolution2D(32, 3, 3)) model.add(Activation(' relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Convolution2D(64, 3, 3, border_mode='same')) model.add (Activation('relu')) model.add(Convolution2D(64, 3, 3)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add (Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(nb_classes )) model.add(Activation('softmax')) modèle de retour

Ce réseau comporte 4 couches convolutives suivies de 2 couches denses. Des calques supplémentaires peuvent être ajoutés et des calques peuvent être supprimés ou modifiés, mais le premier calque doit avoir la même taille qu'une image d'entrée (3, 32, 32) et le dernier calque dense doit avoir le même nombre de sorties que le nombre de classes. nous utilisons comme étiquettes (10). Après la couche dense finale est un softmax couche qui écrase la sortie dans une plage (0, 1) dont la somme est égale à 1.

Formation et tests
Ensuite, nous formons et testons le réseau :

def train_model(model, X_train, Y_train, X_test, Y_test) : sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy', optimiseur=sgd) model.fit(X_train, Y_train, nb_epoch=nb_epoch, batch_size=batch_size, validation_split=0.1, show_accuracy=True, verbose=1) print('Testing...') res = model.evaluate(X_test, Y_test, batch_size=batch_size , verbeux=1, show_accuracy=True) print('Précision du test : {0}'.format(res[1]))

Ici nous avons choisi descente de gradient stochastique comme notre méthode d'optimisation avec un perte d'entropie croisée. Ensuite, nous entraînons le modèle en utilisant le en forme() méthode. Nous spécifions le nombre d'époques de formation (le nombre de fois où nous parcourons les données) et la taille de nos lots (le nombre d'entrées à évaluer sur le réseau à la fois). Des tailles de lots plus grandes correspondent à une utilisation plus importante de la mémoire pendant l'entraînement. Une fois notre réseau formé, nous évaluons le modèle par rapport à l'ensemble de données de test et imprimons la précision.

Enregistrement du modèle
Enfin, nous enregistrons notre modèle entraîné dans des fichiers afin de pouvoir le réutiliser ultérieurement :

def save_model(model): model_json = model.to_json() open('cifar10_architecture.json', 'w').write(model_json) model.save_weights('cifar10_weights.h5', overwrite=True)

Keras fait la distinction entre la sauvegarde de l'architecture du modèle (dans notre cas, ce qui est généré par make_network()) et les poids entraînés. Les poids sont enregistrés au format HDF5.
Notez que Keras ne garantit pas que le modèle enregistré est compatible entre les différentes versions de Keras et Theano. Nous vous recommandons d'essayer de charger les modèles enregistrés avec la même version de Keras et Theano si possible.

Redimensionner le travail de formation
Maintenant que nous avons expliqué le contenu du cifar10_cnn.py script de formation que nous exécuterons, nous créerons une tâche Rescale pour nous entraîner sur un nœud GPU qui est déjà optimisé pour fonctionner sur GPU NVIDIA. Ce travail est disponible publiquement sur Rescale. Tout d’abord, nous téléchargeons le script de formation et l’ensemble de données CIFAR10 :
fichiers d'entrée de formation
Ici, nous téléchargeons la version prétraitée des images CIFAR10 téléchargées par Keras pour éviter de retélécharger l'ensemble de données depuis le site CIFAR à chaque fois que le travail est exécuté. Cette étape est facultative et nous pourrions simplement télécharger le cifar10_cnn.py scripts.
Ensuite, nous sélectionnons Keras et spécifions la ligne de commande :
logiciel-de-formation
Nous sélectionnons Keras dans le sélecteur de logiciels, puis la version GPU K520 de Keras soutenue par Theano. La ligne de commande remballe l'ensemble de données que nous avons téléchargé, puis déplace l'archive vers l'emplacement par défaut de l'ensemble de données Keras à l'adresse ~/.keras/datasets. Ensuite, il appelle le script de formation. Si nous choisissions de ne pas télécharger nous-mêmes l'ensemble CIFAR10, nous pourrions omettre toutes les commandes de manipulation des archives et simplement exécuter le script de formation. L'ensemble de données serait ensuite automatiquement téléchargé sur le cluster de tâches.
Dans la dernière étape, nous sélectionnons le matériel GPU sur lequel nous voulons fonctionner :
matériel-de-formation
Ici, nous avons sélectionné le Jade type de noyau et le minimum 4 couleurs pour ce genre. Enfin, soumettez le travail.
Il faudra environ 15 minutes pour provisionner le cluster et compiler le réseau avant le début de la formation. Une fois démarré, vous pouvez visualiser la progression en sélectionnant processus_output.log.
progression de la formation
Une fois le travail terminé, vous pouvez utiliser vos fichiers de modèle entraînés. Vous pouvez soit les télécharger à partir de la page de résultats du travail, soit les utiliser dans un nouveau travail, comme nous allons le montrer maintenant.

Classer de nouvelles images
Nous avons utilisé un ensemble de données prétraité au format numpy pour notre travail de formation, alors que faisons-nous si nous voulons prendre de vraies images sur Internet et les classer ? Depuis chien et cat sont 2 des 10 classes de images représentées dans CIFAR10, nous choisissons une image de chien et de chat parmi les Internet et essayez de les classer :
chat debout        tête de chien
Nous commençons par charger et réduire les images :

importer numpy en tant que np import scipy.misc def load_and_scale_imgs() : img_names = ['standing-cat.jpg', 'dog-face.jpg'] imgs = [np.transpose(scipy.misc.imresize(scipy.misc.imread (img_name), (32, 32)), (2, 0, 1)).astype('float32') pour img_name dans img_names] return np.array(imgs) / 255

Nous utilisons Scipy imlu pour charger les JPG puis redimensionner les images à 32×32 pixels. Le tenseur d'image résultant a des dimensions de (32, 32, 3) et nous voulons que la dimension de couleur soit la première au lieu de la dernière, nous prenons donc la transposition. Enfin, combinez la liste des tenseurs d'image en un seul tenseur et normalisez les niveaux entre 0 et 1.0 comme nous l'avons fait auparavant. Après traitement, les images sont plus petites :
chat-debout-petit    visage de chien-petit
Notez que nous avons effectué ici le redimensionnement le plus simple qui ne préserve même pas les proportions de l'image d'origine. Si nous avions effectué une normalisation sur les images d'entraînement, nous voudrions également appliquer ces transformations à ces images.

Chargement du modèle et étiquetage
L'assemblage du modèle enregistré est un processus en 2 étapes illustré ici :

depuis keras.models import model_from_json def load_model(model_def_fname, model_weight_fname): model = model_from_json(open(model_def_fname).read()) model.load_weights(model_weight_fname) modèle de retour

En l'assemblant, nous prenons le modèle que nous avons chargé et appelons prédire_classes pour obtenir les valeurs ordinales de classe pour nos 2 images.

si __name__ == '__main__' : imgs = load_and_scale_imgs() model = load_model('cifar10_architecture.json', 'cifar10_weights.h5') prédictions = model.predict_classes(imgs) print(predictions)

Redimensionner le travail d'étiquetage
Maintenant, mettons notre script d'étiquetage dans un travail et étiquetons nos exemples d'images. Ce travail est disponible publiquement sur Rescale. Nous commençons à sélectionner les modèles formés que nous avons créés. « Utiliser les fichiers du stockage cloud », puis sélectionnez les fichiers de modèle JSON et HDF5 créés par la tâche de formation :
modèle d'entrée d'étiquette
Téléchargez ensuite notre nouveau script d'étiquetage chien_cat.py et des images de chiens et de chats.
étiquette-entrée-reste
Sélectionnez le logiciel GPU Keras et exécutez le script d'étiquetage. Dans ce cas, les images de chien et de chat sont chargées à partir du répertoire actuel à partir duquel le travail est exécuté, donc aucun fichier n'a besoin d'être déplacé.
logiciel d'étiquetage
Les étiquettes seront alors affichées dans processus_output.log lorsque le travail est terminé.
sortie d'étiquette
résultats de l'étiquette
La sortie est [3, 5] qui correspond à cat et chien à partir de notre tableau de classes d’images ci-dessus.
Cela conclut ce tutoriel. Nous avons formé avec succès un réseau neuronal convolutif de reconnaissance d'images sur Rescale, puis utilisé ce réseau pour étiqueter des images supplémentaires. Bientôt dans un autre article, nous parlerons de l'utilisation de workflows Rescale plus complexes pour optimiser la formation du réseau.

Auteur

  • Mark Whitney

    Mark Whitney est directeur de l'ingénierie chez Rescale. Ses domaines d'expertise comprennent les architectures de calcul haute performance, la recherche sur l'information quantique et le cloud computing. Il est titulaire d'un doctorat en informatique de l'Université de Californie à Berkeley.