Keras ValueError:检查模型目标(CNN)时出错

时间:2019-10-09 20:39:31

标签: python keras conv-neural-network

该算法旨在描述产品。该部分从图像中识别衣服的颜色(14个输出值),但是它仍然返回以下错误

错误:

pop(ic)

部分代码:

ValueError: Error when checking model target: the list of Numpy arrays 
that you are passing to your model is not the size the model expected. 
Expected to see 1 array(s), but instead got the following list of 14 
arrays.

输入形状是在第一层“ effnet”中定义的,所以我不知道为什么会发生错误。

我也尝试将数据转换为numpy数组,但效果是相同的。

数据框训练:某事。

TRAIN_LABELS_FILE = "train/labels.txt"
VAL_LABELS_FILE = "val/labels.txt"
TEST_LABELS_FILE = "test/labels.txt"
COLOR_FILE = "names.txt"

# Specify image size
IMG_WIDTH = 128
IMG_HEIGHT = 128
CHANNELS = 3

color = pd.read_csv(COLOR_FILE)
color = color.T
color_list = list(color.iloc[0])
color_list.insert(0,'beige')
color_list.insert(0,'path')

train = pd.read_csv(TRAIN_LABELS_FILE,sep=" ",names=color_list, dtype="str")
val = pd.read_csv(VAL_LABELS_FILE,sep=" ",names=color_list, dtype="str")

from keras.preprocessing.image import ImageDataGenerator
BATCH_SIZE = 4
#directory = os.path.dirname(path)

# Add Image augmentation to our generator
train_datagen = ImageDataGenerator(rotation_range=360,
                                   horizontal_flip=True,
                                   vertical_flip=True,
                                   validation_split=0.15,
                                   #preprocessing_function=preprocess_image, 
                                   rescale=1 / 128.)

# Use the dataframe to define train and validation generators
train_generator = train_datagen.flow_from_dataframe(train, 
                                                    x_col='path', 
                                                    y_col=color_list[1:],
                                                    directory='train',
                                                    target_size=(IMG_WIDTH, IMG_HEIGHT),
                                                    batch_size=BATCH_SIZE,
                                                    class_mode="multi_output", 
                                                    subset='training')

val_generator = train_datagen.flow_from_dataframe(val, 
                                                  x_col='path', 
                                                  y_col=color_list[1:],
                                                  directory='val',
                                                  target_size=(IMG_WIDTH, IMG_HEIGHT),
                                                  batch_size=BATCH_SIZE,
                                                  class_mode="multi_output",
                                                  subset='validation')

from efficientnet import EfficientNetB5
effnet = EfficientNetB5(input_shape=(IMG_WIDTH, IMG_HEIGHT, CHANNELS),
                          weights='imagenet',
                          include_top=False)

def build_model():

    model = Sequential()
    model.add(effnet)
    model.add(GlobalAveragePooling2D())
    model.add(Dropout(0.5))
    model.add(Dense(5, activation='relu'))
    model.add(Dense(14, activation='softmax'))
    model.compile(loss='categorical_crossentropy',
                  optimizer='adam', 
                  metrics=["categorical_accuracy"])
    print(model.summary())
    return model

# Initialize model
model = build_model()

# Begin training
model.fit_generator(train_generator,
                    steps_per_epoch=train_generator.samples // BATCH_SIZE,
                    epochs=35,
                    validation_data=val_generator,
                    validation_steps = val_generator.samples // BATCH_SIZE)

2 个答案:

答案 0 :(得分:1)

模型中每个图像的y_train(地面真相标签)应该是由14个元素组成的单个数组[0,0,1,1,0,1,0,...],但看起来像您正在传递每个图像14个不同的阵列。在代码中更改y_train(y_col)的形状。另外,您将其存储在列表中,并按照模型的期望将其转换为numpy数组。

我相信您的数据存储为pandas数据框。在这种情况下,请删除第一列df.drop('Path', axis=1, inplace=True)。然后,您可以将y_train = df.to_numpy()转换为numpy数组。这将为您提供正确形状的目标。给这个适合训练的方法。

此外,请注意,df.to_numpy()仅在使用最新的熊猫版本时有效。对于旧版本,可以使用df.values将数据帧转换为numpy数组。

答案 1 :(得分:1)

class_mode="other"class_mode="multi_output"中都应使用train_generator而不是val_generator。 [Ref:multi-label-classification-with-keras-imagedatagenerator]

此外,由于这是一个多标签分类问题,因此应在模型的输出层中使用sigmoid激活函数。您还应在编译模型时使用binary_crossentropy损失,因为对于需要确定输入是否属于该类的每个目标类,都需要这样做。

model.add(Dense(14, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
              optimizer='adam', 
              metrics=["accuracy"])

希望这会有所帮助。