Actuellement, j'essaie de former un ensemble de données sur un modèle VGG-16. Le problème est que la précision ne change pas beaucoup, mais elle n'est pas limitée à une précision fixe. La figure de l'intrigue peut être vue ci-dessous. Avez-vous des suggestions à expliquer pourquoi cela se produit?
J'ai suivi plusieurs guides pour résoudre ce problème lié à la précision bloquée, mais ils ne fonctionnent pas.
MODIFIER:
La taille d'entrée pour le Le modèle est 600 images de 224x224x3. De plus, deux libellés chien et chat (0,1).
Propriétés
r = model.fit_generator(imgGen.flow(trainX, trainY, batch_size=batch_size), validation_data = imgGen.flow(testX, testY, batch_size=batch_size), epochs=epochs, steps_per_epoch=len(trainX)//batch_size, validation_steps=len(testX)//batch_size, verbose = 1, )
Modèle strong >
from keras.applications.vgg16 import preprocess_input from keras.preprocessing import image from keras.preprocessing.image import ImageDataGenerator imgGen = ImageDataGenerator(rotation_range=20, width_shift_range=0.1, height_shift_range=0.1, shear_range=0.1, zoom_range=0.2, horizontal_flip=True, vertical_flip=True, preprocessing_function = preprocess_input)
Générateur d'images
from keras.applications.vgg16 import VGG16 vgg = VGG16(input_shape=imageSize,weights=None,include_top=False) x = Flatten()(vgg.output) prediction = Dense(1,activation='sigmoid')(x) model = Model(inputs=vgg.input,outputs=prediction) model.compile(loss='binary_crossentropy', optimizer='adam',metrics=['accuracy'])
Fit Model
imageSize = (224,224,3) epochs = 25 batch_size = 32
5 Réponses :
25 époques ne suffisent pas, essayez 100 époques ou 200 époques
def model(self): inputs = keras.layers.Input(shape=self.input_Shape) x = keras.layers.Conv2D(16, (3,3), activation='relu')(inputs) x = keras.layers.MaxPooling2D(2,2)(x) x = keras.layers.Conv2D(32,(3,3),activation='relu')(x) x = keras.layers.MaxPooling2D(2,2)(x) x = keras.layers.Conv2D(64,(3,3),activation='relu')(x) x = keras.layers.MaxPooling2D(2,2)(x) x = keras.layers.Flatten()(x) x = keras.layers.Dense(512,activation='relu')(x) outputs = keras.layers.Dense(1,activation='sigmoid')(x) model = keras.models.Model(inputs, outputs) model.summary() model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics = ['acc']) return model
sry, je revérifie le modèle. Le modèle vgg d'origine n'a pas de couche de sortie. Vous devez donc ajouter une couche de sortie. keras.layers.Dense (1, actication = 'sigmoïde')
Merci d'avoir suggéré. Après l'avoir essayé, je vous répondrai.
si plusieurs époques ne fonctionnent toujours pas. pouvez-vous essayer d'utiliser le poids pré-entraîné et ensuite vérifier le résultat?
Actuellement, j'essaie avec 200 époques et je vous donnerai le graphique de la figure par la suite. Oui, je peux faire ça :)
J'ai essayé les deux et cela ne semble pas fonctionner. J'ai édité mon message et ajouté les parcelles là-dedans :)
Je ne sais vraiment pas pourquoi VGG16 ne peut pas faire cette classification binaire. La dernière fois que j'ai essayé un simple CNN, cela fonctionne.
N'utilisez pas l'optimiseur adam
pour entraîner VGG, il est bien connu qu'il échoue en raison du grand nombre de paramètres dans le réseau VGG. Utilisez simplement sgd
et réglez le taux d'apprentissage, par exemple à partir de 0,01, en augmentant 10x ou 0,1x jusqu'à ce que la perte d'entraînement diminue bien.
Spot sur @Dr. Snoopy, merci! Bien que je me demande pourquoi c'est le cas? Savez-vous?
Je vous suggère de peaufiner le modèle pré-entraîné et de figer les poids des premières couches. comme:
vgg = VGG16(input_shape=imageSize,weights='imagenet',include_top=False) for layer in vgg.layers[0:-10]: layer.trainable = false
Pour les personnes qui peuvent avoir des problèmes similaires, vous pouvez essayer les solutions suivantes:
En ce qui concerne l'utilisation de poids pré-entraînés, l'avantage d'utiliser des poids pré-entraînés est que vous pouvez surmonter une limitation d'un petit ensemble de données comme la situation d'OP avec 600 images. Mais vous devez vous assurer que seules les dernières couches peuvent être entraînées et que le repos ne peut pas être entraîné.
Vous cherchiez la raison pour laquelle cela se produit, je suppose, et il semble que vous n'ayez pas obtenu la réponse, alors la voici ...
La raison est que dans VGGNet, AlexNet l ' espace de paramètres est énorme , pour résoudre ce problème, il n'a pas de techniques sophistiquées comme BatchNorm utilisées dans ResNet et derniers modèles. Donc dans VGGNet pour faire converger le modèle, vous devez le faire vous-même, jouer avec les hyperparamètres en particulier le taux d'apprentissage, le résultat empirique montre que commencer par aussi bas que 1e-6 aide même à converger. De plus, si vous pouviez utiliser une initialisation de poids différente pour les poids, cela montrerait un résultat énorme en termes de convergence, car l'initialisation de poids par défaut ne fonctionne pas bien dans ce cas. Enfin, laissez le modèle s'entraîner pour des époques plus longues (comme 100) car l'espace (des paramètres) est assez cahoteux, vous le verrez osciller un peu mais avec un lr approprié, il convergera mais prendra un certain temps.
J'espère que cela vous donne un peu l'intuition ...