Error when checking target: expected dense_20 to h

2019-08-27 00:35发布

With VGG 16 using Keras, I'm trying to run a three class classification problem and here is the code:

import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
from keras.optimizers import SGD
from keras import backend as K
K.set_image_dim_ordering('tf')
img_width, img_height = 48, 48
top_model_weights_path = 'vgg16_1.h5'
train_data_dir = 'data6/train'
validation_data_dir = 'data6/validation'
nb_train_samples = 400
nb_validation_samples = 100
epochs = 10
batch_size = 32
def save_bottlebeck_features():
   datagen = ImageDataGenerator(rescale=1. / 255)
   model = applications.VGG16(include_top=False, weights='imagenet', input_shape=(48, 48, 3))
   generator = datagen.flow_from_directory(
               train_data_dir,
               target_size=(img_width, img_height),
               batch_size=batch_size,
               class_mode='categorical',
               shuffle=False)
   bottleneck_features_train = model.predict_generator(
               generator, nb_train_samples // batch_size)
   np.save(open('bottleneck_features_train', 'wb'),bottleneck_features_train)

   generator = datagen.flow_from_directory(
               validation_data_dir,
               target_size=(img_width, img_height),
               batch_size=batch_size,
               class_mode='categorical',
               shuffle=False)
   bottleneck_features_validation = model.predict_generator(
               generator, nb_validation_samples // batch_size)
   np.save(open('bottleneck_features_validation', 'wb'),bottleneck_features_validation)

def train_top_model():
   train_data = np.load(open('bottleneck_features_train', 'rb'))
   train_labels = np.array(([0]*(nb_train_samples // 3) + [1]*(nb_train_samples // 3) + 
                            [2]*(nb_train_samples // 3)))
   validation_data = np.load(open('bottleneck_features_validation', 'rb'))
   validation_labels = np.array([0]*(nb_validation_samples // 3) + [1]*(nb_validation_samples // 3) + 
                                [2]*(nb_validation_samples // 3))
   model = Sequential()
   model.add(Flatten(input_shape=train_data.shape[1:]))
   model.add(Dense(128, activation='relu'))
   model.add(Dropout(0.5))
   model.add(Dense(3, activation='softmax'))
   sgd = SGD(lr=1e-2, decay=0.00371, momentum=0.9, nesterov=False)
   model.compile(optimizer=sgd,
         loss='categorical_crossentropy', metrics=['accuracy'])
   model.fit(train_data, train_labels,
          epochs=epochs,
          batch_size=batch_size,
   validation_data=(validation_data, validation_labels))
   model.save_weights(top_model_weights_path)

save_bottlebeck_features()
train_top_model()  

Running the code, I'm getting the error:

Error when checking target: expected dense_20 to have shape (None, 3) but got array with shape (1200, 1)

Kindly let me know what changes I have to make to the code to make it function. I'm using Anaconda with Python 3.5.2, running on a windows machine.

1条回答
别忘想泡老子
2楼-- · 2019-08-27 00:52

Your training output is shaped like (None, 1) --- Or (1200, 1), where there are 1200 samples, all samples with only one dimension (each sample is a number)

But your model ends with Dense(3), which will output things like (None, 3). That is: each sample has 3 numbers.

If you think your training data is correct, you must adjust your model.

A suggestion is add one more Dense(1) layer. With a "sigmoid" activation if the result is between 0 and 1, or a "tanh" if the result is between -1 and 1.

Always use model.summary() to check what dimensions your model have.

查看更多
登录 后发表回答