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

基于Keras的CNN训练准确率停滞在约1/n%,求助问题排查

Troubleshooting Low Accuracy (18-19%) in Your 5-Class Vegetable CNN Classification Model

Hey Ben, let's break down why your CNN is stuck at ~19% accuracy for 5-class vegetable classification—this is a common issue with small datasets, so let's go through the most likely culprits and fixes:

1. Dataset Size & Distribution: The Biggest Red Flag

200 total images split across 5 classes means only ~40 images per class. That's way too little data for a CNN to learn meaningful, generalizable features. Your model is basically guessing randomly (5 classes = 20% random accuracy), which aligns perfectly with your current results.

Fixes:

  • Add aggressive data augmentation: Use Keras' ImageDataGenerator to generate synthetic variations of your existing images. This effectively expands your dataset without collecting new photos. Example code:
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    
    datagen = ImageDataGenerator(
        rotation_range=30,          # Rotate images up to 30 degrees
        width_shift_range=0.2,      # Shift horizontally by 20% of width
        height_shift_range=0.2,     # Shift vertically by 20% of height
        horizontal_flip=True,       # Flip images horizontally
        zoom_range=0.2,             # Zoom in/out by 20%
        brightness_range=[0.7, 1.3],# Adjust brightness
        fill_mode='nearest'         # Fill empty pixels after transformations
    )
    
  • Check class balance: Ensure no class has drastically fewer images than others (e.g., one class with 10 images vs. others with 50). If so, either collect more data for the underrepresented class or use weighted loss (class_weight parameter in model.fit()) to compensate.
  • Verify train/validation split: Make sure you're using a stratified split (preserves class distribution) instead of random split. For example, 80% train / 20% validation should have ~32 images per class in training, ~8 in validation.

2. Model Structure Issues

Your model might be either too shallow (can't extract enough features) or too deep (overfits the tiny dataset instantly).

Fixes:

  • Start with a lightweight, pre-trained model (transfer learning): Instead of building a CNN from scratch, use transfer learning with models like MobileNetV2 or EfficientNetB0. These models are pre-trained on millions of images and can adapt to your small dataset quickly. Example snippet:
    from tensorflow.keras.applications import MobileNetV2
    from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
    from tensorflow.keras.models import Model
    
    base_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(224,224,3))
    # Freeze base model initially
    base_model.trainable = False
    
    x = base_model.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(128, activation='relu')(x)
    predictions = Dense(5, activation='softmax')(x)
    
    model = Model(inputs=base_model.input, outputs=predictions)
    
  • Add regularization if building from scratch: If you want a custom CNN, add Dropout layers and L2 regularization to prevent overfitting:
    from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense
    from tensorflow.keras.regularizers import l2
    
    model = Sequential([
        Conv2D(32, (3,3), activation='relu', input_shape=(128,128,3), kernel_regularizer=l2(0.001)),
        MaxPooling2D((2,2)),
        Dropout(0.25),
        Conv2D(64, (3,3), activation='relu', kernel_regularizer=l2(0.001)),
        MaxPooling2D((2,2)),
        Dropout(0.25),
        Flatten(),
        Dense(128, activation='relu', kernel_regularizer=l2(0.001)),
        Dropout(0.5),
        Dense(5, activation='softmax')
    ])
    
  • Double-check output layer: Ensure your output layer uses softmax activation (for multi-class classification) and your loss function matches your label format:
    • Use sparse_categorical_crossentropy if labels are integer values (e.g., 0,1,2,3,4)
    • Use categorical_crossentropy if labels are one-hot encoded (e.g., [1,0,0,0,0])

3. Training Strategy Missteps

You mentioned tuning optimizer LR and decay, but there are other critical training details to check:

Fixes:

  • Correct step count: You noted 800 steps ×30 epochs, but with a batch size of 32 and 200 total images, your training set (80% = 160 images) should have only 160 // 32 = 5 steps per epoch. Setting 800 steps means you're repeatedly feeding the same small dataset hundreds of times per epoch—this leads to overfitting to noise, not meaningful features. Always set steps to train_samples // batch_size, or let Keras calculate it automatically if using flow_from_directory.
  • Use learning rate scheduling: Instead of manually tuning LR, use a scheduler to adjust it during training. For example, ReduceLROnPlateau lowers LR when validation accuracy plateaus:
    from tensorflow.keras.callbacks import ReduceLROnPlateau
    
    lr_scheduler = ReduceLROnPlateau(
        monitor='val_accuracy',
        factor=0.5,          # Halve LR when triggered
        patience=3,          # Wait 3 epochs with no improvement
        min_lr=1e-6          # Minimum LR to avoid stopping learning
    )
    # Add to model.fit() callbacks
    model.fit(..., callbacks=[lr_scheduler])
    
  • Monitor validation accuracy: Always track val_accuracy alongside accuracy. If training accuracy is high but validation is low, you're overfitting. If both are low (like your case), you're underfitting—meaning your model isn't learning enough from the tiny dataset (hence the need for data augmentation or transfer learning).

4. Data Preprocessing Errors

Even small preprocessing mistakes can derail your model:

Fixes:

  • Normalize pixel values: Scale image pixels to the range [0,1] by dividing by 255.0. CNNs converge much faster on normalized data.
  • Ensure consistent image size: All input images must match the input shape defined in your model (e.g., (224,224,3)). Use ImageDataGenerator's target_size parameter to resize images automatically.
  • Validate label correctness: Double-check that your image labels are accurate—mislabeled data (e.g., a carrot labeled as broccoli) will make it impossible for the model to learn correctly.

Start with the dataset fixes (data augmentation + stratified split) first—this will have the biggest impact. Then move to transfer learning if building from scratch isn't working.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:00:50