fchollet / deep-learning-with-python-notebooks

Jupyter notebooks for the code samples of the book "Deep Learning with Python"
MIT License
18.61k stars 8.63k forks source link

5.3 ValueError: logits and labels must have the same shape ((None, None, None, 1) vs (None, 1)) #157

Open glushakviktor opened 3 years ago

glushakviktor commented 3 years ago

Hello, can you help me please. When I try to check my result on a test samples. I have an error.
My code same as yours from listings 5.17 to 5.19:

import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.applications import VGG16

conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(150,150,3))

base_dir = 'new_docs/'
train_dir = os.path.join(base_dir,'train')
validation_dir = os.path.join(base_dir,'validation')
test_dir = os.path.join(base_dir,'test')

datagen = ImageDataGenerator(rescale=1./255)
batch_size = 20

def extract_features(directory, sample_count):
    features = np.zeros(shape=(sample_count, 4, 4, 512))
    labels = np.zeros(shape=(sample_count))

    generator = datagen.flow_from_directory(
        directory,
        target_size=(150,150),
        batch_size=batch_size,
        class_mode='binary'
    )
    i = 0
    for input_batch, labels_batch in generator:
        features_batch = conv_base.predict(input_batch)
        features[i * batch_size : (i + 1) * batch_size] = features_batch
        labels[i * batch_size : (i + 1) * batch_size] = labels_batch
        i += 1
        if i * batch_size >= sample_count:
            break
        return features, labels

train_features, train_labels = extract_features(train_dir, 2000)
validation_features, validation_labels = extract_features(validation_dir, 1000)
test_features, test_labels = extract_features(test_dir, 1000)

train_features = np.reshape(train_features, (2000, 4 * 4 * 512))
validation_features = np.reshape(validation_features, (1000, 4 * 4 * 512))
test_features = np.reshape(test_features, (1000, 4 * 4 * 512))

from keras import models
from keras import layers
from keras import optimizers

model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim= 4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(
    optimizer=optimizers.RMSprop(lr=2e-5),
    loss='binary_crossentropy',
    metrics=['acc']
)

history = model.fit(train_features, train_labels,
                    epochs=30,
                    batch_size=20,
                    validation_data=(validation_features, validation_labels))

model.save('pas_vgg16_2.h5')

Then after I saved a model, and in another file I loaded it

import os
from keras.preprocessing.image import ImageDataGenerator

from keras.models import load_model
base_dir = 'new_docs/'
test_dir = os.path.join(base_dir,'test')
# load model
model = load_model('pas_vgg16_2.h5')

test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_directory(
        test_dir,
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=50)
print('test acc:', test_acc)

Then I have the error:

ValueError: logits and labels must have the same shape ((None, None, None, 1) vs (None, 1))
ericvoots commented 3 years ago

were you able to solve this?

lbjai commented 3 years ago

最后一层之前 Flatten 一下就好,模型示例如下: image

alibaghayeri commented 3 years ago

you need to match output dimension of your network with label dimension, so you can use GlobalAveragePooling 2D or 3D layer(depend on data shape, here 2D), or Flatten layer after Dense layer.

model = models.Sequential() model.add(layers.Dense(256, activation='relu', input_dim= 4 4 512)) model.add(layers.Dropout(0.5)) model.add(GlobalAveragePooling2D()) or model.add(Flatten()) model.add(layers.Dense(1, activation='sigmoid'))

amonmoce commented 3 years ago

最后一层之前 Flatten 一下就好,模型示例如下: image

This solution worked for me. Thanks @lbjai and @alibaghayeri

ilmal commented 2 years ago

I didn't quite have the same err as the OP, but hopefully I might be able to help anyone else stuck with similar errors.

The problem I had was:

ValueError: logits and labels must have the same shape, received ((None, 1) vs (None, 2)).

This was because when loading data with pandas, the index will be loaded as Unnamed: 0, which will result in the y_data having two columns. And so not working with binary classification. Just a heads up for anyone with this problem!

Solution is simply:

y_train = pd.read_csv(PATH_TO_DATA, index_col=[0])