2025/11/27每日总结 数据预处理全流程(含代码实现)—— 好数据才是模型的灵魂

数据预处理全流程(含代码实现)—— 好数据才是模型的灵魂

大家好!承接上一篇的数据集介绍,今天这篇咱们聚焦数据预处理——深度学习项目里最基础也最关键的一步。很多时候模型效果不好,不是架构设计得差,而是数据没处理到位。这篇我会把混凝土裂纹数据的预处理全流程拆解开,从目录构建到数据增强,每一步都附上可直接复用的代码,新手也能跟着做~

一、数据预处理的核心目标

先明确咱们做预处理的目的:

  1. 规范数据格式:让模型能顺利读取,避免因路径、尺寸、标签不一致导致训练报错;

  2. 优化数据分布:保证训练集、验证集、测试集的分布一致,避免模型评估失真;

  3. 提升模型泛化能力:通过数据增强模拟复杂场景,让模型不“挑食”,在实际工程中也能表现好;

  4. 加速模型收敛:通过归一化等操作,让模型参数更新更平稳,减少训练时间。

二、预处理全流程(附代码)

整个预处理过程我分成了6个关键步骤,用Python+TensorFlow实现,代码都经过实测,直接复制就能跑通~

1. 第一步:构建规范的数据目录

下载下来的原始数据集,文件夹名叫“Positive”(有裂纹)和“Negative”(无裂纹),直接用不够规范,而且要区分训练集、测试集,所以先构建清晰的目录结构。

代码实现:

import os
import shutil
import sys
# 配置路径参数
class Config:
RAW_DATA_DIR = 'crack_data' # 原始数据集路径(你下载的数据集存放目录)
PROCESSED_DATA_DIR = 'processed_crack_data' # 处理后的数据存放目录
# 类别映射:把原始文件夹名改成更直观的命名
CLASSES = {'Positive': 'crack', 'Negative': 'no_crack'}
# 每类样本的训练集、测试集数量(和上一篇的数据集划分一致)
TRAIN_SAMPLES_PER_CLASS = 10000
TEST_SAMPLES_PER_CLASS = 10000
def prepare_directory_structure():
"""创建训练集、测试集的目录结构"""
# 为训练集、测试集分别创建类别子目录
for split in ['train', 'test']:
for cls_name in Config.CLASSES.values():
cls_dir = os.path.join(Config.PROCESSED_DATA_DIR, split, cls_name)
os.makedirs(cls_dir, exist_ok=True) # 不存在则创建,存在则跳过
print("✅ 数据目录结构创建完成!")
# 执行目录创建
prepare_directory_structure()

最终目录结构:

processed_crack_data/
├─ train/
│ ├─ crack/ (训练集-有裂纹,10000张)
│ └─ no_crack/ (训练集-无裂纹,10000张)
└─ test/
├─ crack/ (测试集-有裂纹,10000张)
└─ no_crack/ (测试集-无裂纹,10000张)

2. 第二步:数据划分与复制

按照上一篇确定的划分规则,把原始数据复制到对应的目录下:训练集用前10000张正/负样本,测试集用10001-20000张。

代码实现:

def split_and_copy_data():
"""划分数据集并复制到对应目录"""
for raw_cls, target_cls in Config.CLASSES.items():
# 原始类别文件夹路径
raw_cls_path = os.path.join(Config.RAW_DATA_DIR, raw_cls)
if not os.path.exists(raw_cls_path):
print(f"❌ 错误:原始目录不存在 - {raw_cls_path}")
sys.exit(1)

获取该类别下所有图像文件(支持常见格式)

image_extensions = ('.jpg', '.jpeg', '.png', '.bmp')
all_images = [f for f in os.listdir(raw_cls_path) if f.lower().endswith(image_extensions)]
all_images.sort() # 排序保证划分顺序一致
total_images = len(all_images)

检查样本数量是否足够

required = Config.TRAIN_SAMPLES_PER_CLASS + Config.TEST_SAMPLES_PER_CLASS
if total_images < required:
print(f"❌ 错误:{raw_cls}类样本不足,需要至少{required}张,实际有{total_images}张")
sys.exit(1)

复制训练集样本(前10000张)

train_images = all_images[:Config.TRAIN_SAMPLES_PER_CLASS]
for img_name in train_images:
src = os.path.join(raw_cls_path, img_name)
dst = os.path.join(Config.PROCESSED_DATA_DIR, 'train', target_cls, img_name)
shutil.copy2(src, dst) # 保留文件元数据的复制

复制测试集样本(10001-20000张)

test_images = all_images[Config.TRAIN_SAMPLES_PER_CLASS:required]
for img_name in test_images:
src = os.path.join(raw_cls_path, img_name)
dst = os.path.join(Config.PROCESSED_DATA_DIR, 'test', target_cls, img_name)
shutil.copy2(src, dst)

print(f"✅ {raw_cls}类处理完成:训练集{len(train_images)}张,测试集{len(test_images)}张")

执行数据划分与复制

split_and_copy_data()

### 3. 第三步:图像加载与尺寸统一
虽然原始数据集已经是227×227像素,但加载时还是要明确指定尺寸,避免后续出现兼容问题。这里用TensorFlow的`ImageDataGenerator`批量加载,效率更高。
#### 代码实现:
```python
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
def load_datasets():
 """加载训练集、验证集、测试集"""
 # 图像参数
 IMG_HEIGHT = 227
 IMG_WIDTH = 227
 BATCH_SIZE = 32
 VALIDATION_SPLIT = 0.2 # 从训练集中划分20%作为验证集

# 训练集:需要数据增强,所以配置更多参数
 train_datagen = ImageDataGenerator(
 rescale=1./255, # 归一化(后续步骤详细说)
 validation_split=VALIDATION_SPLIT, # 划分验证集
 rotation_range=10, # 随机旋转±10°
 width_shift_range=0.1, # 水平偏移±10%
 height_shift_range=0.1, # 垂直偏移±10%
 zoom_range=0.1, # 随机缩放±10%
 horizontal_flip=True, # 水平翻转
 brightness_range=[0.9, 1.1] # 亮度调整0.9-1.1倍
 )

# 验证集和测试集:只需要归一化,不做数据增强(保持真实性)
 val_test_datagen = ImageDataGenerator(rescale=1./255)

# 加载训练集(subset='training'表示取训练部分)
 train_generator = train_datagen.flow_from_directory(
 directory=os.path.join(Config.PROCESSED_DATA_DIR, 'train'),
 target_size=(IMG_HEIGHT, IMG_WIDTH),
 batch_size=BATCH_SIZE,
 class_mode='binary', # 二分类任务,标签为0/1
 subset='training',
 seed=42 # 固定随机种子,保证结果可复现
 )

# 加载验证集(subset='validation'表示取验证部分)
 val_generator = train_datagen.flow_from_directory(
 directory=os.path.join(Config.PROCESSED_DATA_DIR, 'train'),
 target_size=(IMG_HEIGHT, IMG_WIDTH),
 batch_size=BATCH_SIZE,
 class_mode='binary',
 subset='validation',
 seed=42
 )

# 加载测试集
 test_generator = val_test_datagen.flow_from_directory(
 directory=os.path.join(Config.PROCESSED_DATA_DIR, 'test'),
 target_size=(IMG_HEIGHT, IMG_WIDTH),
 batch_size=BATCH_SIZE,
 class_mode='binary',
 shuffle=False, # 测试集不打乱,方便后续分析
 seed=42
 )

# 打印数据集信息
 print(f"\n📊 数据集统计:")
 print(f"训练集样本数:{train_generator.samples}")
 print(f"验证集样本数:{val_generator.samples}")
 print(f"测试集样本数:{test_generator.samples}")
 print(f"类别映射:{train_generator.class_indices}") # 查看0/1对应哪个类别

return train_generator, val_generator, test_generator
# 执行数据集加载
train_gen, val_gen, test_gen = load_datasets()

4. 第四步:数据归一化处理

图像像素值原本是0-255的整数,直接输入模型会导致参数更新波动过大,训练不稳定。归一化就是把像素值缩放到0-1的浮点数范围,只需要除以255即可。

关键说明:

  • 归一化的核心作用:加快模型收敛,让训练过程更平稳;

  • 注意事项:只对训练集、验证集、测试集做同样的归一化(除以255),不要用训练集的均值/方差做标准化(因为测试集是未知数据,不能提前泄露信息);

  • 代码里已经包含:rescale=1./255 就是归一化操作,不需要额外写代码。

    5. 第五步:验证集随机划分

    验证集是用来监控训练过程、调整超参数的,必须从训练集中随机划分,这样才能代表训练集的数据分布。

    关键细节:

  • 划分比例:20%(训练集20000张,验证集4000张);

  • 随机抽样:通过validation_split=0.2seed=42实现,固定seed保证每次划分结果一致;

  • 为什么不单独创建验证集目录?因为用ImageDataGeneratorsubset参数更灵活,后续调整比例时不用重新复制数据。

    6. 第六步:训练集数据增强(重点!)

    数据增强是提升模型泛化能力的关键手段,通过对训练集图像做随机变换,人为扩充样本多样性,让模型见过更多“变种”,从而在实际场景中表现更好。

    我用的增强策略(代码里已配置):

    增强方式 参数设置 作用
    随机旋转 rotation_range=10 适应不同拍摄角度的裂纹
    水平翻转 horizontal_flip=True 模拟左右对称的裂纹场景
    宽/高偏移 width/height_shift_range=0.1 适应裂纹在图像中不同位置
    随机缩放 zoom_range=0.1 适应不同拍摄距离的图像
    亮度调整 brightness_range=[0.9,1.1] 适应不同光照条件

    重要提醒:

  • 只对训练集做增强!验证集和测试集要保持原始状态,否则评估结果会失真;

  • 增强是“实时”的:训练时每次读取图像都会随机应用一种或多种变换,不会额外占用硬盘空间;

  • 增强强度要适度:比如旋转角度不要太大(我用10°),否则会改变裂纹的真实形态,导致模型学错特征。

    三、预处理常见问题排查

  1. 文件路径错误:确保RAW_DATA_DIR指向你下载的原始数据集目录,否则会提示“目录不存在”;

  2. 样本数量不足:原始数据集每类必须有20000张样本,不够的话可以减少TRAIN_SAMPLES_PER_CLASSTEST_SAMPLES_PER_CLASS的数量(比如各5000张);

  3. GPU内存不足:如果加载数据时提示GPU内存不够,把BATCH_SIZE调小(比如16);

  4. 中文路径报错:尽量把数据集放在无中文、无空格的路径下,避免TensorFlow读取失败。

四、小结

这篇博客详细讲解了混凝土裂纹数据的预处理全流程,从目录构建、数据划分,到尺寸统一、归一化,再到关键的Data Augmentation(数据增强),每一步都有对应的代码和原理说明。预处理完成后,我们就得到了“干净、规范、多样”的数据集,为下一步的CNN模型构建和训练打好了基础。

posted @ 2026-01-06 03:29  Moonbeamsc  阅读(9)  评论(0)    收藏  举报
返回顶端