2026/4/19 10:46:03
网站建设
项目流程
视频网站建设类图,大型wordpress theme,网站制作公司下,贸易公司做网站怎么样浙大疏锦行
#x1f4d8; Day 38 实战作业#xff1a;数据流水线 —— Dataset 与 DataLoader
1. 作业综述
核心目标#xff1a;
Dataset (厨师)#xff1a;定义数据“长什么样”#xff0c;负责从硬盘读出一个个样本#xff0c;并进行预处理#xff08;切菜、洗菜浙大疏锦行 Day 38 实战作业数据流水线 —— Dataset 与 DataLoader1. 作业综述核心目标Dataset (厨师)定义数据“长什么样”负责从硬盘读出一个个样本并进行预处理切菜、洗菜。DataLoader (服务员)负责把处理好的菜打包Batching打乱顺序Shuffle然后端给模型GPU。实战对象MNIST 手写数字数据集60,000 张训练图10,000 张测试图。涉及知识点Torchvision:datasets.MNIST,transforms.核心类:torch.utils.data.Dataset(实现__len__,__getitem__)。加载器:torch.utils.data.DataLoader(实现batch_size,num_workers)。场景类比不使用 DataLoader: 像是吃自助餐一次性把所有菜数据全拿盘子里盘子显存装不下。使用 DataLoader: 像是吃回转寿司厨师Dataset不停做传送带DataLoader一盘盘Batch送到你面前吃完一盘来下一盘。步骤 1预处理与数据下载场景描述原始图片是 0-255 的像素值PIL Image 或 Numpy但 PyTorch 模型只吃[0, 1] 之间的浮点 Tensor。我们需要定义一个转换管道 (Transform Pipeline)。任务定义transforms转 Tensor 归一化 (Normalize)。下载 MNIST 数据集。importtorchfromtorch.utils.dataimportDataLoaderfromtorchvisionimportdatasets,transformsimportmatplotlib.pyplotasplt# 1. 定义预处理管道# ToTensor: [0, 255] - [0.0, 1.0] 增加 Channel 维度 (1, 28, 28)# Normalize: (x - mean) / std。MNIST 的均值是 0.1307标准差 0.3081transformtransforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))])print( 正在下载/加载数据集...)# 2. 加载数据集 (Dataset)# root: 存放路径# train: True训练集, False测试集# download: 没有就自动下载train_datasetdatasets.MNIST(root./data,trainTrue,downloadTrue,transformtransform)test_datasetdatasets.MNIST(root./data,trainFalse,downloadTrue,transformtransform)print(f✅ 训练集大小:{len(train_dataset)})print(f✅ 测试集大小:{len(test_dataset)}) 正在下载/加载数据集... 100%|██████████| 9.91M/9.91M [00:1800:00, 535kB/s] 100%|██████████| 28.9k/28.9k [00:0000:00, 167kB/s] 100%|██████████| 1.65M/1.65M [00:0100:00, 1.52MB/s] 100%|██████████| 4.54k/4.54k [00:0000:00, 1.73MB/s] ✅ 训练集大小: 60000 ✅ 测试集大小: 10000步骤 2深入 Dataset (厨师的手艺)核心原理train_dataset本质上是一个对象它实现了两个魔术方法__len__: 告诉我一共多少道菜。__getitem__(index): 给我做第 index 道菜。任务手动调用train_dataset[0]看看拿出来的是什么。将拿出来的 Tensor 还原成图片进行可视化。# --- 1. 像访问列表一样访问数据集 ---# 这会自动触发 __getitem__ 方法image,labeltrain_dataset[0]print(f样本形状:{image.shape})# (Channels, Height, Width) - (1, 28, 28)print(f样本标签:{label})# 数字 5# --- 2. 可视化检查 ---defshow_img(img,lbl):# 反归一化 (为了显示正常虽然不做也能看个大概)imgimg*0.30810.1307# 转换维度: PyTorch (C, H, W) - Matplotlib (H, W)# squeeze() 去掉维度为 1 的通道np_imgimg.squeeze().numpy()plt.imshow(np_img,cmapgray)plt.title(fLabel:{lbl})plt.axis(off)plt.show()show_img(image,label)样本形状: torch.Size([1, 28, 28]) 样本标签: 5步骤 3组装 DataLoader (传菜员)核心原理Dataset 只能一个一个拿数据。DataLoader 负责Batching: 把 64 个样本打包成一个大 Tensor (64, 1, 28, 28)。Shuffling: 打乱顺序防止模型记住“先是0后是1”。Multiprocessing: 多进程并行读取num_workers利用 CPU 多核加速。任务实例化train_loader和test_loader。# 定义批次大小BATCH_SIZE64# 1. 训练加载器 (需要打乱)train_loaderDataLoader(datasettrain_dataset,batch_sizeBATCH_SIZE,shuffleTrue,# 重点训练时必须打乱num_workers0# Windows 下建议设为 0 (主进程)Linux 可设为 4)# 2. 测试加载器 (不需要打乱)test_loaderDataLoader(datasettest_dataset,batch_size1000,# 测试时显存允许可以大一点shuffleFalse)print(f Train Loader 共有{len(train_loader)}个 Batches)# 60000 / 64 ≈ 938 Train Loader 共有 938 个 Batches步骤 4模拟训练迭代 (上菜啦)场景描述在真正的训练循环中我们不需要手动getitem。只需要写for data, target in train_loader:DataLoader 就会源源不断地送数据出来。任务从 DataLoader 中取出一个 Batch查看其形状。# 从 Loader 中获取第一个 Batch# iter() 转为迭代器next() 取下一个data_batch,label_batchnext(iter(train_loader))print( 一个 Batch 的数据结构 )print(fData Batch Shape :{data_batch.shape})# 预期: [64, 1, 28, 28] - [Batch Size, Channel, Height, Width]print(fLabel Batch Shape:{label_batch.shape})# 预期: [64]print(\n ️ 这个 Batch 里的前 10 个标签 )print(label_batch[:10])# 可视化 Batch 里的第一张图show_img(data_batch[0],label_batch[0]) 一个 Batch 的数据结构 Data Batch Shape : torch.Size([64, 1, 28, 28]) Label Batch Shape: torch.Size([64]) ️ 这个 Batch 里的前 10 个标签 tensor([0, 0, 2, 1, 9, 5, 0, 9, 1, 4]) Day 38 总结大数据处理的基石今天我们掌握了深度学习数据流的标准范式Dataset (数据源)必须实现__len__和__getitem__。负责处理单个样本。Transforms (预处理)负责张量转换、归一化、数据增强。DataLoader (调度器)负责批量读取 (Batching)和乱序 (Shuffling)。这是 GPU 能够高效吃数据的关键。Dataset vs DataLoader 对照表特性DatasetDataLoader关注点单个样本 (Item)一批样本 (Batch)操作读取文件、预处理打包、打乱、多进程角色仓库管理员/厨师物流车队/传菜员Next Level:有了数据加载器明天Day 39我们终于可以构建一个真正的卷积神经网络 (CNN)来识别这些手写数字了