CNN图像分类模型未学习求助:准确率与损失值恒定
Hey there! Let's break down why your CNN is stuck with constant accuracy and loss—this is a common issue, and we can fix it by checking a few key areas in your code.
1. Fix Data Normalization (Critical!)
Your images are loaded with pixel values in the range 0-255, but CNNs perform best when input data is normalized to a smaller range (like 0-1). Right now, your ImageDataGenerator instances don't include a rescaling step, which can cause gradient issues that prevent weight updates.
Update your data generators to add rescale=1./255:
# Training data generator with augmentation + normalization train_datagen = ImageDataGenerator( rotation_range=5, zoom_range=0.1, rescale=1./255 # Add this line ) # Testing and validation generators with normalization only datagen=ImageDataGenerator(rescale=1./255) # Add rescale here too
2. Verify Your Data Loaders Are Working Correctly
It's possible your generators aren't loading labels or images as expected. Let's validate this:
Check class mappings: Print the class indices to confirm your labels are being recognized properly:
print("Training class indices:", train.class_indices) print("Validation class indices:", validation.class_indices)You should see a dictionary mapping
class0,class1,class2to 0,1,2 (or similar). If any class is missing, your label replacement step might have failed.Inspect a batch of data: Pull a batch from your training generator to check if images and labels are valid:
x_batch, y_batch = next(train) print("Image batch shape:", x_batch.shape) # Should be (32,256,256,3) print("Label batch shape:", y_batch.shape) # Should be (32,3) for 3 classes print("Sample label:", y_batch[0]) # Should be a one-hot vector like [1,0,0]If labels are all the same (e.g., all
[1,0,0]), your dataset might be imbalanced or your label loading is broken.
3. Update fit_generator to Modern Keras fit
fit_generator is deprecated in newer Keras versions—use fit directly, and explicitly set steps_per_epoch and validation_steps to avoid auto-calculation errors:
# Calculate steps based on batch size and dataset length steps_per_epoch = len(trainingfile) // train.batch_size validation_steps = len(validationfile) // validation.batch_size # Train with fit instead of fit_generator h = model.fit( train, validation_data=validation, epochs=50, callbacks=[es], steps_per_epoch=steps_per_epoch, validation_steps=validation_steps )
This ensures the model sees the full dataset each epoch, which is crucial for learning.
4. Check Optimizer and Learning Rate
While the default Adam optimizer works for most cases, a misconfigured learning rate can halt learning. Try explicitly setting a smaller learning rate if the above fixes don't work:
from keras.optimizers import Adam model.compile(optimizer=Adam(learning_rate=0.0001), loss="categorical_crossentropy", metrics=["accuracy"])
5. Minor Architecture Adjustment (Optional)
Your batch normalization placement is after max pooling, which is okay, but some practitioners prefer placing it before the activation function for better stability. You can test this adjustment for one convolution block to see if it helps:
# Revised first convolution block model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(256, 256,3))) model.add(BatchNormalization()) # Batch norm before activation model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2,2)))
Next Steps
Start with the normalization fix and data loader checks—those are the most likely culprits. If the model still doesn't learn, move on to adjusting the learning rate and architecture.
内容的提问来源于stack exchange,提问作者Panri93

