ValueError: Ошибка при проверке цели: ожидалось, что avg_pool будет иметь 4 измерения, но получит массив с формой (100, 2) - PullRequest
1 голос
/ 09 октября 2019

Я пытаюсь запустить этот код (двоичная классификация), но все еще застрял с этой ошибкой: ValueError: Ошибка при проверке цели: ожидалось, что avg_pool будет иметь 4 измерения, но получил массив с формой (100, 2)

    NUM_CLASSES = 2
    CHANNELS = 3
    IMAGE_RESIZE = 224
    RESNET50_POOLING_AVERAGE = 'avg'
    DENSE_LAYER_ACTIVATION = 'softmax'
    OBJECTIVE_FUNCTION = 'binary_crossentropy'
    NUM_EPOCHS = 10
    EARLY_STOP_PATIENCE = 3
    STEPS_PER_EPOCH_VALIDATION = 10
    BATCH_SIZE_TRAINING = 100
    BATCH_SIZE_VALIDATION = 100
    resnet_weights_path = '../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
    train_data_dir = "C:\\Users\\Desktop\\RESNET"
    model = ResNet50(include_top=True, weights='imagenet')
    x = model.get_layer('avg_pool').output
    predictions = Dense(1, activation='sigmoid')(x)
    model = Model(input = model.input, output = predictions)
    print(model.summary())
    model.layers.pop() 
    model = Model(input=model.input,output=model.layers[-1].output)
    sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(loss='binary_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9), metrics=   ['binary_accuracy'])
    data_dir = "C:\\Users\\Desktop\\RESNET"
    batch_size = 32
    from keras.applications.resnet50 import preprocess_input
    from keras.preprocessing.image import ImageDataGenerator
    image_size = IMAGE_RESIZE
    data_generator = ImageDataGenerator(preprocessing_function=preprocess_input)
    def append_ext(fn):
        return fn+".jpg"
    dir_path = os.path.dirname(os.path.realpath(__file__))
    train_dir_path = dir_path + '\data'
    onlyfiles = [f for f in listdir(dir_path) if isfile(join(dir_path, f))]
    NUM_CLASSES = 2
    data_labels = [0, 1]
    t = []
    maxi = 25145
    LieOffset = 15799
    i = 0
    while i < maxi: # t = tuple
    if i <= LieOffset:
        t.append(label['Lie'])
    else:
        t.append(label['Truth'])
    i = i+1
    train_datagenerator = ImageDataGenerator(rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        validation_split=0.2) 
    train_generator = train_datagenerator.flow_from_directory(
        train_data_dir,
        target_size=(image_size, image_size), 
        batch_size=BATCH_SIZE_TRAINING,
        class_mode='categorical', shuffle=False, subset='training') # set as training data

    validation_generator = train_datagenerator.flow_from_directory(
        train_data_dir, # same directory as training data 
        target_size=(image_size, image_size), 
        batch_size=BATCH_SIZE_TRAINING,
        class_mode='categorical', shuffle=False, subset='validation') 

    (BATCH_SIZE_TRAINING, len(train_generator), BATCH_SIZE_VALIDATION, len(validation_generator))
    from sklearn.grid_search import ParameterGrid
    param_grid = {'epochs': [5, 10, 15], 'steps_per_epoch' : [10, 20, 50]}
    grid = ParameterGrid(param_grid)
# Accumulate history of all permutations (may be for viewing trend) and keep watching for lowest   val_loss as final model
    for params in grid:
    fit_history = model.fit_generator(
        train_generator,
        steps_per_epoch=STEPS_PER_EPOCH_TRAINING,
        epochs = NUM_EPOCHS,
        validation_data=validation_generator,
        validation_steps=STEPS_PER_EPOCH_VALIDATION,
        callbacks=[cb_checkpointer, cb_early_stopper]
    )
    model.load_weights("../working/best.hdf5")

Ответы [ 2 ]

0 голосов
/ 09 октября 2019

Измените class_mode='categorical' на class_mode='binary' в train_generator и validation_generator.

Кроме того, удалите следующие строки, поскольку вы уже создали модель.

model.layers.pop() 
model = Model(input=model.input,output=model.layers[-1].output)

ИтакВаша модель будет выглядеть так:

model = ResNet50(include_top=True, weights='imagenet')
x = model.get_layer('avg_pool').output
x = Flatten()(x)
predictions = Dense(1, activation='sigmoid')(x)
model = Model(input = model.input, output = predictions)
0 голосов
/ 09 октября 2019

Удалите эти строки, и это будет работать,

model.layers.pop() 
model = Model(input=model.input,output=model.layers[-1].output)

Первый удаляет последний (Dense) слой, а буква означает создание модели без последнего (Flatten, какDense уже всплыл) слой.

Это не имеет смысла, так как ваши целевые данные (100, 2). Почему вы помещаете их туда в первую очередь?

Также я думаю, что эта строка

predictions = Dense(1, activation='sigmoid')(x)

Произойдет ошибка, так как ваши целевые данные являются 2-канальными, если они имеют ошибку, то измените это на

predictions = Dense(2, activation='sigmoid')(x)

Обновление

Вывод avg_pool имеет 4 измерения (batch_size, высота, ширина, канал). Вам нужно сначала сделать Flatten или использовать GlobalAveragePooling2D вместо AveragePooling2D.

Как

x = model.get_layer('avg_pool').output
x = keras.layers.Flatten()(x)
predictions = Dense(1, activation='sigmoid')(x)

Или

model = ResNet50(include_top=False, pooling='avg', weights='imagenet')  # `pooling='avg'` makes the `ResNet50` include a `GlobalAveragePoiling` layer and `include_top=False` means that you don't include the imagenet's output layer
x = model.output  # as I use `include_top=False`, you don't need to care the layer name, just use the model's output right away
predictions = Dense(1, activation='sigmoid')(x)

Также как @Бит01 сказал, замените class_mode='categorical' на class_mode = 'binary'.

...