TensorFlow2.0 大数据预处理Pipeline

it2023-08-21  68

目录

一、为什么需要这样?

二、如何解决?

三、TF2.0提供的方法

1、tf.data.Dataset中的map函数

2、TFRecord


 

一、为什么需要这样?

        入门的时候,我们非常熟悉MNIST手写数字数据集,我们构建深度神经网络,比如CNN,MLP,LSTM等来训练数据集,我们一次性的加载了所有的数据集,然后不停地迭代训练。

        当数据集非常大,大到50GB,100GB的时候,我们显然是不能将所有数据加载到内存空间的,不然的话硬件要求是非常苛刻的。

二、如何解决?

      其实在我们训练的时候,我们一次需要加载的数据只有batch_size大小,所以我们没有必要将所有的数据全部加载到内存中,可以构建一个队列,每次加载几个batch_size,然后不停地用完,不停的补新,这样可以很好的减少内存开销。

三、TF2.0提供的方法

1、tf.data.Dataset中的map函数

(可以参考TensorFlow2.0 分批读取数据集、训练)

可以发现map中的映射函数decode里面的操作都是基于tf,但是TF2.0也提供了函数tf.py_function供我们使用,通过这个函数来做一些python操作,例子如下:

def get_ftp_picture(self, tf_pic_name): return self.ftp.get_picture(pic_name=str(tf_pic_name.numpy(), encoding='utf-8')) def decode_ftp(self, filenames, label): res_tensor = tf.zeros(dtype=tf.float32, shape=[15, 112, 112, 3]) index = 0 for file in filenames: image_decode = tf.py_function(self.get_ftp_picture, [file], tf.float32) # image_decode = tf.image.resize(image_decode, [112, 112]) image_decode = image_decode / 255.0 image_decode = (image_decode - 0.5) * 2.0 image_decode = tf.expand_dims(image_decode, axis=0) res_tensor = tf.tensor_scatter_nd_update(res_tensor, [[index]], image_decode) index += 1 res_tensor = tf.transpose(res_tensor, (1, 2, 0, 3)) return res_tensor, label

但是这里有一个问题,一旦使用了tf.py_function,那么map函数将不会去并行处理,导致处理速度极其低下,这就是其非常不好的地方。如果需要使用非TF库的处理函数来处理数据的话,那怎么办呢?使用下面的第二种方法,先将数据保存为tfrecord的形式,然后再去加载训练。

2、TFRecord

(可以参考TensorFlow2.0 利用TFRecord存取数据集,分批次读取训练)

当然在将数据保存为TFRecord的时候,我们也是不能并行的, 但是这么做在训练阶段将会节省大量的时间。

关于TFRecord的一些feature的定义,和一些细节的处理官网给出了非常好的解释TFRecord 和 tf.Example

这里有一个注意点,也算是一个坑点,就是在非eager的情况下是不能使用tensor.numpy()的,但是在保存数据集为tfrecord形式的时候如果需要我们去用到tensor.numpy()的时候,我们可以将带有tensor.numpy()的操作放到一个函数中,通过tf.py_function去调用,这是我遇到这个问题的解决方案。

最新回复(0)