如何在Keras中结合图像文件夹与含分类信息的Excel训练CNN
Got it, let's walk through this step by step—this is a standard computer vision workflow, so you're already set up with the right ingredients (images + labeled data). Here's how to tie everything together for your CNN training:
1. First: Map Image Files to Excel Labels
First, you need to link each image to its corresponding label from the Excel sheet. Let's assume your Excel has columns like image_id (matching the filename of your images, e.g., 123.jpg maps to image_id=123) and label (your two classes, say 0/1 or "cat"/"dog").
- Use
pandasto load your Excel data and create image path mappings:import pandas as pd import os # Load the Excel file df = pd.read_excel("your_labels.xlsx") # Add a column for the full image path (adjust the folder path to your images) df["image_path"] = df["image_id"].apply(lambda x: f"your_image_folder/{x}.jpg") # Double-check for missing images (critical to avoid training errors) df["exists"] = df["image_path"].apply(os.path.exists) print(f"Missing images: {len(df[~df['exists']])}") df = df[df["exists"]] # Drop rows with missing images
2. Load Data into Keras (Two Common Approaches)
You have two straightforward options to feed this labeled data into Keras—pick the one that fits your needs:
Option A: Use ImageDataGenerator with flow_from_dataframe (Simplest)
This is great if you want built-in data augmentation and easy batching:
from tensorflow.keras.preprocessing.image import ImageDataGenerator from sklearn.model_selection import train_test_split # Split your data into training and validation sets (80-20 split, stratified to preserve class balance) train_df, val_df = train_test_split(df, test_size=0.2, random_state=42, stratify=df["label"]) # Initialize data generators (add augmentation only for training!) train_datagen = ImageDataGenerator( rescale=1./255, rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, horizontal_flip=True ) val_datagen = ImageDataGenerator(rescale=1./255) # Only rescale for validation # Create training generator train_generator = train_datagen.flow_from_dataframe( dataframe=train_df, x_col="image_path", y_col="label", target_size=(224, 224), # Adjust to your desired input size batch_size=32, class_mode="binary" # Use "categorical" if you had more than 2 classes ) # Create validation generator val_generator = val_datagen.flow_from_dataframe( dataframe=val_df, x_col="image_path", y_col="label", target_size=(224, 224), batch_size=32, class_mode="binary" )
Option B: Use tf.data.Dataset (More Flexible)
If you need custom preprocessing logic or want better control over your data pipeline:
import tensorflow as tf # Extract lists of image paths and labels train_paths = train_df["image_path"].tolist() train_labels = train_df["label"].tolist() val_paths = val_df["image_path"].tolist() val_labels = val_df["label"].tolist() # Define a preprocessing function def preprocess_image(path, label): # Load and decode image img = tf.io.read_file(path) img = tf.image.decode_jpeg(img, channels=3) # Use decode_png if your images are PNG # Resize to target size img = tf.image.resize(img, (224, 224)) # Normalize pixel values to [0,1] img = img / 255.0 # Add training-only data augmentation if tf.keras.backend.learning_phase(): img = tf.image.random_flip_left_right(img) img = tf.image.random_brightness(img, max_delta=0.2) return img, label # Build training dataset train_dataset = tf.data.Dataset.from_tensor_slices((train_paths, train_labels)) train_dataset = train_dataset.map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) train_dataset = train_dataset.shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE) # Build validation dataset val_dataset = tf.data.Dataset.from_tensor_slices((val_paths, val_labels)) val_dataset = val_dataset.map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) val_dataset = val_dataset.batch(32).prefetch(tf.data.AUTOTUNE)
3. Build and Train Your CNN Model
Now that your data is ready, build a simple CNN (adjust layers based on your task complexity):
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout model = Sequential([ Conv2D(32, (3, 3), activation="relu", input_shape=(224, 224, 3)), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activation="relu"), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation="relu"), MaxPooling2D((2, 2)), Flatten(), Dense(128, activation="relu"), Dropout(0.5), # Prevent overfitting Dense(1, activation="sigmoid") # Binary classification output ]) # Compile the model model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"]) # Train the model history = model.fit( train_generator, # Swap with train_dataset if you used Option B epochs=20, validation_data=val_generator # Swap with val_dataset if you used Option B )
Quick Tips to Avoid Headaches
- Check Label Consistency: Make sure your Excel labels are either integers (0/1) or strings—Keras will handle both, but stay consistent.
- Image Size: 224x224 is a standard size that works with most pre-trained models if you ever want to fine-tune later.
- Class Balance: If one class has way more images than the other, use
class_weightinmodel.fit(e.g.,class_weight={0: 1.5, 1: 0.8}) to balance the loss. - Save Progress: Use
model.save()after training to save your model for later use.
内容的提问来源于stack exchange,提问作者Aritra Sen

