Keras猫狗分类CNN预测异常:始终输出单一类别问题求助
Hey there! Let's figure out why your CNN is only predicting a single class on test images, even though it hit 80% accuracy during training. This is a common gotcha, and usually boils down to a few key issues—let's break them down step by step:
1. Test Data Preprocessing Doesn't Match Training
This is the #1 culprit here. Your model learned patterns based on how you processed training images—if test images are handled differently, the model can't make sense of them.
- Check normalization: Did you scale training images (e.g., divide by 255.0) but forget to do the same for test images? If training data was in [0,1] but test data stays in [0,255], the model will see drastically different value ranges and fail to generalize.
- Image size & channels: Did you resize training images to a specific size (like 64x64) but test images use a different dimension? Also, double-check if you're using RGB vs grayscale consistently—if training was on RGB but test images are loaded as grayscale (or vice versa), the input shape mismatch will throw off predictions.
- DataGenerator consistency: If you used
ImageDataGeneratorfor training (with augmentation like rotations/flips), make sure you're using the same generator (without augmentation) for testing—don't redefine a new one with different parameters.
Example fix for consistent preprocessing (use this across train and test):
def preprocess(img_path, target_size=(64, 64)): img = scipy.misc.imread(img_path) img = scipy.misc.imresize(img, target_size) img = img / 255.0 # Critical normalization step return np.expand_dims(img, axis=0) # Add batch dimension for model input
2. Post-Prediction Logic Errors
Sometimes the model outputs correct probabilities, but your code interprets them wrong.
- Check prediction extraction: If you're using
model.predict(), it returns class probabilities (e.g.,[0.9, 0.1]for cat,[0.2, 0.8]for dog). Did you forget to usenp.argmax(pred, axis=1)to get the class index? - Label mapping mix-up: You defined cats as
[1,0]and dogs as[0,1]—soargmax(pred)returning 0 means cat, 1 means dog. Are you accidentally mapping 0 to dog instead? That could make you think all predictions are the same when they're not. - Threshold issues: If you're using a custom threshold (e.g., "if probability > 0.6, classify as cat"), make sure it's not set too high/low. For example, if most test predictions are between 0.51 and 0.49, a threshold of 0.6 would push all results to dog.
Test this by printing raw probabilities for a known cat and dog image:
cat_pred = model.predict(preprocess("test_cat.jpg")) dog_pred = model.predict(preprocess("test_dog.jpg")) print("Cat image prediction:", cat_pred) print("Dog image prediction:", dog_pred)
If these probabilities are lopsided (e.g., both show [0.9, 0.1]), preprocessing is the issue. If they look correct but your code outputs the same class, fix your post-processing logic.
3. Model Generalization Issues
80% training accuracy doesn't always mean the model learned meaningful features—it might be overfitting to training data, or underfitting entirely.
- Check validation accuracy: Did you use a validation set during training? If validation accuracy is way lower than training accuracy (e.g., 50% vs 80%), your model is overfitting. Fix this by adding Dropout layers, reducing model size, or increasing data augmentation.
- Training data diversity: Is your training set small or unbalanced? If you have way more cats than dogs, the model might just default to predicting cat for everything to get high accuracy. Make sure your training data is balanced, and use augmentation to add variety.
4. Test Data Loading Mistakes
Double-check that your test data is actually a mix of cats and dogs! It sounds silly, but it's easy to accidentally load a folder full of only one class (e.g., wrong file path, or test set wasn't split correctly).
Start with the preprocessing check—it's the most likely fix. Once you verify that, move to checking prediction outputs and model generalization.
内容的提问来源于stack exchange,提问作者vidit02100

