web-dev-qa-db-fra.com

Erreur lors de la vérification de la cible: dense_3 devrait avoir une forme (3,) mais un tableau avec une forme (1,)

Je travaille actuellement à la formation d'un modèle de type VGG16 à Keras, sur un sous-ensemble de 3 classes de Places205, et j'ai rencontré l'erreur suivante:

ValueError: Error when checking target: expected dense_3 to have shape (3,) but got array with shape (1,)

J'ai lu plusieurs numéros similaires, mais aucun ne m'a aidé jusqu'à présent. L'erreur est sur la dernière couche, où j'ai mis 3 parce que c'est le nombre de classes que j'essaie en ce moment.

Le code est le suivant:

import keras from keras.datasets
import cifar10 from keras.preprocessing.image 
import ImageDataGenerator 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 import os


# Constants used  
img_width, img_height = 224, 224  
train_data_dir='places\\train'  
validation_data_dir='places\\validation'  
save_filename = 'vgg_trained_model.h5'  
training_samples = 15  
validation_samples = 5  
batch_size = 5  
epochs = 5


if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height) else:
    input_shape = (img_width, img_height, 3)

model = Sequential([
    # Block 1
    Conv2D(64, (3, 3), activation='relu', input_shape=input_shape, padding='same'),
    Conv2D(64, (3, 3), activation='relu', padding='same'),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    # Block 2
    Conv2D(128, (3, 3), activation='relu', padding='same'),
    Conv2D(128, (3, 3), activation='relu', padding='same'),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    # Block 3
    Conv2D(256, (3, 3), activation='relu', padding='same'),
    Conv2D(256, (3, 3), activation='relu', padding='same'),
    Conv2D(256, (3, 3), activation='relu', padding='same'),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    # Block 4
    Conv2D(512, (3, 3), activation='relu', padding='same'),
    Conv2D(512, (3, 3), activation='relu', padding='same'),
    Conv2D(512, (3, 3), activation='relu', padding='same'),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    # Block 5
    Conv2D(512, (3, 3), activation='relu', padding='same',),
    Conv2D(512, (3, 3), activation='relu', padding='same',),
    Conv2D(512, (3, 3), activation='relu', padding='same',),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    # Top
    Flatten(),
    Dense(4096, activation='relu'),
    Dense(4096, activation='relu'),
    Dense(3, activation='softmax') ])

model.summary()

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# no augmentation config train_datagen = ImageDataGenerator() validation_datagen = ImageDataGenerator()
     train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

validation_generator = validation_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

model.fit_generator(
    train_generator,
    steps_per_Epoch=training_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=validation_samples // batch_size)

model.save_weights(save_filename)

Le problème vient de votre forme de données d'étiquette. Dans un problème multiclass, vous prédisez la probabilité de chaque classe possible. Vous devez donc fournir des données d'étiquette sous la forme (N, m), où N est le nombre d'exemples d'apprentissage et m le nombre de classes possibles (3 dans votre cas). .

Keras s'attend à ce que les données y soient en forme (N, 3) et non pas (N,) comme vous l'avez probablement fourni, c'est pourquoi une erreur est générée.

Utilisez par exemple OneHotEncoder pour convertir vos données d'étiquette en une forme encodée à chaud.

14
Kamil Kaczmarek

Comme mentionné par d'autres, Keras s'attend à un encodage "à chaud" dans les problèmes multiclass.

Keras est livré avec une fonction pratique pour recoder les étiquettes:

print(train_labels)
[1. 2. 2. ... 1. 0. 2.]

print(train_labels.shape)
(2000,)

Recodez les étiquettes en utilisant to_categorical Pour obtenir la forme correcte des entrées:

from keras.utils import to_categorical
train_labels = to_categorical(train_labels)

print(train_labels)
[[0. 1. 0.]
 [0. 0. 1.]
 [0. 0. 1.]
 ...
 [0. 1. 0.]
 [1. 0. 0.]
 [0. 0. 1.]]

print(train_labels.shape)
(2000, 3)  # viz. 2000 observations, 3 labels as 'one hot'

Autres éléments importants à modifier/vérifier en multiclass (par rapport à la classification binaire):

Définissez class_mode='categorical' Dans la (les) fonction (s) generator().

N'oubliez pas que la dernière couche dense doit spécifier le nombre d'étiquettes (ou de classes):

model.add(layers.Dense(3, activation='softmax'))

Assurez-vous que activation= Et loss= Sont choisis de manière à répondre aux problèmes multiclass, cela signifie généralement activation='softmax' Et loss='categorical_crossentropy'.

8
Peter

Avait le même problème. Pour résoudre le problème, vous pouvez simplement changer dans validation_generator et train_generator le mode de classe de "binaire" à "catégorique" - c'est parce que vous avez 3 classes, ce qui n'est pas binaire.

8
Doctor Strange

Problème: dense_3 devrait avoir une forme (3,) mais un tableau avec une forme (1,)

Si vous l'utilisez pour la classification, le nombre de variables doit être correct dans le paramètre permettant d'ajouter une couche dense.

variables_for_classification=5 #change it as per your number of categories
model.add(Dense(variables_for_classification, activation='softmax'))

model.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size,validation_split=0.1,callbacks=[EarlyStopping(monitor='val_loss', patience=3, min_delta=0.0001)])

Pour le rendre plus clair. Comme je me servais du LSTM pour prédire la catégorie de nouvelles et les catégories 5 à 5: affaires, technologie, politique, sports, divertissement

Dans cette fonction dense quand je mets 5 cela a fonctionné correctement.

1
Vinay Verma