咨询:Keras ImageDataGenerator非加法操作下扩展汽车图像训练集的方法
Got it, let's break down how you can expand your car image dataset and combine original + augmented data for training, since Keras' ImageDataGenerator doesn't natively return both together. Here are three practical approaches:
1. Offline Augmentation: Generate and Save Augmented Images to Disk
This is the most straightforward method—you pre-generate augmented versions of your original images, save them to the same class-specific folders as your raw data, then train your model on the combined dataset.
Steps:
- Initialize
ImageDataGeneratorwith your desired augmentation parameters (rotation, shift, flip, etc.). - Use
flow_from_directory(if your images are organized by class folders) and specifysave_to_dirto store augmented images. - Generate enough augmented samples to expand your dataset (e.g., 3-5 augmented images per original).
Code Example:
from tensorflow.keras.preprocessing.image import ImageDataGenerator import os # Set up augmentation parameters tailored to car images datagen = ImageDataGenerator( rotation_range=15, width_shift_range=0.1, height_shift_range=0.1, zoom_range=0.1, horizontal_flip=True, fill_mode='nearest' ) # Assume original images live in ./train/{class_name}/ generator = datagen.flow_from_directory( './train/', target_size=(224, 224), batch_size=32, class_mode='categorical', save_to_dir='./train/', # Save augmented images directly into original class folders save_prefix='aug_', save_format='jpg' ) # Generate 5x augmented images for every original image total_original = sum(len(files) for _, _, files in os.walk('./train/')) total_augmented = total_original * 5 for _ in range(total_augmented // generator.batch_size): generator.next()
After this, your ./train/ folders will contain both original and augmented images. You can then use a standard ImageDataGenerator (even without augmentation, or with light preprocessing) to load the full dataset for training.
2. Custom Data Generator: Return Original + Augmented Data in Real-Time
If you don't want to clog up disk space, build a custom Sequence generator that loads original images, generates augmented versions on-the-fly, and returns a batch containing both.
Code Example:
from tensorflow.keras.utils import Sequence import numpy as np import cv2 import os class CombinedAugmentGenerator(Sequence): def __init__(self, image_dir, target_size=(224,224), batch_size=32, augmenter=None): self.image_dir = image_dir self.target_size = target_size self.batch_size = batch_size self.augmenter = augmenter # Load image paths and labels (adjust based on your folder structure) self.image_paths = [] self.labels = [] self.class_map = {cls: idx for idx, cls in enumerate(os.listdir(image_dir))} for cls in os.listdir(image_dir): cls_path = os.path.join(image_dir, cls) for img_name in os.listdir(cls_path): self.image_paths.append(os.path.join(cls_path, img_name)) self.labels.append(self.class_map[cls]) self.labels = np.array(self.labels) def __len__(self): return int(np.ceil(len(self.image_paths) / self.batch_size)) def __getitem__(self, idx): # Fetch batch of original images batch_paths = self.image_paths[idx*self.batch_size : (idx+1)*self.batch_size] batch_labels = self.labels[idx*self.batch_size : (idx+1)*self.batch_size] # Load and preprocess original images original_imgs = [] for path in batch_paths: img = cv2.imread(path) img = cv2.resize(img, self.target_size) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) / 255.0 original_imgs.append(img) original_imgs = np.array(original_imgs) # Generate augmented versions augmented_imgs = self.augmenter.random_transform(original_imgs) # Combine original + augmented data combined_imgs = np.concatenate([original_imgs, augmented_imgs], axis=0) combined_labels = np.concatenate([batch_labels, batch_labels], axis=0) return combined_imgs, combined_labels # Usage augmenter = ImageDataGenerator( rotation_range=15, horizontal_flip=True, zoom_range=0.1 ) train_generator = CombinedAugmentGenerator( image_dir='./train/', target_size=(224,224), batch_size=32, augmenter=augmenter ) # Train your model with the generator # model.fit(train_generator, epochs=10, ...)
3. Use tf.data.Dataset to Merge Original and Augmented Streams
For TensorFlow users, the tf.data API lets you create two parallel datasets (one raw, one augmented) and concatenate them for training.
Code Example:
import tensorflow as tf import os def load_image(path, label, target_size=(224,224)): img = tf.io.read_file(path) img = tf.image.decode_jpeg(img, channels=3) img = tf.image.resize(img, target_size) return img / 255.0, label def augment(img, label): # Apply car-safe augmentations img = tf.image.random_flip_left_right(img) img = tf.image.random_brightness(img, max_delta=0.1) img = tf.image.random_rotation(img, factor=0.1) return img, label # Load original dataset image_paths = tf.data.Dataset.list_files('./train/*/*.jpg', shuffle=False) class_names = os.listdir('./train/') class_map = {cls: idx for idx, cls in enumerate(class_names)} # Extract labels from folder structure labels = tf.data.Dataset.from_tensor_slices( [class_map[os.path.basename(os.path.dirname(path.numpy()))] for path in image_paths] ) original_ds = tf.data.Dataset.zip((image_paths, labels)) original_ds = original_ds.map(load_image, num_parallel_calls=tf.data.AUTOTUNE) # Create augmented dataset augmented_ds = original_ds.map(augment, num_parallel_calls=tf.data.AUTOTUNE) # Merge and prepare training dataset combined_ds = original_ds.concatenate(augmented_ds) combined_ds = combined_ds.shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE) # Train your model # model.fit(combined_ds, epochs=10, ...)
Quick Notes:
- For offline augmentation, avoid over-augmenting (e.g., don't generate 20x images per original) to prevent overfitting to distorted samples.
- When using real-time methods, ensure your augmentations are relevant to car images—skip vertical flips, limit rotation angles, etc.
- All three methods let you train on the full combined dataset of original + augmented images, which should boost your model's generalization.
内容的提问来源于stack exchange,提问作者nikki

