u深度学习 神经网络图像数据的预处理全解
|深度学习| 二维数据pytorch训练模版
文章目录
- |深度学习| 二维数据pytorch训练模版
- 前言
- 图像预处理
- 读取并加载图像
- 数据集打包
- 二维训练模版
- 总结
前言
在最近复现各种经典的CNN网络时突发奇想准备加入一个全新的数据集做一个完整的神经网络代码,但是发现自己好像并不太会对图像数据进行预处理,在经过各种渠道的学习之后,目前对于图像数据的预处理有了很大的心得,并且成功运用自己预处理成功的图像数据完成了在各种二维网络上的训练。特此把这篇博客作为这段时间的一个经验之谈。
本篇博客内训练模版改动完全是在学长 @浩浩的科研笔记的博客:Pytroch 自写训练模板适合入门版 包含十五种经典的自己复现的一维模型 1D CNN为基础进行的一系列符合二维数据的改动(站在巨人肩膀上了属于是),并且二维数据训练相较于一维数据训练改动的地方大部分都是围绕数据处理,具体体现在 数据集打包和创建数据库。
在这篇博客中我会拿一个很经典的mnist手写数字识别作为图像数据集,详细展开对于各种图像处理以及二维数据训练的叙述。
MNIST数据集(Modified National Institute of Standards and Technology database)是一个大型的手写数字数据库,常被用于训练各种图像处理系统。这个数据集由美国国家标准与技术研究院(NIST)在20世纪80年代收集,后经过修改而成为MNIST数据集。它是机器学习和计算机视觉领域最广泛使用的入门数据集之一。
由于mnist数据集在下载完成后为了更容易储存是以ubyte
为结尾的文件,所以为了更好地展示对图像的预处理首先我用了一段python
代码把ubyte
格式的文件转换成了jpg
格式的图片文件。
import os
import numpy as np
from PIL import Imagedef convert_ubyte_to_jpg(ubyte_file, output_dir):# 确保输出目录存在if not os.path.exists(output_dir):os.makedirs(output_dir)with open(ubyte_file, 'rb') as f:# 读取头部信息magic, num_images, rows, cols = np.frombuffer(f.read(16), dtype=np.dtype('>i4'))# 遍历所有图片for i in range(num_images):# 读取每张图片img = np.frombuffer(f.read(rows * cols), dtype=np.uint8)img = img.reshape((rows, cols))# 转换为PIL图像并保存为JPEGimg = Image.fromarray(img, mode='L') # 'L' 表示灰度图img.save(os.path.join(output_dir, f'{i}.jpg'))# 使用示例
ubyte_file = 'train-images-idx3-ubyte' # ubyte文件路径
output_dir = 'mnist_jpg' # 输出目录
convert_ubyte_to_jpg(ubyte_file, output_dir)
转换后的效果如下:
共有60000张训练集和10000张测试集,并且每张图片名称都是 ‘标签_序号’ 的形式。
图像预处理
在进行预处理之前,我们首先需要知道神经网络能够接受的预处理最终的格式。这里以pytorch
为例,它能够接受的格式为torch.Tensor
的一个张量(即多维数组),并且一般我们在训练的时候多会将数据和标签打包成一个package
.
读取并加载图像
首先我们要先知道读取并加载图像的意义,这一步的目的是将我们jpg
格式的图像根据每个图像的不同,转换成对应的numpy
张量(即多维数组)。
因为大多数的深度学习框架都会与
numpy
紧密集成,都能够将numpy
数组转换成为这些框架的数据形式(如TensorFlow
的tf.Tensor
或者Pytorch
的torch.Tensor
);第二点是因为numpy
库提供了广泛的数学和数组操作功能,便于进行各种数学上的预处理;最后就是在数据归一化和标准化过程中使用numpy
数组可以选择合适的数据类型来存储图像数据,有助于在处理过程中保持数值精度。
在读取图像之前,我们要对自己要处理的数据集有一定了解,特别是在图像类型(几通道、几维度等)、和对应标签上面。以我们转换完成的Mnist数据集为例,他是1通道28×28的灰度图像。
但是由于此博客介绍的是二维数据处理以及相关训练模板,所以在后续的处理中我会将mnist数据集按照3通道的格式读取(实际运用中,并不太建议三通道读取灰度图像,因为灰度图像三个通道数据是相同的,这样做只会浪费计算空间,我单纯因为不想找其他图像数据集了,所以暂时使用mnist做二维处理) ,标签为每张图片名称的前半部分,例如图片名为0_1的图片标签为0。
下面是读取加载图像的各部分代码:
import numpy as np
import os
import cv2 as cvhome_list = r'D:/jiqixuexi/mnist/train'
files = os.listdir(home_list)#列出目录下所有文件的名字并赋值给filesprint(files)
首先调用numpy
,os
,opencv
库,然后通过os.listdir
把目录下的数据集一一列出所有文件并且赋给files,目的是后文分离标签和根据标签一一对应数据转换格式。可以看到输出files
后文件名被一一列出。
下面是分离标签以及转换图像格式的代码:
data = []
label = []for i,file in enumerate(files):img_path = os.path.join(home_list,file)#生成每个图片的完整路径img = cv.imread(img_path)data.append(img)label.append(int(file.split('_')[0]))#以‘_’为分隔并取第一个元素作为标签print(i+1,label[i])
在这里首先定义data[]
和label[]
两个空列表,然后遍历files
,根据名称读取图片并且转换格式