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

不借助ImageDataGenerator实现Keras CNN训练的数据准备方法问询

嘿,我完全理解你想亲手实现数据加载和预处理的底层逻辑,而不是依赖ImageDataGenerator——这绝对是深入掌握Keras数据管道的好方式!下面我会一步步带你完成从数据加载、预处理到模型训练的全流程,全程不依赖ImageDataGenerator,完全手动实现。

手动实现Keras CNN训练(不依赖ImageDataGenerator)

1. 导入必要依赖

首先我们需要导入核心库,包括图像加载工具、数组处理库和Keras模型组件:

import os
import numpy as np
from keras.preprocessing.image import load_img, img_to_array
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split

2. 自定义数据加载函数

针对你的数据集结构(training_set/test_set下各有cats/dogs子文件夹),我们写一个通用的加载函数,负责遍历文件夹、加载图片、转换格式并生成标签:

def load_dataset(folder_path, target_size=(224, 224)):
    images = []
    labels = []
    # 遍历两个类别文件夹,cats对应标签0,dogs对应标签1
    for label, class_name in enumerate(['cats', 'dogs']):
        class_folder = os.path.join(folder_path, class_name)
        # 遍历当前类别下的所有图片
        for img_name in os.listdir(class_folder):
            img_path = os.path.join(class_folder, img_name)
            # 加载图片并统一尺寸
            img = load_img(img_path, target_size=target_size)
            # 转换为numpy数组(Keras模型需要numpy格式输入)
            img_array = img_to_array(img)
            # 归一化处理(和ImageDataGenerator的rescale=1./255效果一致)
            img_array /= 255.0
            images.append(img_array)
            labels.append(label)
    # 转为numpy数组返回
    return np.array(images), np.array(labels)

调用这个函数加载你的训练集和测试集:

# 替换为你实际的数据集路径
X_train, y_train = load_dataset('training_set')
X_test, y_test = load_dataset('test_set')

# 从训练集中拆分出验证集(按20%比例拆分)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)

3. 标签格式处理(可选)

如果要和ImageDataGenerator的class_mode='categorical'对齐,可以对标签做one-hot编码;如果用整数标签,后续训练时选择sparse_categorical_crossentropy损失函数即可:

# one-hot编码(二分类场景下可选)
y_train = to_categorical(y_train, num_classes=2)
y_val = to_categorical(y_val, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)

4. 构建CNN模型

我们搭建一个简单的VGG风格CNN模型,你可以根据需求调整层数和参数:

model = Sequential([
    # 卷积层1:32个3x3卷积核,ReLU激活
    Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
    MaxPooling2D((2, 2)),
    # 卷积层2:64个3x3卷积核
    Conv2D(64, (3, 3), activation='relu'),
    MaxPooling2D((2, 2)),
    # 卷积层3:128个3x3卷积核
    Conv2D(128, (3, 3), activation='relu'),
    MaxPooling2D((2, 2)),
    # 展平层:将多维特征转为一维
    Flatten(),
    # 全连接层
    Dense(128, activation='relu'),
    # 输出层:二分类用softmax(对应one-hot标签),或sigmoid
    Dense(2, activation='softmax')
])

# 编译模型
model.compile(optimizer='adam',
              loss='categorical_crossentropy',  # 用one-hot标签时选这个
              # loss='sparse_categorical_crossentropy',  # 用整数标签时选这个
              metrics=['accuracy'])

5. 训练模型

因为数据已经全部加载到内存,直接用model.fit训练即可:

history = model.fit(X_train, y_train,
                    epochs=10,
                    batch_size=32,
                    validation_data=(X_val, y_val))

6. 测试模型性能

训练完成后,在测试集上验证模型效果:

test_loss, test_acc = model.evaluate(X_test, y_test)
print(f'测试集准确率: {test_acc:.4f}')

7. 进阶:手动实现数据增强(模拟ImageDataGenerator核心功能)

如果你还想实现ImageDataGenerator的数据增强功能,可以手动写一个增强函数,并配合生成器实现批量训练(避免大内存占用):

import random
from keras.preprocessing.image import flip_axis, apply_affine_transform

def augment_image(img_array):
    # 随机水平翻转
    if random.random() > 0.5:
        img_array = flip_axis(img_array, 1)
    # 随机垂直翻转
    if random.random() > 0.5:
        img_array = flip_axis(img_array, 0)
    # 随机平移(±10像素)
    tx = random.randint(-10, 10)
    ty = random.randint(-10, 10)
    img_array = apply_affine_transform(img_array, tx=tx, ty=ty)
    return img_array

# 自定义数据生成器
def data_generator(X, y, batch_size=32, augment=False):
    while True:
        # 随机打乱数据索引
        indices = np.random.permutation(len(X))
        for i in range(0, len(X), batch_size):
            batch_indices = indices[i:i+batch_size]
            X_batch = X[batch_indices]
            y_batch = y[batch_indices]
            # 应用数据增强
            if augment:
                X_batch = np.array([augment_image(img) for img in X_batch])
            yield X_batch, y_batch

用生成器训练模型:

train_generator = data_generator(X_train, y_train, batch_size=32, augment=True)
val_generator = data_generator(X_val, y_val, batch_size=32)

history = model.fit(train_generator,
                    steps_per_epoch=len(X_train)//32,
                    epochs=10,
                    validation_data=val_generator,
                    validation_steps=len(X_val)//32)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:32:37