- 1. image_dataset_from_directory
- 用法
- 参数
- 返回
- 2. ImageDataGenerator
- 3. tf.image.decode_image
- 4. Important
官方API 文档 : tf.keras.utils.image_dataset_from_directory
下图代码展示了从data/minist_subfolders/下面读取image的过程。
labels:'inferred’指的是自动从文件目录加载label。这里拿Mnist数据集举例
img_height = 28
img_width = 28
batch_size = 32
ds_train = tf.keras.utils.image_dataset_from_directory(
'data/minist_subfolders/',
labels='inferred',
label_mode= "int", #categorical, binary
# class_names = ['0','1','2','3'],
color_mode = 'grayscale',
batch_size = batch_size,
image_size = (img_height, img_width),
shuffle=True,
seed=123,
validation_split = 0.1,
subset="training",
)
用法
tf.keras.utils.image_dataset_from_directory(
directory, labels=‘inferred’, label_mode=‘int’,
class_names=None, color_mode=‘rgb’, batch_size=32, image_size=(256,
256), shuffle=True, seed=None, validation_split=None, subset=None,
interpolation=‘bilinear’, follow_links=False,
crop_to_aspect_ratio=False, **kwargs
)
-
directory 数据所在的目录。如果labels是"inferred",它应该包含子目录,每个子目录都包含一个类的图像。否则,目录结构将被忽略。
-
labels “inferred”(从目录结构生成标签)、None(无标签)或与目录中找到的图像文件数量相同大小的整数标签列表/元组。标签应根据图像文件路径的字母数字顺序排序(通过Python 中的os.walk(directory) 获得)。
-
label_mode
‘int’:means that the labels are encoded as integers (e.g. for
sparse_categorical_crossentropy loss).- ‘categorical’ 表示标签被编码为分类向量(例如,对于 categorical_crossentropy 损失)。
- ‘binary’ 表示标签(只能有 2 个)被编码为值为 0 或 1 的 float32 标量(例如,对于 binary_crossentropy )。
-
无(无标签)。
-
class_names 仅当 “labels” 为 "inferred"时才有效。这是类名的显式列表(必须与子目录的名称匹配)。用于控制类的顺序(否则使用字母数字顺序)。
-
color_mode “grayscale”、“rgb”、“rgba” 之一。默认值:“rgb”。图像是否将转换为具有 1、3 或 4个通道。
-
batch_size 数据批次的大小。默认值:32。如果 None ,数据将不会被批处理(数据集将产生单个样本)。
-
image_size 从磁盘读取图像后调整图像大小的大小。默认为 (256, 256)
。由于管道处理必须具有相同大小的批量图像,因此必须提供这一点。 -
shuffle 是否打乱数据。默认值:真。如果设置为 False,则按字母数字顺序对数据进行排序。
-
seed 用于洗牌和转换的可选随机种子。
-
validation_split 0 到 1 之间的可选浮点数,保留用于验证的数据的一部分。
-
subset “training” 或 “validation” 之一。仅在设置 validation_split 时使用。
-
interpolation 字符串,调整图像大小时使用的插值方法。默认为 bilinear 。支持 bilinear , nearest, bicubic , area , lanczos3 , lanczos5 , gaussian , mitchellcubic 。
-
follow_links 是否访问符号链接指向的子目录。默认为假。
-
crop_to_aspect_ratio 如果为True,则调整图像大小而不会出现纵横比失真。当原始纵横比与目标纵横比不同时,将裁剪输出图像以返回与目标纵横比匹配的图像(大小为image_size)中最大的可能窗口。默认情况下(crop_to_aspect_ratio=False),可能不会保留纵横比。
-
**kwargs 旧版关键字参数。
- A tf.data.Dataset对象。
- 如果 label_mode 为 None,它会产生形状为 (batch_size, image_size[0], image_size[1], num_channels) 的 float32 张量,对图像进行编码(有关 num_channels的规则,请参见下文)。
- 否则,它会产生一个元组 (images, labels) ,其中 images 具有形状 (batch_size,image_size[0], image_size[1], num_channels) ,并且 labels 遵循下面说明的格式。
如果你的目录结构是:
main_directory/ ...class_a/ ......a_image_1.jpg ......a_image_2.jpg ...class_b/ ......b_image_1.jpg ......b_image_2.jpg
然后调用 image_dataset_from_directory(main_directory, labels=‘inferred’) 将返回一个 tf.data.Dataset,它会从子目录 class_a 和 class_b 中生成批量图像,以及标签 0 和 1(0 对应于 class_a,1 对应于 class_b)。
支持的图片格式:jpeg、png、bmp、gif。动画 gif 被截断到第一帧。
关于标签格式的规则:
- 如果 label_mode 是 int ,则标签是形状为 (batch_size,) 的 int32 张量。
- 如果 label_mode是 binary ,则标签是形状为 (batch_size, 1) 的 1 和 0 的 float32 张量。
- 如果 label_mode是 categorial ,则标签是形状为 (batch_size, num_classes) 的 float32 张量,表示类索引的one-hot 编码。
关于生成图像中通道数的规则:
- 如果 color_mode 是 grayscale ,则图像张量中有 1 个通道。
- 如果 color_mode 是 rgb ,则图像张量中有 3 个通道。
- 如果 color_mode 是 rgba ,则图像张量中有 4 个通道。
API文档:tf.keras.preprocessing.image.ImageDataGenerator
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=5,
zoom_range=(0.99, 0.99),
horizontal_flip=False,
vertical_flip=False,
data_format='channels_last',
validation_split=0.0,
dtype=tf.float32,
)
train_generator = datagen.flow_from_directory(
'data/mnist_subfolders/',
target_size=(img_height, img_width),
batch_size=batch_size,
color_mode='grayscale',
shuffle=True,
subset="training",
seed=123,
)
3. tf.image.decode_image
- 3.1 这里是将图片文件的name 和label 统一放到一个CSV 文件中去,然后通过tf.io.read_file读取CSV文件目录,然后使用tf.image.decode_image 去解析图片格式到tensorflowdatasets变量ds_train里面去
Step1:tf.io.read_file 读文件
Step2: tf.image.decode_image 解析图片
参考下面 read_image 函数
import pandas as pd
directory = 'data/mnist_images_csv/'
df = pd.read_csv(directory + 'train.csv')
file_paths = df['file_name'].values
labels = df['lable'].values
# print(file_paths)
ds_train = tf.data.Dataset.from_tensor_slices((file_paths, labels))
def read_image(image_file, lable):
image = tf.io.read_file(directory + image_file)
image = tf.image.decode_image(image, channels=1, dtype=tf.float32)
return image, lable
def augment(image, label):
# data augmentation here
return image, label
ds_train = ds_train.map(read_image).map(augment).batch(2)
- 3.2 第二种则是比较通用的一直读取文件的方式。
即把所有的图片放到一个folder(data/mnist_images_only/)下面
通过解析图片上面名字来识别label
图片格式为:
data/mnist_images_only/2.jpg
data/mnist_images_only/3.jpg
import pathlib #pathlib is in standard library
batch_size = 2
img_height = 28
img_height = 28
directory = 'data/mnist_images_only/'
ds_train = tf.data.Dataset.list_files(str(pathlib.path(directory + "*.jpg")))
def process_path(file_path):
image = tf.io.read_file(file_path)
image = tf.image.decode_jpeg(image, channels=1)
label = tf.strings.split(file_path, '\')
label = tf.strings.substr(label, pos=0, len=1)[2]
label = tf.strings.to_number(label, out_type=tf.int64)
return image, label
ds_train = ds_train.map(process_path).batch(batch_size)
4. Important
- 使用tf.data.Dataset 读取文件格式的时候一定要加上batch参数 eg: ds_train.map(process_path).batch(batch_size), 否则在model读取数据train的时候会出现维度不一致的报错信息。比如下面model的输入层的定义layers.Input((28, 28, 1)), 实际上它会读取一个4D数据信息(batch_szie, width, heigth, channel)而不是(width, heigth, channel)
model = keras.Sequential(
[
layers.Input((28, 28, 1)),
layers.Conv2D(16, 3, padding='same'),
layers.Conv2D(32, 3, padding='same'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(10),
]
)
如果你对这篇文档有什么疑问,欢迎留言!同时你觉得对你有帮助,请点赞,留言,转发支持一下博主



