栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

tensorflow2.x keras 几种使用Dataset 读 Images 的方式

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

tensorflow2.x keras 几种使用Dataset 读 Images 的方式

文章目录
    • 1. image_dataset_from_directory
      • 用法
      • 参数
      • 返回
    • 2. ImageDataGenerator
    • 3. tf.image.decode_image
    • 4. Important

1. image_dataset_from_directory

官方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 个通道。
2. ImageDataGenerator

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),
   ]
)

如果你对这篇文档有什么疑问,欢迎留言!同时你觉得对你有帮助,请点赞,留言,转发支持一下博主

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/928234.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号