当前位置: 首页 > news >正文

【机器学习深度学习】数据预处理

目录

一、数据预处理的目的是什么?

二、数据预处理示例

2.1 示例代码

2.2 运行结果

2.3 代码解析

2.3.1 自定义数据集 CustomDataset

2.3.2 创建模拟数据

2.3.3 定义数据增强(transform)

2.3.4 构建数据集 + DataLoader

2.3.5 数据加载

2.3.6 TensorDataset 的简化用法(适合非图像数据)

三、总结口诀


一、数据预处理的目的是什么?

把原始数据 → 变成模型可训练格式:张量形式,标准大小,归一化,增强(如翻转/旋转)


二、数据预处理示例

2.1 示例代码

import torch
import numpy as np
from torch.utils.data import Dataset, DataLoader, TensorDataset
from torchvision import transforms
# ==============================
# 数据预处理(将数据处理成模型可输入的形状)
# ==============================
print("\n" + "=" * 50)
print("数据预处理示例")
print("=" * 50)# 自定义数据集类
class CustomDataset(Dataset):def __init__(self, data, targets, transform=None):self.data = dataself.targets = targetsself.transform = transformdef __len__(self):return len(self.data)def __getitem__(self, idx):sample = self.data[idx]label = self.targets[idx]if self.transform:sample = self.transform(sample)return sample, label# 创建模拟数据
num_samples = 100
data = np.random.randn(num_samples, 3, 32, 32)  # 100张32x32的RGB图像
targets = np.random.randint(0, 10, num_samples)  # 0-9的标签# 定义转换管道
transform = transforms.Compose([transforms.ToTensor(),  # 转为张量transforms.Normalize((0.5,), (0.5,)),  # 标准化transforms.RandomHorizontalFlip(),  # 随机水平翻转transforms.RandomRotation(15)  # 随机旋转±15度
])# 创建数据集和数据加载器
dataset = CustomDataset(data, targets, transform=transform)
dataloader = DataLoader(dataset, batch_size=16, shuffle=True, num_workers=0)# 演示数据加载
print(f"数据集大小: {len(dataset)}")
batch = next(iter(dataloader))
print(f"批数据形状: 输入={batch[0].shape}, 标签={batch[1].shape}")# 使用TensorDataset的简化方法
tensor_x = torch.randn(100, 5)  # 特征
tensor_y = torch.randint(0, 2, (100,))  # 二分类标签
tensor_dataset = TensorDataset(tensor_x, tensor_y)
dataloader_simple = DataLoader(tensor_dataset, batch_size=10, shuffle=True)#print(f"批数据形状: 输入={batch[0].shape}, 标签={batch[1].shape}")

2.2 运行结果

==================================================
数据预处理示例
==================================================
数据集大小: 100
批数据形状: 输入=torch.Size([16, 32, 3, 32]), 标签=torch.Size([16])

2.3 代码解析

2.3.1 自定义数据集 CustomDataset

Dataset 子类,它是 PyTorch 数据加载的标准做法

# 自定义数据集类
class CustomDataset(Dataset):def __init__(self, data, targets, transform=None):self.data = data               # 原始数据(图像等)self.targets = targets         # 标签(分类结果)self.transform = transform     # 预处理方法(可以为 None)def __len__(self):return len(self.data)          # 数据集中样本个数def __getitem__(self, idx):sample = self.data[idx]        # 第 idx 个图像label = self.targets[idx]      # 对应标签if self.transform:sample = self.transform(sample)  # 应用 transformreturn sample, label

它的作用就是:
✔ 把你的数据 data(比如图片)和 targets(比如标签)装进一个可迭代对象
✔ 在训练时,按批(batch)从中抽出样本

▲ def __init__(self, data, targets, transform=None)

定义

▲def __len__(self)

def __len__(self):return len(self.data)

计算数据长度

▲def __getitem__(self, idx)

def __getitem__(self, idx):sample = self.data[idx]label = self.targets[idx]if self.transform:sample = self.transform(sample)return sample, label

sample = self.data[idx]

  • self.data 中取出第 idx 个样本

  • 假设 self.data 是一个形状 [100, 3, 32, 32] 的数组(100张图片),那么这个就是取出第 idx 张图片

  • 类型:通常是 ndarray 或张量

label = self.targets[idx]

  • self.targets 中取出对应的标签

  • 比如,如果是图像分类,targets 就是 [0, 1, 5, 3, ...] 等类别编号

  • 所以你现在得到的是一对:
    ✔ 一张图片
    ✔ 一个标签

if self.transform:

  • 判断你有没有设置 transform

  • transform 是你传入的转换管道,例如:

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))
])

 

sample = self.transform(sample)

  • 如果设置了 transform,就用它来“处理样本”,比如:

    • 转为 PyTorch 张量

    • 做归一化

    • 数据增强(随机翻转、旋转等)

📌 注意:标签 label 通常不做 transform,只处理 sample

return sample, label

  • 最后,返回处理后的 (样本, 标签)

  • DataLoader 会调用这个方法一次次地取出 batch,例如:

for batch in dataloader:x, y = batch  # x 是样本数据,y 是标签

2.3.2 创建模拟数据
data = np.random.randn(100, 3, 32, 32)
targets = np.random.randint(0, 10, 100)

模拟了:

  • 100张 32×32 的RGB图像(3通道)→ shape=(100, 3, 32, 32)

  • 100个标签,范围在 0~9(多分类)


2.3.3 定义数据增强(transform)

transforms.Compose([...])

是用来 把多个图像变换步骤“串起来”依次执行 的。

就像你做图像预处理的“流水线”——每个步骤按顺序处理图像。

transform = transforms.Compose([transforms.ToTensor(),               # ① 转换为张量transforms.Normalize((0.5,), (0.5,)),# ② 标准化transforms.RandomHorizontalFlip(),   # ③ 数据增强transforms.RandomRotation(15)        # ④ 数据增强
])

每个步骤含义:

步骤作用
ToTensor()把图片/数组转成 PyTorch 张量
Normalize((0.5,), (0.5,))将像素值标准化(减均值除方差)
RandomHorizontalFlip()以 50% 概率将图像左右翻转(数据增强)
RandomRotation(15)随机旋转 ±15 度(模拟不同角度)

是对图像数据进行预处理和增强的过程,目的是为了:

✅ 把原始图像变成模型可以理解的格式
✅ 增强数据多样性,让模型更强健、泛化更好

✅ 最终的作用:

让你的训练模型更健壮:

  • 能接受输入是张量

  • 像素值范围适合网络

  • 不容易被方向、角度小变化干扰

  • 在数据不多时有效“制造更多样本”

📌 为啥图像训练前要 transform?

深度学习模型不能直接处理图像(像素),它只理解张量(tensor)!
而且模型容易“过拟合训练数据”,所以我们要用数据增强让它更健壮。

🔍 逐步解释每一行:

transforms.ToTensor()

把图像数据(PIL Image 或 NumPy 的 [H, W, C])变成 PyTorch 张量 [C, H, W],并自动把像素值从 [0, 255] 缩放到 [0.0, 1.0]

例子:

原图(HWC): uint8, [32, 32, 3], 像素0-255
→ 转为张量: float32, [3, 32, 32], 像素0.0-1.0

transforms.Normalize((0.5,), (0.5,))

对每个像素做标准化:$x' = \frac{x - 0.5}{0.5}$
等价于把像素从 [0, 1] 映射到 [-1, 1]

这么做的好处是:

  • 加快模型收敛速度

  • 避免某些神经元“激活太强”或“始终为零”

📌 如果是 RGB 图像,应该写成 (0.5, 0.5, 0.5),不是一个元素!


transforms.RandomHorizontalFlip()

以一定概率把图像水平翻转
举个例子:左手 → 右手

作用:增加训练数据的多样性,避免模型只学到“固定方向”


transforms.RandomRotation(15)

把图像随机旋转 ±15 度
例如:

  • 原图是“狗正面”

  • 旋转后变成“狗歪着头”

作用:提升模型对角度变化的鲁棒性


例图(视觉演示)

如果你要训练猫狗分类器:

原图水平翻转旋转15°
🐶 正面🐶 反方向🐶 歪头

这些都“看起来像狗”,但模型可能就不容易学到这些变化,如果不做 transform。

 

🧠 总结口诀

步骤作用
ToTensor()变成模型能吃的格式
Normalize()提升训练效率
RandomFlip/Rotate增强数据多样性,防止过拟合

2.3.4 构建数据集 + DataLoader
dataset = CustomDataset(data, targets, transform=transform)
dataloader = DataLoader(dataset, batch_size=16, shuffle=True)

DataLoader 会:

  • 每次给你一小批数据(batch_size=16)

  • 每次打乱顺序(shuffle=True)

  • 在内部调用你写的 __getitem__ 方法

  • 返回 (sample, label),也就是图片 + 标签

dataset = CustomDataset(data, targets, transform=transform)

 这行代码的意思是:

创建一个“自定义数据集对象”,将原始数据 data 和标签 targets 封装起来,
并设置了一个图像预处理管道 transform让你后续可以直接加载预处理后的数据

关键词说明
CustomDataset自定义数据集类,封装原始数据 + 标签
transform=...每次取数据时执行的数据预处理流程
__getitem__控制每次加载时具体怎么返回数据

 

dataloader = DataLoader(dataset, batch_size=16, shuffle=True)

 这行代码的作用是:

把你刚刚创建好的 dataset 数据集对象,分批次(每批16个样本)加载,
并在每个 epoch 前
打乱顺序
,返回一个支持迭代的“批数据提供器”。

 

🔹 DataLoader(...) 是什么?

PyTorch 提供的一个数据加载器,它能自动帮你:

  • 把数据集 Dataset 拆分成多个 batch(小批次)

  • 自动迭代取出每一个 batch(配合 fornext(iter(...)) 使用)

  • (可选)打乱数据顺序

  • (可选)多线程提速(num_workers 参数)

🔹 dataset

就是你传入的数据集对象(比如 CustomDataset(...)),它必须实现两个方法:

__len__      # 返回数据集长度
__getitem__  # 给定索引,返回 (样本, 标签)

🔹 batch_size=16

告诉 DataLoader:

“每次返回 16 个样本为一个批次(mini-batch)。”

这符合深度学习训练的常规方式——批量训练(不是一条一条,而是一批一批地训练)。

🔹 shuffle=True

告诉 DataLoader:

“在每个 epoch 开始前,把样本顺序打乱。”

为什么?

  • 避免模型学到“数据的顺序”而不是规律;

  • 提高泛化能力(尤其在数据顺序本身有偏差时);


 📊 举个例子:

假设你有 100 个训练样本,写了:

dataloader = DataLoader(dataset, batch_size=16, shuffle=True)

 那么:

  • 每次 next(iter(dataloader)) 就返回 16 条 (x, y)

  • 总共返回 7 次(最后一次只返回 4 条);

  • 每个 epoch 会重新打乱数据顺序后再分批次。

参数含义举例说明
dataset数据源(继承自 Dataset)你自己定义的 CustomDataset
batch_size=16每次加载 16 个样本即一个训练批次
shuffle=True每个 epoch 开始前打乱防止模型记住样本顺序

2.3.5 数据加载
# 演示数据加载
print(f"数据集大小: {len(dataset)}")
batch = next(iter(dataloader))
print(f"批数据形状: 输入={batch[0].shape}, 标签={batch[1].shape}")

 🔹 第一句:len(dataset)

print(f"数据集大小: {len(dataset)}")

 这会调用你 CustomDataset 类中定义的:

def __len__(self):return len(self.data)

 ✅ 输出的是:你有多少张图像数据(样本数量)。例如:100

🔹 第二句:batch = next(iter(dataloader))

这句可以分成两步理解:

iter(dataloader)

dataloader 变成一个迭代器对象,就像你写:

for batch in dataloader:

 它其实底层就是自动做了 iter(dataloader)

next(...)

从这个迭代器里“取出一个 batch”,也就是第一个小批量的数据。

🔍所以这一句整体意思是:

从 DataLoader 中拿出第一个 mini-batch(批数据),保存在变量 batch 里。

这个 batch 是一个元组,格式如下:

batch = (输入数据张量, 标签张量)
# 等价于
x = batch[0]
y = batch[1]


2.3.6 TensorDataset 的简化用法(适合非图像数据)
tensor_x = torch.randn(100, 5)           # 100个样本,每个5维特征
tensor_y = torch.randint(0, 2, (100,))   # 100个二分类标签(0或1)
tensor_dataset = TensorDataset(tensor_x, tensor_y)
dataloader_simple = DataLoader(tensor_dataset, batch_size=10)

这个版本适合:

  • 不需要 transform

  • 输入特征本身就是张量(如 tabular、嵌入、语音信号等)

✅ 最终输出:

print(f"批数据形状: 输入={batch[0].shape}, 标签={batch[1].shape}")

输出示例:

输入 = torch.Size([16, 3, 32, 32])
标签 = torch.Size([16])

代表:

  • 一批 16 张图像,每张是 3×32×32

  • 每张图像一个标签,长度为 16


语法作用
iter(dataloader)把数据加载器变成迭代器
next(...)从中取出一个 batch
batch = next(iter(...))获取一批样本+标签


三、总结口诀

  • 自定义 Dataset = 管理你原始数据结构

  • transform = 自动处理 & 数据增强

  • DataLoader = 批量送进模型

  • TensorDataset = 张量格式数据的快速封装

相关文章:

  • 苏州网络推广苏州网站建设郑州seo服务公司
  • 官网网站建设公司外包公司和劳务派遣
  • 大型网站建设公司 北京爱站小工具圣经
  • 网站开发需要怎么做百度做广告多少钱
  • PHP网站新闻发布怎么做网络营销公司排行榜
  • 对接标准做好门户网站建设百度代理授权查询
  • kanzi 视频插件
  • FFmpeg音视频同步思路
  • 计算机网络 网络层:控制平面(二)
  • 从零开始理解百度语音识别API的Python实现
  • Milvus中 Collections 级多租户 和 分区级多租户 的区别
  • C# .NET Framework 中的高效 MQTT 消息传递
  • 解密 C++ 中的左值(lvalue)与右值(rvalue)的核心内容
  • 命名数据网络 | 数据包(Data Packet)
  • docker 命令
  • 2-深度学习挖短线股-1-股票范围选择
  • 均值 ± 标准差的含义与计算方法‘; Likert 5 分制的定义与应用
  • 解锁AI无限潜能!景联文科技数据产品矩阵再升级:多语言题库、海量语料、垂域代码库,全面赋能大模型训练
  • PHP基础2(流程控制,函数)
  • 小程序入门:本地生活案例之首页九宫格布局渲染
  • 快速在手机上部署YOLOv10模型
  • MySQL备份和恢复
  • Linux——系统操作前言:冯诺依曼体系结构、全局理解操作系统
  • CSS 背景属性用于定义HTML元素的背景
  • GEO生成式引擎优化发展迅猛:热点数智化传播是GEO最佳路径
  • 3步精简Android11预装!瑞芯微开发板系统瘦身实战