【问题标题】:How to train with a dataset of images where the labels are also images?如何使用标签也是图像的图像数据集进行训练?
【发布时间】:2021-05-18 15:52:46
【问题描述】:

我正在为超分辨率构建神经网络。我有一个由 2 个文件夹组成的数据集,每个文件夹包含 100990 张图片。第一个文件夹的图像分辨率为 128x128x3,第二个文件夹的图像分辨率为 32x32x3。作为输入,我想为神经网络提供 32x32x3 的图像。然后作为输出,我想给神经网络 128x128x3 的图像。理想情况下,神经网络将学习如何将 32x32x3 图像映射到 128x128x3 图像以执行超分辨率。

我之前参与过一个自动编码器项目,该项目也使用图像作为 NN 的输入和输出。但它是在一个小得多的数据集上,只包含 800 张图片。我这样做的方法是使用如下代码将所有图像作为数组加载到 RAM 中:

from PIL import ImageOps, Image
size = 64, 64

for f in os.listdir(os.path.join(base_dir, "pokemon_jpg")):
    im = Image.open(os.path.join(base_dir, "pokemon_jpg", f)).resize(size, Image.ANTIALIAS)
    break

big_arr = np.array([np.array(im)]).reshape(1, 64, 64, 3)
for f in os.listdir(os.path.join(base_dir,"pokemon_jpg"))[1:]:
    big_arr = np.append(big_arr, [np.array(Image.open(os.path.join(base_dir, "pokemon_jpg", f)).resize(size, Image.ANTIALIAS)).reshape(64, 64, 3)], axis=0)
    #i+=1
    
big_arr = big_arr/255

但是,由于我当前的数据集包含 100,000 多张图像,因此我不能同时将它们全部加载到 RAM 中。为了训练模型,我需要一次加载一批图像。我试过使用 tf.keras.preprocessing.image_dataset_from_directory() 但是当我制作 image_dataset_from_directory 时,它使用文件夹的名称作为标签(应该如此)。但是我如何制作一个类似的 image_dataset_from_directory 但标签是 128x128x3 的图像,以便我可以将其输入神经网络?

这是我目前尝试过的:

# building the neural network with input shape (None, 32, 32, 3) and output shape (None, 128, 128, 3)
input_img = tf.keras.Input(shape=(32, 32, 3))
x = keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same')(input_img)
x = keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = tf.keras.layers.UpSampling2D((2, 2))(x)
x = keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same')(x)
x = keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same')(x)
x = tf.keras.layers.UpSampling2D((2, 2))(x)
x = keras.layers.Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)
model = keras.Model(input_img, x)
model.compile(optimizer='adam', loss = 'binary_crossentropy')

resized_dir = os.path.join(os.getcwd(), os.pardir, "resized_food_high_res_images")
converted_dir = os.path.join(os.getcwd(), os.pardir, "train_food_images_low_res" )

labels_dataset = tf.keras.preprocessing.image_dataset_from_directory(resized_dir, label_mode=None, image_size=(128, 128), shuffle=False)
train_dataset = tf.keras.preprocessing.image_dataset_from_directory(converted_dir,label_mode = None, image_size=(32, 32), shuffle=False)

model.fit(labels_dataset, train_dataset,
         epochs=3,
         batch_size=128)

模型总结为:

Model: "model_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_5 (InputLayer)         [(None, 32, 32, 3)]       0         
_________________________________________________________________
conv2d_11 (Conv2D)           (None, 32, 32, 8)         224       
_________________________________________________________________
conv2d_12 (Conv2D)           (None, 32, 32, 8)         584       
_________________________________________________________________
up_sampling2d_8 (UpSampling2 (None, 64, 64, 8)         0         
_________________________________________________________________
conv2d_13 (Conv2D)           (None, 64, 64, 16)        1168      
_________________________________________________________________
conv2d_14 (Conv2D)           (None, 64, 64, 16)        2320      
_________________________________________________________________
up_sampling2d_9 (UpSampling2 (None, 128, 128, 16)      0         
_________________________________________________________________
conv2d_15 (Conv2D)           (None, 128, 128, 3)       435       
=================================================================
Total params: 4,731
Trainable params: 4,731
Non-trainable params: 0
_________________________________________________________________

我收到的错误是:

ValueError: `y` argument is not supported when using dataset as input.

据我了解,我收到此错误是因为 image_dataset_from_directory 具有图片文件夹名称的标签。但我找不到任何有关如何执行此操作的信息。

【问题讨论】:

    标签: tensorflow keras deep-learning


    【解决方案1】:

    您传递给拟合序列的生成器必须生成一个元组(img1, img2)。您可以使用tf.data.Dataset.zip 来实现所需的形状:

    labels_dataset = tf.keras.preprocessing.image_dataset_from_directory(resized_dir, label_mode=None, image_size=(128, 128), shuffle=False)
    train_dataset = tf.keras.preprocessing.image_dataset_from_directory(converted_dir,label_mode = None, image_size=(32, 32), shuffle=False)
    # zipping
    zipped_ds = tf.data.Dataset.zip((train_dataset, labels_dataset))
    

    然后你可以拨打fit:

    model.fit(zipped_ds)
    

    【讨论】:

    • 运行该代码时,我收到错误“ValueError: Input 0 is incompatible with layer model: expected shape=(None, 32, 32, 3), found shape=(None, None, 32 , 32, 3)”。然后我尝试将模型的输入层更改为“input_img = tf.keras.Input(batch_input_shape=(32, 32, 32, 3))”,但我收到了同样的错误。但是当我从 zipped_ds 中删除 .batch(32) 时,它起作用了!
    • 啊,tf.keras.preprocessing.image_dataset_from_directory 可能已经在进行批处理了。我将编辑我的答案。
    猜你喜欢
    • 2020-02-02
    • 2021-07-08
    • 2021-11-19
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 2016-06-25
    相关资源
    最近更新 更多