基于CNN的10类不平衡数据分类:加权后F1值无提升求助
Hey there! Let's dig into why your class weighting approaches aren't boosting the F1-score—even with a validation accuracy over 98%—and walk through actionable fixes for your 10-class imbalanced classification task.
First, Let's Understand the Paradox: High Accuracy, Low F1
Accuracy can be wildly misleading with imbalanced data. If most of your samples belong to a handful of majority classes, your model can nail those easy predictions and score a sky-high accuracy while completely failing on underrepresented minority classes. The F1-score, however, measures the harmonic mean of precision and recall across all classes—so it’s far more sensitive to how well your model handles those overlooked groups. That 98% accuracy is almost certainly being driven by your majority classes, while the minority ones are still struggling.
Check If Your Class Weights Are Actually Working
Let’s start with the basics: make sure your weighting logic is correctly applied to the right classes.
For Method 1:
counter = Counter(training_set.classes) max_val = float(max(counter.values())) class_weights = {class_id: max_val/num_images for class_id, num_images in counter.items()}
- Double-check that
training_set.classesuses the exact same class IDs as your model’s output layer. If your dataset’s class indices are mismatched with the model’s neuron order (e.g., model expects class 0 to be "bird" but your dataset labels "bird" as class 5), the weights will be assigned to the wrong classes entirely. - Confirm you’re passing this
class_weightsdictionary directly tomodel.fit(class_weight=class_weights)—no typos or missing arguments here!
For Method 2:
from sklearn.utils import class_weight import numpy as np class_weights = class_weight.compute_class_weight( 'balanced', np.unique(training_set.classes), training_set.classes )
- The
compute_class_weightfunction returns an array where the index corresponds to the class ID. If your class IDs aren’t consecutive integers starting at 0 (e.g., you have IDs like 1,2,...10), this array will misalign with your model’s class order. Fix this by converting it to a dictionary:class_weight_dict = dict(zip(np.unique(training_set.classes), class_weights)) - Again, make sure you’re passing this dictionary (not the raw array) to
model.fit()unless your class IDs are strictly 0-9.
Beyond Class Weights: Fixes to Boost F1-Score
If your weights are correctly applied but F1 still isn’t improving, try these targeted strategies:
- Switch to Focal Loss: Cross-entropy loss treats all misclassifications equally, but focal loss down-weights easy-to-classify majority samples and focuses on hard minority ones. Implement it for categorical labels like this:
import tensorflow.keras.backend as K def focal_loss(gamma=2., alpha=1.): gamma = float(gamma) alpha = float(alpha) def focal_loss_fixed(y_true, y_pred): epsilon = 1e-8 y_pred = K.clip(y_pred, epsilon, 1. - epsilon) cross_entropy = -y_true * K.log(y_pred) weight = alpha * y_true * K.pow((1 - y_pred), gamma) loss = weight * cross_entropy return K.sum(loss, axis=-1) return focal_loss_fixed # Use in model compilation model.compile(optimizer='adam', loss=focal_loss(gamma=2, alpha=1), metrics=['accuracy']) - Targeted Data Augmentation: Apply aggressive augmentation (rotations, flips, zooms, brightness shifts) only to minority class samples to artificially boost their representation. Avoid over-augmenting majority classes to prevent overfitting.
- Oversample Minority Classes: Use synthetic sample generation (like SMOTE for tabular data, or custom image synthesis for visual data) to create additional minority samples. Critical note: only apply this to your training set—never your validation/test set!
- Analyze Class-Specific Metrics: Generate a full classification report (not just a confusion matrix) to see exactly which minority classes have low precision/recall. For example, if Class 7 has a recall of 0, you might need to collect more real samples, augment existing ones, or crank up its class weight even further.
- Adjust Training Dynamics: If your model is overfitting to majority classes, add more dropout layers, reduce model size, or use early stopping based on validation F1-score (instead of accuracy) to halt training when minority class performance stops improving.
Final Check: Validate Your Evaluation Pipeline
Make sure you’re calculating F1-score correctly! Use sklearn.metrics.f1_score with average='weighted' (accounts for class imbalance) or 'macro' (treats all classes equally). Avoid average='binary'—it’s designed for two-class tasks, not your 10-class problem.
内容的提问来源于stack exchange,提问作者AK_AI

