共计 2460 个字符,预计需要花费 7 分钟才能阅读完成。
为什么 GAN 训练的第一步总是数据集?
刚入门 GAN 时,很多同学会直接拿 MNIST 练手,但切换到真实项目就发现:现成数据集和实际需求差距巨大。我踩过的坑主要有三个:

- 图像尺寸五花八门(有的 1080p 有的 640×480)
- 样本类别严重不均衡(某些类别只有几十张)
- 标注质量参差不齐(错误标签比没标签更可怕)
现成数据集 vs 自定义数据集
| 对比维度 | MNIST/CIFAR-10 | 自定义数据集 |
|---|---|---|
| 数据质量 | 清洗完善 | 需自行预处理 |
| 适用场景 | 算法验证 | 真实业务场景 |
| 扩展性 | 固定不可变 | 可灵活增强 |
| 计算成本 | 加载快 | 需优化 IO pipeline |
手把手构建 chapter04 数据集
1. 生成合成数据(Python 实现)
# 环境要求:Python 3.8+ / NumPy 1.20+
import numpy as np
from typing import Tuple
def generate_fake_data(
num_samples: int = 1000,
img_size: Tuple[int, int] = (64, 64)
) -> np.ndarray:
"""
生成随机噪声图像数据集
Args:
num_samples: 生成样本数
img_size: 图像尺寸 (H, W)
Returns:
np.ndarray: 形状为 (N, H, W, 3) 的 RGB 图像数组
"""
return np.random.randint(
0, 256,
size=(num_samples, *img_size, 3),
dtype=np.uint8
)
2. OpenCV 预处理流水线
关键步骤拆解:
- 统一缩放到 64×64 像素
- 转换到 [-1,1] 的归一化范围
- 随机水平翻转增强
import cv2
def preprocess_image(
img: np.ndarray,
augment: bool = True
) -> np.ndarray:
"""
标准化图像处理流程
Args:
img: 输入 BGR 图像 (H,W,3)
augment: 是否启用数据增强
Returns:
np.ndarray: 归一化后的 RGB 图像
"""
# 尺寸标准化
img = cv2.resize(img, (64, 64))
# BGR 转 RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 数据增强
if augment and np.random.rand() > 0.5:
img = cv2.flip(img, 1)
# 归一化到[-1,1]
return (img / 127.5) - 1.0
双框架数据加载实现
TensorFlow Dataset API 版
# 环境:TF 2.6+
import tensorflow as tf
def build_tf_dataset(
image_dir: str,
batch_size: int = 32
) -> tf.data.Dataset:
"""
构建 TF 数据管道
Args:
image_dir: 图像文件夹路径
batch_size: 批次大小
Returns:
tf.data.Dataset: 可迭代数据集
"""
def parse_image(filename):
img = tf.io.read_file(filename)
img = tf.image.decode_jpeg(img, channels=3)
return tf.image.resize(img, [64, 64])
filelist = tf.data.Dataset.list_files(f"{image_dir}/*.jpg")
return filelist.map(parse_image).batch(batch_size).prefetch(2)
PyTorch DataLoader 版
# 环境:torch 1.9+
from torch.utils.data import Dataset, DataLoader
class CustomDataset(Dataset):
def __init__(self, image_dir: str):
self.image_paths = [f for f in Path(image_dir).glob('*.jpg')]
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
img = cv2.imread(str(self.image_paths[idx]))
return preprocess_image(img)
# 使用示例
dataloader = DataLoader(CustomDataset("path/to/images"),
batch_size=32,
num_workers=4
)
新手避坑指南
内存泄漏陷阱
错误写法:
for batch in dataset: # 会持续累积计算图
train_step(batch)
正确写法:
for batch in iter(dataset): # 显式创建迭代器
train_step(batch)
多 GPU 数据分片
# 每个 GPU 只处理部分数据
dataset = dataset.shard(
num_shards=num_gpus,
index=gpu_index
)
标签平滑实现
# 原始标签:one-hot [0, 1]
smoothed_labels = labels * (1 - 0.1) + 0.1 / num_classes
性能优化实战
测试对比 10000 张 64×64 图像:
| 存储方式 | 加载耗时 | 内存占用 |
|---|---|---|
| 直接读 JPEG | 2.3s | 1.2GB |
| HDF5 单文件 | 0.4s | 0.8GB |
| TFRecords | 0.7s | 0.9GB |
动手实践任务
尝试修改噪声生成函数:
def noisy_data_generator():
# 将均匀分布改为高斯分布
return np.random.normal(loc=0.5, scale=0.2, size=(64,64,3))
观察生成图像的质量变化,思考:
1. 不同分布对 GAN 训练有何影响?
2. 如何控制噪声的多样性程度?
总结心得
构建高质量数据集比模型调参更重要。建议:
– 小规模数据先用 HDF5 存储
– 预处理流水线要封装成可复用组件
– 始终监控数据分布是否偏移
下次我们聊聊如何用 StyleGAN2 生成更逼真的图像。
正文完
发表至: 未分类
近两天内
