使用 tf.io 和 tf.image预处理训练图像

    高效的数据输入处理也可以很大程度提升模型的能,减少模型的训练时间,数据输入处理实际上是一个ELT过程, 读取、预处理加载到模型当中

1.预处理函数

注意事项:

  1.     一般图像处理中,高速数据管道是为了解决,图像数据加载过慢,加速图像数据的加载过程.
  2.     在编写预处理函数时,一般输入是已经处理好(例如 划分好的训练集的图片路径)图片路径, 返回的是图像的像素数据
  3.     函数重要的作用是,使用tf.io按照路径读取图片, 加上图片的预处理过程

代码示例:

def load_and_preprocess_image(path):
    
    # 读取图片
    image = tf.io.read_file(path)
    image = tf.image.decode_jpeg(image, channels=3)
    
    image = tf.image.resize(image, [192, 192])
    
    # 归一化处理  或者其他的 图像处理的方法
    image = image / 255.0
    
    return image

 

基于图像的多分类问题,如果有对应的图片label文件,或者语义识别问题,可以修改函数构造,如下:

def load_and_preprocess_image(path):
    
    # 读取图片
    image = tf.io.read_file(path[0])
    image = tf.image.decode_jpeg(image, channels=3)
    
    image = tf.image.resize(image, [192, 192])

    label = tf.io.read_file(path[1])
    label = tf.image.decode_jpeg(label, channels=1)
    
    label = tf.image.resize(label, [192, 192])
    
    # 归一化处理  或者其他的 图像处理的方法
    image = image / 255.0
    label = label / 255.0
    
    return image,label

 

2.数据集处理

一般在训练模型的时候,需要训练集和测试集, 不要试图将数据处理管道流程的代码封装成函数,以便快速构造两者, 经过试验会出现内存爆满,进程被杀死的情况.
代码示例:

# 下面构造 tf.data.Dataset 用来构建 和 管理数据集

# 创建 图片文件 路径的 管道的结点 图片路径的数据集
path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)
   
# 使用 AUTOTUNE 自动调节管道的参数
AUTOTUNE = tf.data.experimental.AUTOTUNE

# 构建图片的数据集
image_ds = path_ds.map(load_and_preprocess_image,
                       num_parallel_calls = AUTOTUNE)

# 构建图片 类标数据 的数据集
label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(all_image_labels, tf.int64))


# 将图片 和 类标 压缩为(图片, 类标)对
image_labels_ds = tf.data.Dataset.zip((image_ds, label_ds))

image_labels_ds = image_labels_ds.shuffle(buffer_size=3670)
image_labels_ds = image_labels_ds.repeat(1)
image_labels_ds = image_labels_ds.batch(8)
image_labels_ds = image_labels_ds.prefetch(buffer_size = AUTOTUNE)

 

3.使用数据

num = 0
for (image, lable) in image_labels_ds:
    num = num + 1
    print(lable)

 

总结


1. image_labels_ds = tf.data.Dataset.zip((image_ds, label_ds))
用于将数据与标签数据类型不相同的 情况下 构造数据与标签的 训练数据对


2. image_labels_ds = image_labels_ds.shuffle(buffer_size=3670)
该步骤的操作一定要用在 batch 设置之前, 博主一般直接用在datdset 对象构建完成之后. 否则可能会造成数据 无法打乱

3. 在构造tf.data.Dataset对象的时候, map操作要在 batchsizie,cache,shuffle 操作之前,否则可能出现 unknown error ,此时检查以下代码.

4. 在mode.fit() 依旧可以设置batch_size,epochs, 注意当在datasets中设置batch_size,repaet 之后, fit()函数中不要再设置batch_size或者设置成相同的大小, 否则会报错.

ValueError: The `batch_size` argument must not be specified for the given input type. 
Received input: <PrefetchDataset shapes: ((None, 192, 192, 3), (None,)), 
types: (tf.float32, tf.int64)>, batch_size: 4

 

5. 若果设置epochs, 则实际的训练批次是 repe*epohs .


6. 管道性能加速,参考 https://blog.csdn.net/Forrest97/article/details/105882837/

 

posted @ 2021-01-22 14:09  简约的代码无限的创新  阅读(919)  评论(0)    收藏  举报