CNN图像分类:AlexNet准确率极低,疑数据预处理问题求助
Hey there, let's break down the issues causing your low accuracy—you were right to flag data preprocessing, but there are also critical mismatches between your task setup and model configuration that are hurting performance. Here's what to fix:
1. Fix the Classification Task Mismatch (Biggest Issue!)
Your dataset has 10 classes (class0 to class9), but your code is set up for binary classification:
- You used
class_mode='binary'in your generators - Your model ends with
Dense(1, activation='sigmoid') - You're using
binary_crossentropyloss
This is a fundamental misalignment—your model is trying to predict a single yes/no label instead of 10 distinct classes. To fix this:
- Change
class_modeto'categorical'(or'sparse_categorical'if you want to avoid one-hot encoding) - Update your model's final layer to output 10 classes with softmax activation:
tf.keras.layers.Dense(10, activation='softmax') - Switch your loss function to
categorical_crossentropy(orsparse_categorical_crossentropyif usingclass_mode='sparse_categorical'):model.compile(loss='categorical_crossentropy', optimizer=RMSprop(lr=1e-4), metrics=['acc'])
2. Fix Your Validation Set Split
You're using your Test directory to create a validation set with validation_split=0.4—this is bad practice! The Test set should be reserved exclusively for final model evaluation, not used during training for validation. Instead, split your Training directory into train/validation subsets:
Option 1: Use validation_split in train_datagen
train_datagen = ImageDataGenerator( rescale=1./255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest', validation_split=0.2 # Reserve 20% of training data for validation ) # Train generator train_generator = train_datagen.flow_from_directory( train_dir, target_size=(224, 224), batch_size=20, class_mode='categorical', subset='training' ) # Validation generator (from training data) validation_generator = train_datagen.flow_from_directory( train_dir, target_size=(224, 224), batch_size=20, class_mode='categorical', subset='validation' )
Option 2: Manually split your Training folder into train/validation subfolders
If you prefer more control, reorganize your Training directory into:
Training ├── train │ ├── class0 │ ├── ... │ └── class9 └── val ├── class0 ├── ... └── class9
Then create separate generators for each.
3. Correct steps_per_epoch and validation_steps
Your current values are way off from your actual dataset size:
- Your Training set has 10 classes × 20 images = 200 total images. With
batch_size=20,steps_per_epochshould be200 // 20 = 10(not 100). - If using 20% validation split from training data, that's 40 images, so
validation_steps = 40 // 20 = 2(adjust based on your actual split size).
Update your fit_generator call:
history = model.fit_generator( train_generator, steps_per_epoch=10, # Match actual training batch count epochs=20, # You may need more epochs than 10 for AlexNet to converge validation_data=validation_generator, validation_steps=2, verbose=2 )
4. Improve Data Preprocessing for AlexNet
AlexNet was trained with specific preprocessing steps that you're missing:
- Mean Subtraction: Subtract the mean pixel value of your dataset (or ImageNet's mean if fine-tuning) from each channel. For example:
# Add this custom preprocessing function def preprocess_input(x): x = x * 255.0 # Scale back to 0-255 since you rescaled to 0-1 x[..., 0] -= 103.939 x[..., 1] -= 116.779 x[..., 2] -= 123.68 return x train_datagen = ImageDataGenerator( preprocessing_function=preprocess_input, # ... other augmentation parameters ) test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input) - Note: If you're training from scratch (not fine-tuning), compute the mean of your own training dataset instead of using ImageNet's mean.
5. Simplify AlexNet Architecture for Your Task
Your model has a redundant Dense(1000) layer leftover from the original AlexNet (trained on 1000 ImageNet classes). Remove this to streamline your model for 10 classes:
# Remove this unnecessary block: # tf.keras.layers.Dense(1000, activation='relu'), # tf.keras.layers.Dropout(0.5), # tf.keras.layers.BatchNormalization(), # Keep only the final 10-class output layer: tf.keras.layers.Dense(10, activation='softmax')
Once you make these changes, your model will align with your multi-class classification task, and you should see a significant improvement in accuracy. Remember to test your final model on the untouched Test directory once training is complete!
内容的提问来源于stack exchange,提问作者ungau76

