要利用Tensorflow或者Pytorch实现深度学习过程的第一步就是图像数据集的加载。
这里写目录标题
- Tensorflow
- 图像数据集加载
- 图片路径和标签读取
- 图像预处理
- 创建Tensorflow Dataset对象
- 方案一(不推荐)
- 方案二(推荐)
- Dataset对象的预处理
- 输入网络
- Pytorch
- 参考
Tensorflow
图像数据集加载
从tf.keras.util下载五类花数据集合
1 2 | data_dir = tf.keras.utils.get_file(origin='https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz', fname='flower_photos', untar=True) |
下载完成后,查看数据集的目录位置,可以看到flower_photos目录下有五类花对应的子目录,其中有对应的花.jpg图片。这就是一个标准的图像分类数据集合的存储格式。
1 2 3 | import pathlib data_root = pathlib.Path(data_dir) print(data_root) |

图片路径和标签读取
读取所有图像检索路径,注意不是读取图像数据
1 2 3 4 5 | import random all_image_paths = list(data_root.glob('*/*')) # 所有子目录下图片 all_image_paths = [str(path) for path in all_image_paths] random.shuffle(all_image_paths) #打乱数据 print(len(all_image_paths)) |
根据子目录名称建立分类字典
1 2 3 4 | label_names = sorted(item.name for item in data_root.glob('*/') if item.is_dir())#读取目录并排序为类别名 label_to_index = dict((name, index) for index, name in enumerate(label_names))#创建类别字典 all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_image_paths] #图像parent path 对应类 |
图像预处理
读取、解码、Resize、根据情况数据增强、标准化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def preprocess_image(path): image_size=224 image = tf.io.read_file(path) image = tf.image.decode_jpeg(image, channels=3) image = tf.image.resize(image, [image_size, image_size]) # 数据增强 x=tf.image.random_brightness(x, 1)#亮度调整 x = tf.image.random_flip_up_down(x) #上下颠倒 x= tf.image.random_flip_left_right(x) # 左右镜像 x = tf.image.random_crop(x, [image_size, image_size, 3]) # 随机裁剪 image /= 255.0 # normalize to [0,1] range x = normalize(x) # 标准化 return image |
创建Tensorflow Dataset对象
创建Tensorflow Dataset对象的目的是方便在训练过程中每组epoch的输入数据的高效输入和统一管理。
方案一(不推荐)
使用 from_tensor_slices 方法构建图像tf.data.Dataset。并使用map方法加载图像预处理preprocess_image
1 2 3 | path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths) AUTOTUNE = tf.data.experimental.AUTOTUNE image_ds = path_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE) |
使用 from_tensor_slices 方法构建标签tf.data.Dataset。并于图像dataset打包zip构成数据对。
1 2 | label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(all_image_labels, tf.int64)) image_label_ds = tf.data.Dataset.zip((image_ds, label_ds)) |
方案二(推荐)
直接使用all_image_labels 和 all_image_paths 构成一个元组作为tf.data.Dataset.from_tensor_slices的输入
1 2 3 4 5 6 | ds = tf.data.Dataset.from_tensor_slices((all_image_paths, all_image_labels)) def load_and_preprocess_from_path_label(path, label): return preprocess_image(path), label image_label_ds = ds.map(load_and_preprocess_from_path_label) image_label_ds |
Dataset对象的预处理
在正式开始训练前需要把数据集充分打乱、分割成batcch组、
1 2 3 4 5 6 7 8 9 | BATCH_SIZE = 16 image_count = len(all_image_paths) # 设置一个和数据集大小一致的 shuffle buffer size(随机缓冲区大小)以保证数据 # 被充分打乱。 ds = image_label_ds.shuffle(buffer_size=image_count) # buffer_size等于数据集大小确保充分打乱 ds = ds.repeat() #repeat 适用于next(iter(ds)) ds = ds.batch(BATCH_SIZE) # 当模型在训练的时候,`prefetch` 使数据集在后台取得 batch。 ds = ds.prefetch(buffer_size=AUTOTUNE)#随机缓冲区相关 |
输入网络
最后就是输入网络中如果没问题就大功告成
1 2 3 4 5 6 7 8 9 | mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3), include_top=False) mobile_net.trainable=False def change_range(image,label): return 2*image-1, label keras_ds = ds.map(change_range) # 数据集可能需要几秒来启动,因为要填满其随机缓冲区。 image_batch, label_batch = next(iter(keras_ds)) feature_map_batch = mobile_net(image_batch) print(feature_map_batch.shape) |
1 |
Pytorch
标准二级目录名为类别的图像存储格式数据,采用Pytorch自带API
1 | db = torchvision.datasets.ImageFolder(root='dir', transform=preprocess) |
参考