ImageDataGenerator的标签形状错误

时间:2020-06-22 10:40:24

标签: python tensorflow machine-learning keras deep-learning

我正在尝试训练具有不同尺寸图像的模型,通常我会使用flatten,但是flatten()期望所有图像都具有固定尺寸,而我没有。

在这里,我尝试用GlobalMaxPool2D()替换flatten,但是最后我遇到了预期尺寸的问题。我是TensorFlow的新手,但我很难理解在哪里可以调整模型以避免出现预期的问题?

代码:(某些导入是不必要的,但是将在以后使用,如果有不兼容的情况,我会添加它们)

from __future__ import print_function
import keras

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, GlobalMaxPool2D
import os
from random import shuffle

train_image_generator = ImageDataGenerator(rescale=1./255) # Generator for our training data
validation_image_generator = ImageDataGenerator(rescale=1./255) # Generator for our validation data
batch_size = 128

train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                           directory=f"/kaggle/working",
                                                           shuffle=True,
                                                           class_mode='binary')
val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size,
                                                           directory=f"/kaggle/working/",
                                                           shuffle=True,
                                                           class_mode='binary')

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=(None,None,3))) #We change the input shape because the images have different shapes but always 3 chan.
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

# model.add(Flatten()) #as all the pictures have different size, flatten does not work. Possibly other solutions found there :
model.add(GlobalMaxPool2D())
# https://stackoverflow.com/questions/47795697/how-to-give-variable-size-images-as-input-in-keras
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)

# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

# X_train_i = X_train_i.astype('float32')
# X_test_i = X_test_i.astype('float32')
X_train_i /= 255
X_test_i /= 255
model.summary()
model.fit_generator(train_data_gen,
        steps_per_epoch=2000,
        epochs=10,
        validation_data=val_data_gen,
        validation_steps=800)
#             batch_size=batch_size,
#             epochs=epochs,
#             validation_data=(X_test_i, y_test),
#             shuffle=True)


# Score trained model.
scores = model.evaluate(X_test_i, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

模型总结如下:

Model: "sequential_11"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_20 (Conv2D)           (None, None, None, 32)    896       
_________________________________________________________________
activation_38 (Activation)   (None, None, None, 32)    0         
_________________________________________________________________
conv2d_21 (Conv2D)           (None, None, None, 32)    9248      
_________________________________________________________________
activation_39 (Activation)   (None, None, None, 32)    0         
_________________________________________________________________
dropout_20 (Dropout)         (None, None, None, 32)    0         
_________________________________________________________________
global_max_pooling2d_9 (Glob (None, 32)                0         
_________________________________________________________________
dense_19 (Dense)             (None, 512)               16896     
_________________________________________________________________
activation_40 (Activation)   (None, 512)               0         
_________________________________________________________________
dropout_21 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_20 (Dense)             (None, 2)                 1026      
_________________________________________________________________
activation_41 (Activation)   (None, 2)                 0         
=================================================================
Total params: 28,066
Trainable params: 28,066
Non-trainable params: 0
_________________________________________________________________
Epoch 1/10

错误如下:

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

似乎绝对值是“一半”,但我尝试删除一些图层,但无法使其正常工作。

此外,如果您可以推荐一个教程以更好地理解这些概念,我将不知所措。

非常感谢++

1 个答案:

答案 0 :(得分:2)

我不认为您应该放n_classes=1(如您的评论所述),因为它不是True,并且可能会带来混乱。您可以使用一种适用于所有情况的方法。

无论类数是多少,都可以使用class_mode='categorical'

然后,在最后一层中,您甚至不必手动设置类别数,您可以执行以下操作:

Dense(units=len(train_data_gen.class_indices))

然后,您将始终在最终神经元和类别数量之间找到匹配。然后,请始终确保您有一个损失函数,该函数允许一键编码输出,并且一切顺利(例如categorical_crossentropy