Cet article est le troisième article prévu pour les trois fois. Cet article n'est qu'une explication ligne par ligne de mnist_transfer_cnn.py. Il y a des chevauchements avec le précédent, mais veuillez noter qu'une partie du contenu peut être dupliquée pour faciliter la lecture de l'article seul. Il est destiné aux personnes intéressées par l'IA mais qui n'y ont pas encore touché. Je pense que si vous lisez ceci, vous devriez être en mesure de comprendre le flux d'apprentissage de base de l'apprentissage profond. (À l'origine, il a été créé en interne avec l'intention de l'utiliser pour la formation)
Puisque MNIST est une image, il est préférable d'avoir un GPU pour exécuter ce code (c'est un peu pénible pour un CPU). La méthode recommandée consiste à utiliser Google Colaboratory. Il n'y a que deux choses à faire. · Ouvrez un nouveau notebook Python 3 · Activer le GPU à partir du runtime Vous pouvez maintenant utiliser le GPU. Collez simplement le code dans la cellule et exécutez-le (le raccourci est CTRL + ENTRÉE) et cela fonctionnera.
Un ensemble de données d'images de texte manuscrit, souvent utilisé dans les didacticiels d'apprentissage automatique. Contenu: caractères manuscrits de 0 à 9 Taille de l'image: 28px * 28px Couleur: noir et blanc Taille des données: 70000 feuilles (60000 données d'entraînement, 10000 images et étiquettes de données de test sont disponibles)
Utilisez les paramètres d'un bon modèle existant comme valeurs initiales pour gérer une autre tâche. En faisant cela, vous pouvez vous attendre à réduire le coût de calcul et à améliorer la précision.
En parlant de cette fois
*** Puisque nous nous sommes entraînés à classer les images de 5 à 9, nous ne pouvons pas classer les images de 0 à 4 avec le modèle finalement terminé cette fois. *** ***
'''Trains a simple convnet on the MNIST dataset.
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''
'''Transfer learning toy example.
1 - Train a simple convnet on the MNIST dataset the first 5 digits [0..4].
2 - Freeze convolutional layers and fine-tune dense layers
for the classification of digits [5..9].
Get to 99.8% test accuracy after 5 epochs
for the first five digits classifier
and 99.2% for the last five digits after transfer + fine-tuning.
'''
#Aucun code spécial nécessaire (requis si Python version 3 mais le code est écrit en Python 2)
from __future__ import print_function
#Importer les bibliothèques requises
import datetime
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
#Obtenez l'heure actuelle
now = datetime.datetime.now
#constant
batch_size = 128 #Taille du lot. Taille des données à apprendre en une seule fois
num_classes = 5 #Nombre d'étiquettes à classer. Cette fois, nous classerons les images manuscrites en 5 types de 5 à 9.
epochs = 5 #Nombre d'époques. Combien de fois pour apprendre toutes les données
img_rows, img_cols = 28, 28 #Nombre de dimensions de l'image d'entrée
filters = 32 #Nombre de filtres pliables
pool_size = 2 #Taille maximale de la mise en commun
kernel_size = 3 #Filtre pliant(noyau)Taille
#Forme des données
if K.image_data_format() == 'channels_first':
input_shape = (1, img_rows, img_cols)
else:
input_shape = (img_rows, img_cols, 1)
En ce qui concerne le formulaire de données, les détails sont [Pour les débutants en IA] mnist_cnn.py sera expliqué ligne par ligne (apprendre MNIST avec Keras) Vérifier. Il est décrit dans la partie prétraitement des données.
Il détermine que le format d'image est différent selon que le backend Keras est Theano (channels_first) ou tensorflow (channels_last). Cette fois, c'est tensorflow, donc ce sera (28, 28, 1).
#Lire les données mnist et former les données(60000 caisses)Et tester les données(10000 caisses)Diviser en
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#Créer des ensembles de données séparés par l'étiquette 5 ou plus ou moins
#Image d'entraînement avec une valeur d'étiquette inférieure à 5
x_train_lt5 = x_train[y_train < 5]
#Étiquette de formation avec une valeur d'étiquette inférieure à 5
y_train_lt5 = y_train[y_train < 5]
#Image de test avec une valeur d'étiquette inférieure à 5
x_test_lt5 = x_test[y_test < 5]
#Étiquette de test avec une valeur d'étiquette inférieure à 5
y_test_lt5 = y_test[y_test < 5]
#Image d'entraînement avec une valeur d'étiquette égale ou supérieure à 5
x_train_gte5 = x_train[y_train >= 5]
#Un ensemble de données d'étiquettes d'entraînement avec une valeur d'étiquette égale ou supérieure à 5 moins 5.(5-9 ⇒ 0-4)
y_train_gte5 = y_train[y_train >= 5] - 5
#Image de test avec une valeur d'étiquette égale ou supérieure à 5
x_test_gte5 = x_test[y_test >= 5]
#Un ensemble de données d'étiquettes de test avec une valeur d'étiquette égale ou supérieure à 5 moins 5.(5-9 ⇒ 0-4)
y_test_gte5 = y_test[y_test >= 5] - 5
Tout d'abord, afin de créer un modèle qui classe les images de 0 à 4, nous le divisons en données de 0 à 4 et données de 5 à 9.
Ensuite, pour les données de 5 à 9, changez l'étiquette de 5 à 9 à 0 à 4.
#Définition du modèle(.add()Modèles qui n'utilisent pas de méthodes)
#Apprenez les fonctionnalités avec la convolution
feature_layers = [
#Couche pliante (filtre: 32 feuilles, taille du filtre:(3, 3), Recevoir la taille d'entrée:(28, 28, 1))
Conv2D(filters, kernel_size,
# padding='valid'Ne complétez pas avec 0. 0 Lors du rembourrage'same'Spécifier
padding='valid',
input_shape=input_shape),
#Fonction d'activation: Relu
Activation('relu'),
#Couche pliante (filtre: 32 feuilles, taille du filtre:(3, 3))
Conv2D(filters, kernel_size),
#Fonction d'activation: Relu
Activation('relu'),
#Couche de regroupement
MaxPooling2D(pool_size=pool_size),
# 0.25 chances de décrochage
Dropout(0.25),
#Convertir les données en une dimension
Flatten(),
]
#Apprenez la classification dans des couches entièrement connectées
classification_layers = [
#Couche entièrement connectée (128 unités)
Dense(128),
#Fonction d'activation: relu
Activation('relu'),
# 0.5 chances d'abandonner
Dropout(0.5),
#Couche entièrement connectée (5 unités)
Dense(num_classes),
#Fonction d'activation: softmax(En raison de problèmes de classification)
Activation('softmax')
]
#Fonctionnalité dans la classe séquentielle_couches et classification_Instancier ce qui a passé les couches
model = Sequential(feature_layers + classification_layers)
Cette fois, contrairement aux parties 1 et 2, le modèle est défini sans utiliser la méthode .add (). Dans Keras, vous pouvez également définir un modèle en passant une liste ordonnée de couches à Sequential () et en l'instanciant.
La raison d'écrire de cette façon est que *** Le réglage fin ne change pas (ou ne change) le poids que d'une couche spécifique pendant l'apprentissage ***. C'est pourquoi j'ose l'écrire comme ça.
*** En définissant le calque pour extraire les caractéristiques de l'image et le calque pour la classification séparément, il devient facile de mettre à jour un seul des poids ***.
#Créer une fonction pour former
def train_model(model, train, test, num_classes):
#Prétraitement des données
#Remodeler et faire correspondre le format des données
x_train = train[0].reshape((train[0].shape[0],) + input_shape) # (30596, 28, 28) -> reshape(30596, 28, 28, 1)
x_test = test[0].reshape((test[0].shape[0],) + input_shape) # (5139, 28, 28) -> reshape(5139, 28, 28, 1)
#Les données d'image prennent une valeur de 0 à 255, donc standardisez les données en les divisant par 255.
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# .astype('float32')Convertissez le type de données avec.(Sinon, vous devriez obtenir une erreur lorsque vous vous brisez)
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
#Étiqueter les données un-hot-Vectorisation
'''one-hot-L'image du vecteur ressemble à ceci
label 0 1 2 3 4
0: [1,0,0,0,0]
3: [0,0,0,1,0]'''
y_train = keras.utils.to_categorical(train[1], num_classes)
y_test = keras.utils.to_categorical(test[1], num_classes)
#Mettre en place le processus d'apprentissage
model.compile(loss='categorical_crossentropy', #Réglez la fonction de perte. Cette fois, c'est une classification, si catégorique_crossentropy
optimizer='adadelta', #L'algorithme d'optimisation est adadelta
metrics=['accuracy']) #Spécifier la fonction d'évaluation
#Obtenir l'heure de début de l'apprentissage
t = now()
#Apprendre
model.fit(x_train, y_train, #Données d'entraînement, étiquette
batch_size=batch_size, #Taille du lot (128)
epochs=epochs, #Nombre d'époques (5)
verbose=1, #Afficher la progression de l'apprentissage sous forme de graphique à barres en temps réel(Cacher à 0)
validation_data=(x_test, y_test)) #données de test(Pour tester chaque époque et calculer l'erreur)
#Sortie du temps pris pour l'apprentissage
print('Training time: %s' % (now() - t))
#Évaluation
#Passer les données de test(verbose=0 ne donne pas de message de progression)
score = model.evaluate(x_test, y_test, verbose=0)
#Erreur de généralisation de la sortie
print('Test score:', score[0])
#Performances de généralisation de sortie
print('Test accuracy:', score[1])
Cette fois, nous nous entraînerons deux fois pour créer un modèle qui classe 5 à 9 images.
#Apprenez à utiliser la fonction créée ci-dessus
#Apprenez en attribuant de 0 à 4 étiquettes aux images de moins de 5(Classer)
train_model(model,
(x_train_lt5, y_train_lt5),
(x_test_lt5, y_test_lt5), num_classes)
# trainable=Faux pour empêcher la couche d'apprendre
#Caractéristique qui est la partie à plier_Définir de ne pas mettre à jour les paramètres des couches et de classer_Mettre à jour uniquement les paramètres des couches
#Pour que les modifications prennent effet, compilez dans le modèle après les modifications de propriété()Besoin d'appeler
for l in feature_layers:
l.trainable = False
#Apprenez à utiliser la fonction créée ci-dessus
#Apprenez en attribuant 0 à 4 étiquettes à 5 images ou plus(Classer)
train_model(model,
(x_train_gte5, y_train_gte5),
(x_test_gte5, y_test_gte5), num_classes)
C'est enfin apprendre.
Ceci est la fin des trois articles de commentaire source. L'explication est terminée, mais en prime, je publierai un article sur la façon de sauvegarder et de charger le modèle et comment l'utiliser la prochaine fois. Si vous le créez et ne le sauvegardez pas, il disparaîtra même si vous l'avez fait.
Recommended Posts