You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ResNet50二分类训练报错:期望avg_pool为4维但得到(100,2)数组

Fixing the ValueError in Your Binary Classification ResNet50 Code

Hey there, let's break down why you're hitting this ValueError: Error when checking target: expected avg_pool to have 4 dimensions, but got array with shape (100, 2) error and fix it step by step.

Root Cause

The core issue is a mismatch between your model's output shape and the label shape generated by your data pipeline. Let's walk through the specific problems in your code and how to fix them.

1. Broken Model Construction Logic

Looking at your model code, you're accidentally discarding your custom classification layer:

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()  # ❌ This removes your new Dense layer!
model = Model(input=model.input,output=model.layers[-1].output)

After adding a Dense(1, sigmoid) layer for binary classification, you immediately pop it off. This leaves your model outputting the raw avg_pool layer results from ResNet50, which has a shape that doesn't align with your training labels.

Fixed Model Code

Let's rebuild the model properly, using a pre-trained ResNet50 without the ImageNet top layer, then add our own binary classification head:

# Load ResNet50 without the pre-trained top classification layer
model = ResNet50(include_top=False, weights=resnet_weights_path, input_shape=(IMAGE_RESIZE, IMAGE_RESIZE, CHANNELS))

# Freeze pre-trained layers (unfreeze later if you want to fine-tune)
for layer in model.layers:
    layer.trainable = False

# Add custom classification layers
x = model.output
x = GlobalAveragePooling2D()(x)  # Ensures we get a 2D tensor (batch_size, 2048)
predictions = Dense(1, activation='sigmoid')(x)  # Binary classification output

# Final model
model = Model(inputs=model.input, outputs=predictions)
  • Using include_top=False avoids loading the 1000-class ImageNet head, so we can build our own
  • Freezing layers prevents overwriting pre-trained weights during initial training
  • GlobalAveragePooling2D ensures our output is compatible with the dense classification layer

2. Mismatched class_mode in Data Generators

You're using class_mode='categorical' in your flow_from_directory calls, which generates 2D one-hot encoded labels (shape (batch_size, 2)). But your model uses sigmoid activation, which expects 1D binary labels (shape (batch_size,)).

Fixed Data Generator Code

Change class_mode to 'binary' for both generators:

train_generator = train_datagenerator.flow_from_directory(
    train_data_dir,
    target_size=(image_size, image_size),
    batch_size=BATCH_SIZE_TRAINING,
    class_mode='binary',  # ✅ Match sigmoid output
    shuffle=False,
    subset='training')

validation_generator = train_datagenerator.flow_from_directory(
    train_data_dir,
    target_size=(image_size, image_size),
    batch_size=BATCH_SIZE_VALIDATION,
    class_mode='binary',  # ✅ Same here
    shuffle=False,
    subset='validation')

3. Other Minor Cleanup

  • You have unused code for building a custom label list t—since flow_from_directory automatically generates labels from your folder structure, you can delete this section to avoid confusion
  • Define STEPS_PER_EPOCH_TRAINING properly (use len(train_generator) instead of an undefined variable)
  • Ensure your callbacks (cb_checkpointer, cb_early_stopper) are defined before training

Final Core Working Code Snippet

Here's the streamlined, fixed version of your core training code:

# Model Setup
NUM_CLASSES = 2
CHANNELS = 3
IMAGE_RESIZE = 224
resnet_weights_path = '../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
NUM_EPOCHS = 10

model = ResNet50(include_top=False, weights=resnet_weights_path, input_shape=(IMAGE_RESIZE, IMAGE_RESIZE, CHANNELS))
for layer in model.layers:
    layer.trainable = False

x = model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(1, activation='sigmoid')(x)
model = Model(inputs=model.input, outputs=predictions)

# Compile Model
from keras.optimizers import SGD
model.compile(loss='binary_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9), metrics=['binary_accuracy'])

# Data Pipeline
from keras.applications.resnet50 import preprocess_input
from keras.preprocessing.image import ImageDataGenerator

train_datagenerator = ImageDataGenerator(
    preprocessing_function=preprocess_input,
    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_RESIZE, IMAGE_RESIZE),
    batch_size=100,
    class_mode='binary',
    subset='training'
)

validation_generator = train_datagenerator.flow_from_directory(
    train_data_dir,
    target_size=(IMAGE_RESIZE, IMAGE_RESIZE),
    batch_size=100,
    class_mode='binary',
    subset='validation'
)

# Train
fit_history = model.fit_generator(
    train_generator,
    steps_per_epoch=len(train_generator),
    epochs=NUM_EPOCHS,
    validation_data=validation_generator,
    validation_steps=len(validation_generator),
    callbacks=[cb_checkpointer, cb_early_stopper]
)

This should resolve the shape mismatch error and let your binary classification model train properly.

内容的提问来源于stack exchange,提问作者SpEm1822

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:16:21