2
votes

Pourquoi ai-je besoin de compiler et d'ajuster un modèle pré-entraîné dans Keras?

Je souhaite charger un modèle pré-entraîné et commencer à tester des images.

Voici le code qui, selon moi, fonctionnerait:

from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras import backend as K

base_model = InceptionV3(weights='imagenet', include_top=False)

from __future__ import absolute_import, division, print_function

import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

#Preprocessing
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = train_images / 255.0
test_images = test_images / 255.0
#Preprocessing

test_loss, test_acc = base_model.evaluate(test_images, test_labels)

print('Test accuracy:', test_acc)

Au lieu de cela, il dit: "Vous devez compiler un modèle avant l'entraînement / le test"

En regardant ici https://keras.io/applications/ sur InceptionV3: ils semblent compiler et adapter le modèle après son importation. Pourquoi font-ils cela?


0 commentaires

3 Réponses :


2
votes

La plupart des modèles de classification d'images pré-entraînés sont pré-entraînés sur l'ensemble de données ImageNet, vous chargez donc les pondérations des paramètres de cette formation lorsque vous appelez base_model = InceptionV3 (weights = 'imagenet', include_top = False) . Le paramètre include_top = False coupe en fait la couche de prédiction du modèle, que vous devez ajouter et entraîner sur votre propre jeu de données, Fashion MNIST dans ce cas.

L'approche d'apprentissage par transfert ne supprime pas complètement toute formation, mais fait en sorte que vous n'ayez qu'à affiner le modèle en fonction des données spécifiques de votre ensemble de données. Étant donné que le modèle a déjà appris à reconnaître des formes de base et même quelque peu complexes en s'entraînant sur ImageNet, il lui suffit maintenant d'être formé pour reconnaître ce que certaines combinaisons de formes signifient dans le contexte de vos données.

Cela étant dit, je pense que vous devriez toujours pouvoir appeler model.predict (x) sur une image prétraitée, x, si vous remplacez include_top = False par include_top = True , bien que le modèle essaie de classer l'image dans l'une des 1000 classes d'ImageNet et non dans l'une des classes de Fashion MNIST.


0 commentaires

1
votes

Le modèle InceptionV3 a été formé sur des images très différentes par rapport à Fashion MNIST. Ce que vous voyez dans le didacticiel est une instance de l ' apprentissage par transfert . En gros, dans l'apprentissage par transfert, vous pouvez diviser le modèle en un module d'extraction de caractéristiques et un module de classification. L'objectif des couches convolutives et de regroupement est d'automatiser les extractions de caractéristiques afin que nous puissions produire une transformation idéale des pixels d'image bruts en un ensemble représentatif de caractéristiques qui décrit bien les images.

Ces images sont ensuite transmises à un module de classification , où le but est de prendre ces fonctionnalités et de faire une classification. C'est l'objectif des couches denses qui sont attachées après la convolution et la mise en commun. Notez également que le modèle InceptionV3 est formé sur des images ImageNet, qui ont 1000 classes. Afin d'appliquer avec succès ImageNet à l'ensemble de données Fashion MNIST, vous devrez recycler les couches Dense afin que les couches de convection et de regroupement puissent prendre les caractéristiques extraites des images et effectuer une classification à ce sujet. Par conséquent, définissez include_top = False comme ce que vous avez fait, mais vous devrez également attacher des couches Dense et les recycler. Assurez-vous également que vous spécifiez la dernière couche pour avoir 10 classes en raison du jeu de données Fashion MNIST.

Cependant, certains pièges sont qu'InceptionV3 prend des images de taille 299 x 299 où Fashion MNIST prend 28 x 28. Vous devrez redimensionner les images, ainsi que garnir artificiellement les images dans la troisième dimension afin qu'elles soient RVB. Parce que passer de 28 x 28 à 299 x 299 nécessite une augmentation d'un facteur 10 dans les deux dimensions, le redimensionnement des images jusqu'à cette résolution ne sera probablement pas bien perceptible. InceptionV3 peut charger dans un modèle où vous pouvez modifier la taille d'image d'entrée attendue. La plus petite taille d'image est malheureusement 75 x 75 pour InceptionV3, nous devrons donc l'utiliser puis redimensionner jusqu'à 75 x 75. Pour redimensionner l'image, vous pouvez utiliser Scikit-images Méthode resize de skimage.transform . De plus, si vous prévoyez d'utiliser InceptionV3, vous devrez prétraiter les images d'entrée comme ils l'ont fait dans leur réseau avant l'entraînement.

Par conséquent:

from __future__ import absolute_import, division, print_function

from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.applications.inception_v3 import preprocess_input # New
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras import backend as K

import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

base_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(75, 75, 3))

# Now add some Dense Layers - let's also add in a Global Average Pooling layer too
# as a better way to "flatten"
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a softmax layer -- 10 classes
predictions = Dense(10, activation='softmax')(x)

# Create new model
model = Model(inputs=base_model.input, outputs=predictions)

# Make sure we set the convolutional layers and pooling layers so that they're not trainable
for layer in base_model.layers:
    layer.trainable = False

#Preprocessing
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = train_images.astype(np.float) / 255.0 # Change
test_images = test_images.astype(np.float) / 255.0 # Change

# Preprocessing the images
from skimage.transform import resize
train_images_preprocess = np.zeros((train_images.shape[0], 75, 75, 3), dtype=np.float32)

for i, img in enumerate(train_images):
    img_resize = resize(img, (75, 75), anti_aliasing=True)
    img_resize = preprocess_input(img_resize).astype(np.float32)
    train_images_preprocess[i] = np.dstack([img_resize, img_resize, img_resize])

del train_images

test_images_preprocess = np.zeros((test_images.shape[0], 75, 75, 3), dtype=np.float32)

for i, img in enumerate(test_images):
    img_resize = resize(img, (75, 75), anti_aliasing=True)
    img_resize = preprocess_input(img_resize).astype(np.float32)
    test_images_preprocess[i] = np.dstack([img_resize, img_resize, img_resize])

del test_images

# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Train it
model.fit(train_images_preprocess, train_labels, epochs=15)

# Now evaluate the model - note that we're evaluating on the new model, not the old one
test_loss, test_acc = model.evaluate(test_images_preprocess, test_labels)

print('Test accuracy:', test_acc)


0 commentaires

1
votes

L'exemple que vous montrez dans la documentation Keras ne correspond pas à ce que vous souhaitez faire. Ils correspondent à un modèle afin d'effectuer un apprentissage par transfert.

Vous semblez vouloir simplement charger un modèle pré-entraîné, puis évaluer sa perte / précision sur un ensemble de données. Le problème est que pour appeler model.evaluate , vous devez d'abord définir une perte et des métriques (y compris la précision), et pour cela, vous devez appeler model.compile (loss =. .., metrics = ..., optimizer = ...) , simplement parce que c'est le seul appel Keras qui définit la perte et les métriques d'un modèle.

Si, pour une raison quelconque, vous ne souhaitez pas faire cela, vous pouvez simplement appeler y_pred = model.predict avec votre ensemble de données et utiliser n'importe quelle implémentation python de la perte et des métriques que vous souhaitez sur

code> y_true et y_pred . Cela ne nécessiterait pas de compiler le modèle lorsque vous extériorisez l'évaluation.


0 commentaires