――Ceci est le résultat de mon propre dossier d'étude sur l'apprentissage automatique et l'apprentissage profond.
Le meme que la derniere fois. Pour plus de détails ** ici **.
--Acquis ** JDLA Deep Learning pour Engeneer 2019 # 2 ** en septembre 2019. ――Jusqu'à la fin mars 2020, vous occuperez le bureau d'une société d'intérêt public. À partir d'avril 2020, il a changé de carrière en ingénieur de données.
――Nous avons collecté un total de 120 fichiers image (jpg), 60 photos de chiens de compagnie (chiens Shiba) et 60 photos de chiens Shiba (autres que des chiens de compagnie), et les avons classés en 2 catégories par apprentissage profond. ―― À la suite de l'apprentissage du modèle et de sa vérification avec des données de test, la précision n'était que d'environ 75 à 76%.
** Étape 1 Augmentez la quantité de données d'analyse (doublez le nombre de photos) et téléchargez-les sur Google Drive ** ** Étape 2 Créez un dossier de travail sur Google Drive, décompressez et copiez les données ** ** Étape 3 Construction du modèle / apprentissage / résultats ** ** Étape 4 Transfert de l'apprentissage avec le modèle ImageNet (VGG16) ** ** Étape 5 Réglage fin avec le modèle ImageNet (VGG16) **
Dans l'analyse précédente, je pense qu'il y a plusieurs raisons pour lesquelles l'exactitude de la classification est restée dans la fourchette de 70%, mais je pense que la plus importante est que les données de formation étaient aussi petites que 60 données. Il est assez difficile d'augmenter les données, mais pour ce classement, nous avons augmenté le nombre de photos à 120 pour les chiens de compagnie et 120 pour les shiba autres que les chiens de compagnie, pour un total de 240 photos. Reclassez en fonction de ce fichier de données.
--Fichier jpg Pet Dog (120 feuilles) Exemple de photo nouvellement ajouté ⇒ Résumer dans mydog2.zip
-Fichier jpg de chiens Shiba autres que votre chien (120 feuilles) Exemple de photo nouvellement ajouté → Résumer dans otherdogs2.zip
--Lorsque vous avez effectué l'analyse précédente, vous avez créé les dossiers suivants pour stocker les données. (La figure est un exemple de ma structure de dossiers)
--Téléchargez les deux fichiers zip "mydog2.zip" et "otherdogs2.zip" dans Google Drive (dossier "original_data").
** Note) À propos du décalage temporel concernant la coopération entre Colaboratory et Google Drive ** Cela ressemble plus à la rédaction d'un mémo qu'à une mise en garde, mais pour la coopération entre Colaboratory et Google Drive Je pense qu'il y a un décalage dans le temps. Afin d'effectuer le traitement en toute sécurité, il semble préférable de procéder étape par étape tout en confirmant que chaque traitement est terminé, au lieu d'effectuer chaque traitement tel que la création d'un dossier de travail et la copie en une seule fois. Je pense. Dans mon essai, après avoir émis une commande de Colaboratory vers Google Drive, il faut un certain temps pour qu'elle se reflète réellement. Par conséquent, bien que cela puisse dépendre de la synchronisation, si le processus suivant est exécuté avant la réflexion, une erreur peut se produire. Si cela ne fonctionne pas d'un seul coup, il est judicieux de diviser le processus en plusieurs étapes. </ font>
――Les résultats de la formation sont présentés dans le graphique ci-dessous. Il y a des signes de surapprentissage à la fois en précision et en perte, et il n'y a pas d'amélioration notable.
Les résultats de vérification appliqués aux données de test sont les suivants. L'augmentation du nombre d'échantillons de données a conduit à une précision améliorée et la précision a atteint environ 80%. test loss: 1.7524430536416669 test acc: 0.8166666567325592
Ensuite, je me suis entraîné avec l'augmentation des données. Les résultats de la formation sont présentés dans le graphique ci-dessous.
Ensuite, les résultats de vérification des données de test lorsque le paramètre Image Generator est défini pour remplir les données d'image sont les suivants (les conditions de remplissage sont les mêmes que les paramètres de l'essai précédent, seul l'affichage des résultats). Celui-ci a une plus grande précision. test loss: 1.382319548305386 test acc: 0.8666666634877522
Cette fois, nous effectuerons l'apprentissage par transfert. Importez le modèle entraîné (VGG16) d'ImageNet, qui est un modèle typique, à partir de la bibliothèque keras et utilisez-le. À partir du modèle VGG16, seule la base de convolution entraînée est utilisée pour extraire une carte de caractéristiques locales polyvalente. En connectant le classificateur "(pour Shiba chien) mon enfant-autre enfant" à la sortie, la précision de la classification sera améliorée.
--VGG16 est un réseau neuronal multicouche composé de 13 couches convolutives et de 3 couches entièrement connectées, pour un total de 16 couches. Le modèle publié est formé à l'aide d'un grand ensemble d'images appelé ImageNet. --Il est implémenté dans le module keras.applications.vgg16 en tant que bibliothèque Keras.
――Ce qui suit sera basé sur l'hypothèse qu'un dossier de stockage de données et un dossier de travail ont été créés dans Google Drive et que les données d'image à analyser ont été stockées. (Implémenté dans le même environnement d'analyse qu'avant) --Chargez le modèle VGG16 dans la variable conv_base.
#Chargement de VGG16
from keras.applications import VGG16
conv_base = VGG16(weights='imagenet', #Spécifiez le type de poids(Ici, spécifiez le poids appris par Imagenet)
include_top=False, #S'il faut inclure le classificateur entièrement couplé du côté sortie du NW(Puisque nous utiliserons ici notre propre classificateur entièrement connecté, nous ne l'inclurons pas.)
input_shape=(320, 320, 3)) #Le standard ImageNet est la forme du tenseur d'image fourni au NW.(224, 224 3) (Cette fois 320pxl*Spécifier une image RVB 320pxl)
conv_base.summary()
La structure de modèle suivante s'affiche pour la partie correspondante du VGG16 chargé.
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) (None, 320, 320, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 320, 320, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 320, 320, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 160, 160, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 160, 160, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 160, 160, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 80, 80, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 80, 80, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 80, 80, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 80, 80, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 40, 40, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 40, 40, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 40, 40, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 40, 40, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 20, 20, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 20, 20, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 20, 20, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 20, 20, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 10, 10, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
Créez un modèle en joignant la couche entièrement connectée pour cette classification binaire à conv_base.
from keras import models
from keras import layers
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
La structure de modèle suivante s'affiche.
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
vgg16 (Model) (None, 10, 10, 512) 14714688
_________________________________________________________________
flatten_1 (Flatten) (None, 51200) 0
_________________________________________________________________
dense_1 (Dense) (None, 256) 13107456
_________________________________________________________________
dense_2 (Dense) (None, 1) 257
=================================================================
Total params: 27,822,401
Trainable params: 27,822,401
Non-trainable params: 0
_________________________________________________________________
# conv_Nombre de poids pouvant être formés avant de congeler la base
print('conv_Nombre de poids pouvant être formés avant de congeler la base:' ,len(model.trainable_weights))
Une fois exécuté, le résultat "30" est affiché.
# conv_Définir uniquement le poids de base pour qu'il ne puisse pas être entraîné
conv_base.trainable = False
#Vérification du nombre de poids entraînables
print('conv_base Nombre de poids pouvant être entraînés à l'état gelé:' ,len(model.trainable_weights))
Une fois exécuté, le nombre de poids entraînables sera changé en "4" et affiché. Entraînez le modèle dans cet état de configuration.
Utilisez le code ci-dessous.
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
#Paramètres du générateur de données de train Gonflé: Oui
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
#Paramètres du générateur pour les données de validation et les données de test Gonflé: Aucun\(Le générateur de données de validation et de données de test est courant)
test_datagen = ImageDataGenerator(rescale=1./255)
#Tensolisation des données du train
train_generator = train_datagen.flow_from_directory(
# target directory
train_dir,
# size 320x320
target_size=(320, 320),
batch_size=20,
#Binaire comme fonction de perte_Nécessite une étiquette binaire pour utiliser la copie croisée
class_mode='binary')
#Tensolisation des données de validation
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(320, 320),
batch_size=32,
class_mode='binary')
#Compiler le modèle
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
#Apprentissage
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=30,
validation_data=validation_generator,
validation_steps=50,
verbose=2)
Enregistrez le modèle après l'exécution.
model.save('mydog_or_otherdogs_02a.h5')
Le graphique des résultats de la formation est le suivant. ――La forme du graphique a changé. La précision commence autour de 0,88 et s'améliore de 0,93 à environ 0,96. La perte commence autour de 0,3 et se situe entre 0,1 et 0,2. Il y a des signes d'amélioration par rapport à l'état de surapprentissage.
Ensuite, vérifiez le résultat de la classification de ce modèle avec les données de test. (Voir l'article précédent pour le code) test loss: 0.274524162985399 test acc: 0.9333333373069763
À la suite de l'apprentissage par transfert, les performances de classification se sont améliorées. La précision a dépassé 90% pour la première fois. Dans cet essai, seul le module formé de VGG16 a été utilisé pour la base de convolution, mais la capacité d'extraire la carte des caractéristiques locales très polyvalente obtenue par la formation avec ImageNet contribue grandement aux performances de classification. Vous pouvez voir que ce sera le cas.
Le réglage fin dégivre plusieurs couches côté sortie de la base de convolution gelée utilisée pour l'extraction de caractéristiques et entraîne à la fois la partie nouvellement ajoutée du modèle (dans ce cas le classificateur entièrement couplé) et la couche décongelée. C'est un mécanisme à faire.
- Ajouter un réseau personnalisé à la fin du réseau de base formé
conv_base.trainable = True
set_trainable = False
for layer in conv_base.layers:
if layer.name == 'block5_conv1':
set_trainable = True
if set_trainable:
layer.trainable = True
else:
layer.trainable = False
Apprenons avec le code suivant.
#Sélectionnez RMSprop comme optimiseur et utilisez un taux d'apprentissage assez faible
#Si la valeur de mise à jour est élevée, cela endommagera les expressions des trois couches cibles de réglage fin.
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-5),
metrics=['acc'])
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)
Enregistrez le modèle après l'entraînement.
model.save('mydog_or_otherdogs_02b.h5')
Le graphique résultant est présenté ci-dessous. Le code suivant lisse le graphique.
#Lissage du tracé
def smooth_curve(points, factor=0.8):
smoothed_points = []
for point in points:
if smoothed_points:
previous = smoothed_points[-1]
smoothed_points.append(previous * factor + point * (1 - factor))
else:
smoothed_points.append(point)
return smoothed_points
plt.plot(epochs, smooth_curve(acc), 'bo', label='Smoothed training acc')
plt.plot(epochs, smooth_curve(val_acc), 'b', label='Smoothed validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, smooth_curve(loss), 'bo', label='Smoothed training loss')
plt.plot(epochs, smooth_curve(val_loss), 'b', label='Smoothed validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
Le graphique est le suivant. En regardant l'état de validation, il ne semble pas que les performances s'améliorent à mesure que le nombre d'époques augmente, mais la plage de changement dans le graphique est affichée dans une plage plus étroite qu'auparavant, de sorte que la précision est améliorée. Vous pouvez vous attendre à y être.
Les résultats de vérification appliqués aux données de test sont les suivants.
test loss: 0.5482699687112941 test acc: 0.9499999916553498
Grâce à des ajustements précis, nous avons pu améliorer encore les performances de classification. Je voudrais mettre en œuvre diverses approches que je n'ai pas encore essayées pour améliorer encore la précision. Dans cette vérification, nous ferons une pause jusqu'à présent.
Recommended Posts