如何使用标签也是图像的图像数据集进行训练?

时间:2021-02-15 18:30:41

标签: tensorflow keras deep-learning

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

我之前参与了一个自动编码器项目,该项目也使用图像作为神经网络的输入和输出。但它是在一个仅包含 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 具有图片文件夹名称的标签。但我找不到有关如何执行此操作的任何信息。

1 个答案:

答案 0 :(得分: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)
相关问题