Google colab 在使用 tensorflow 2.0 批处理数据集时未加载图像文件
Google colab not loading image files while using tensorflow 2.0 batched dataset
一些背景知识,我正在将大约 60,000 张图像加载到 colab 以训练 GAN。我已经将它们上传到云端硬盘,目录结构包含 root
内不同 类(大约 7-8 个)的文件夹。我正在将它们加载到 colab,如下所示:
root = "drive/My Drive/data/images"
root = pathlib.Path(root)
list_ds = tf.data.Dataset.list_files(str(root/'*/*'))
for f in list_ds.take(3):
print(f.numpy())
给出输出:
b'drive/My Drive/data/images/folder_1/2994.jpg'
b'drive/My Drive/data/images/folder_1/6628.jpg'
b'drive/My Drive/data/images/folder_2/37872.jpg'
我进一步处理如下:
def process_path(file_path):
label = tf.strings.split(file_path, '/')[-2]
image = tf.io.read_file(file_path)
image = tf.image.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
return image#, label
ds = list_ds.map(process_path)
BUFFER_SIZE = 60000
BATCH_SIZE = 128
train_dataset = ds.shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
每张图片的大小为128x128
。现在问题来了,当我尝试在 colab 中查看批处理时,执行将永远持续下去并且永不停止,例如,使用以下代码:
for batch in train_dataset.take(4):
print([arr.numpy() for arr in batch])
早些时候我认为 batch_size 可能是个问题所以尝试更改它但仍然是同样的问题。当我加载大量文件时,这会不会是 colab 的问题?
或者由于使用 MNIST(28x28) 时图像的大小?如果是这样,可能的解决方案是什么?
提前致谢。
编辑:
删除 shuffle 语句后,最后一行会在几秒钟内执行。所以我认为这可能是由于随机播放 BUFFER_SIZE 造成的问题,但即使减少了 BUFFER_SIZE,它也需要很长时间才能执行。任何解决方法?
以下是我如何从个人 Google 驱动器加载 1.12GB 压缩 FLICKR 图像数据集。首先,我在 colab 环境中解压数据集。可以加快性能的一些功能是 prefetch
和 autotune
。此外,我使用本地 colab 缓存来存储处理后的图像。第一次执行大约需要 20 秒(假设您已经解压缩数据集)。然后缓存允许后续调用非常快速地加载。
假设您已经授权 google 驱动器 API,我首先解压文件夹
!unzip /content/drive/My\ Drive/Flickr8k
!unzip Flickr8k_Dataset
!ls
然后我使用了您的代码并添加了 prefetch()
、autotune
和 cache file
。
import pathlib
import tensorflow as tf
def prepare_for_training(ds, cache, BUFFER_SIZE, BATCH_SIZE):
if cache:
if isinstance(cache, str):
ds = ds.cache(cache)
else:
ds = ds.cache()
ds = ds.shuffle(buffer_size=BUFFER_SIZE)
ds = ds.batch(BATCH_SIZE)
ds = ds.prefetch(buffer_size=AUTOTUNE)
return ds
AUTOTUNE = tf.data.experimental.AUTOTUNE
root = "Flicker8k_Dataset"
root = pathlib.Path(root)
list_ds = tf.data.Dataset.list_files(str(root/'**'))
for f in list_ds.take(3):
print(f.numpy())
def process_path(file_path):
label = tf.strings.split(file_path, '/')[-2]
img = tf.io.read_file(file_path)
img = tf.image.decode_jpeg(img)
img = tf.image.convert_image_dtype(img, tf.float32)
# resize the image to the desired size.
img = tf.image.resize(img, [128, 128])
return img#, label
ds = list_ds.map(process_path, num_parallel_calls=AUTOTUNE)
train_dataset = prepare_for_training(ds, cache="./custom_ds.tfcache", BUFFER_SIZE=600000, BATCH_SIZE=128)
for batch in train_dataset.take(4):
print([arr.numpy() for arr in batch])
这是一种使用 keras flow_from_directory()
的方法。这种方法的好处是您可以避免 tensorflow shuffle()
,这取决于缓冲区大小可能需要处理整个数据集。 Keras 为您提供了一个迭代器,您可以调用它来获取数据批次并内置随机洗牌。
import pathlib
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
root = "Flicker8k_Dataset"
BATCH_SIZE=128
train_datagen = ImageDataGenerator(
rescale=1./255 )
train_generator = train_datagen.flow_from_directory(
directory = root, # This is the source directory for training images
target_size=(128, 128), # All images will be resized
batch_size=BATCH_SIZE,
shuffle=True,
seed=42, #for the shuffle
classes=[''])
i = 4
for batch in range(i):
[print(x[0]) for x in next(train_generator)]
一些背景知识,我正在将大约 60,000 张图像加载到 colab 以训练 GAN。我已经将它们上传到云端硬盘,目录结构包含 root
内不同 类(大约 7-8 个)的文件夹。我正在将它们加载到 colab,如下所示:
root = "drive/My Drive/data/images"
root = pathlib.Path(root)
list_ds = tf.data.Dataset.list_files(str(root/'*/*'))
for f in list_ds.take(3):
print(f.numpy())
给出输出:
b'drive/My Drive/data/images/folder_1/2994.jpg'
b'drive/My Drive/data/images/folder_1/6628.jpg'
b'drive/My Drive/data/images/folder_2/37872.jpg'
我进一步处理如下:
def process_path(file_path):
label = tf.strings.split(file_path, '/')[-2]
image = tf.io.read_file(file_path)
image = tf.image.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
return image#, label
ds = list_ds.map(process_path)
BUFFER_SIZE = 60000
BATCH_SIZE = 128
train_dataset = ds.shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
每张图片的大小为128x128
。现在问题来了,当我尝试在 colab 中查看批处理时,执行将永远持续下去并且永不停止,例如,使用以下代码:
for batch in train_dataset.take(4):
print([arr.numpy() for arr in batch])
早些时候我认为 batch_size 可能是个问题所以尝试更改它但仍然是同样的问题。当我加载大量文件时,这会不会是 colab 的问题?
或者由于使用 MNIST(28x28) 时图像的大小?如果是这样,可能的解决方案是什么?
提前致谢。
编辑: 删除 shuffle 语句后,最后一行会在几秒钟内执行。所以我认为这可能是由于随机播放 BUFFER_SIZE 造成的问题,但即使减少了 BUFFER_SIZE,它也需要很长时间才能执行。任何解决方法?
以下是我如何从个人 Google 驱动器加载 1.12GB 压缩 FLICKR 图像数据集。首先,我在 colab 环境中解压数据集。可以加快性能的一些功能是 prefetch
和 autotune
。此外,我使用本地 colab 缓存来存储处理后的图像。第一次执行大约需要 20 秒(假设您已经解压缩数据集)。然后缓存允许后续调用非常快速地加载。
假设您已经授权 google 驱动器 API,我首先解压文件夹
!unzip /content/drive/My\ Drive/Flickr8k
!unzip Flickr8k_Dataset
!ls
然后我使用了您的代码并添加了 prefetch()
、autotune
和 cache file
。
import pathlib
import tensorflow as tf
def prepare_for_training(ds, cache, BUFFER_SIZE, BATCH_SIZE):
if cache:
if isinstance(cache, str):
ds = ds.cache(cache)
else:
ds = ds.cache()
ds = ds.shuffle(buffer_size=BUFFER_SIZE)
ds = ds.batch(BATCH_SIZE)
ds = ds.prefetch(buffer_size=AUTOTUNE)
return ds
AUTOTUNE = tf.data.experimental.AUTOTUNE
root = "Flicker8k_Dataset"
root = pathlib.Path(root)
list_ds = tf.data.Dataset.list_files(str(root/'**'))
for f in list_ds.take(3):
print(f.numpy())
def process_path(file_path):
label = tf.strings.split(file_path, '/')[-2]
img = tf.io.read_file(file_path)
img = tf.image.decode_jpeg(img)
img = tf.image.convert_image_dtype(img, tf.float32)
# resize the image to the desired size.
img = tf.image.resize(img, [128, 128])
return img#, label
ds = list_ds.map(process_path, num_parallel_calls=AUTOTUNE)
train_dataset = prepare_for_training(ds, cache="./custom_ds.tfcache", BUFFER_SIZE=600000, BATCH_SIZE=128)
for batch in train_dataset.take(4):
print([arr.numpy() for arr in batch])
这是一种使用 keras flow_from_directory()
的方法。这种方法的好处是您可以避免 tensorflow shuffle()
,这取决于缓冲区大小可能需要处理整个数据集。 Keras 为您提供了一个迭代器,您可以调用它来获取数据批次并内置随机洗牌。
import pathlib
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
root = "Flicker8k_Dataset"
BATCH_SIZE=128
train_datagen = ImageDataGenerator(
rescale=1./255 )
train_generator = train_datagen.flow_from_directory(
directory = root, # This is the source directory for training images
target_size=(128, 128), # All images will be resized
batch_size=BATCH_SIZE,
shuffle=True,
seed=42, #for the shuffle
classes=[''])
i = 4
for batch in range(i):
[print(x[0]) for x in next(train_generator)]