Tensorflow Datasets: Plodín/zmena Veľkosti snímky na jednu dávku po dataset.dávku()

0

Otázka

Je možné Orezať/zmena Veľkosti snímky na jednu dávku ?

Ja používam Tensorflow dataset API, ako je to uvedené nižšie:

dataset = dataset.shuffle().repeat().batch(batch_size, drop_remainder=True)

Chcem, v dávke všetky obrázky by mali mať rovnakú veľkosť. Avšak cez dávkach môže to mať rôzne veľkosti.

Napríklad, 1. dávka má všetky obrázky tvar (batch_size, 300, 300, 3). Ďalšie dávky môžu mať obrázky tvar (batch_size, 224, 224, 3). Ďalšie dávky môžu mať obrázky tvar (batch_size, 400, 400, 3).

V podstate chcem mať dymanically tvarované dávkach, avšak všetky obrázky v dávke mať statické tvary.

Ak urobíme nasledovne:

dataset = dataset.shuffle().repeat().batch(batch_size, drop_remainder=True).map(lambda x, y: map_fn(x, y))

Má vyššie .mapa() platí pre každú dávku samostatne alebo cez celý dataset ?

Ak vyššie .mapa() sa nevzťahujú na každej šarže samostatne, ako to môžeme urobiť ? Môžeme definovať akékoľvek iterator po dataset.dávku(), uplatňovať tf.obraz.crop_and_resize() za každý obraz na dávku a neskôr použiť dokumentačný materiál.zreťazenie() spojiť všetky premenil dávkach ?

Som vytváraní súboru, ako je uvedené nižšie:

# Dataset creation (read image data from files of COCO dataset)
dataset = tf.data.Dataset.list_files(self._file_pattern, shuffle=False)
dataset = dataset.shard(dataset_num_shards, dataset_shard_index)
dataset = dataset.shuffle(tf.cast(256 / dataset_num_shards, tf.int64))
dataset = dataset.interleave(map_func=tf.data.TFRecordDataset(filename).prefetch(1), cycle_length=32, block_length=1, num_parallel_calls=tf.data.experimental.AUTOTUNE)
dataset = dataset.map(tf_example_decoder.TfExampleDecoder().decode, num_parallel_calls=64)
dataset = dataset.shuffle(64).repeat()
# Parse each image for preprocessing
dataset = dataset.map(lambda data, _: _parse_example(data), num_parallel_calls=64)
dataset = dataset.batch(batch_size=batch_size, drop_remainder=True)

# Below code suggested by you to resize images to fixed shape in each batch
def resize_data(images, labels):
    tf.print('Original shape -->', tf.shape(images))
    SIZE = (300, 300)
    return tf.image.resize(images, SIZE), labels
dataset = dataset.map(resize_data)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

tf.estimator.Estimator(...).train(
        input_fn=dataset,
        steps=steps,
        hooks=train_hooks)
python tensorflow tensorflow-datasets
2021-11-24 05:50:45
1

Najlepšiu odpoveď

1

Vo všeobecnosti, môžete sa pokúsiť niečo ako toto:

import tensorflow as tf
import numpy as np

dataset1 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 300, 300, 3)))
dataset2 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 224, 224, 3)))
dataset3 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 400, 400, 3)))
dataset = dataset1.concatenate(dataset2.concatenate(dataset3))
dataset = dataset.shuffle(1).repeat().batch(32, drop_remainder=True)

def resize_data(images):
  tf.print('Original shape -->', tf.shape(images))
  SIZE = (180, 180)

  return tf.image.resize(images, SIZE)

dataset = dataset.map(resize_data)

for images in dataset.take(3):
  tf.print('New shape -->', tf.shape(images))
Original shape --> [32 300 300 3]
New shape --> [32 180 180 3]
Original shape --> [32 224 224 3]
New shape --> [32 180 180 3]
Original shape --> [32 400 400 3]
New shape --> [32 180 180 3]

Môžete tiež použiť tf.image.resize_with_crop_or_pad ak chcete, aby:

def resize_data(images):
  tf.print('Original shape -->', tf.shape(images))
  SIZE = (180, 180)
  return tf.image.resize_with_crop_or_pad(images, SIZE[0], SIZE[1])

dataset = dataset.map(resize_data)

for images in dataset.take(3):
  tf.print('New shape -->', tf.shape(images))

Všimnite si, že pomocou repeat() vytvorí nekonečná množina údajov.

Aktualizácia 1

Ak chcete náhodnú veľkosť pre každú dávku, skúste niečo ako toto:

import tensorflow as tf
import numpy as np

dataset1 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 300, 300, 3)))
dataset2 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 224, 224, 3)))
dataset3 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 400, 400, 3)))
dataset = dataset1.concatenate(dataset2.concatenate(dataset3))
dataset = dataset.batch(32, drop_remainder=True).shuffle(96)


def resize_data(images):
  batch_size = tf.shape(images)[0]
  images_resized = tf.TensorArray(dtype=tf.float32, size = 0, dynamic_size=True)
  SIZE = tf.random.uniform((2,), minval=300, maxval=500, dtype=tf.int32)
  for i in range(batch_size):
    images_resized = images_resized.write(images_resized.size(), tf.image.resize(images[i], SIZE))
  return images_resized.stack()

dataset = dataset.map(resize_data)

for images in dataset:
  tf.print('New shape -->', tf.shape(images))
New shape --> [32 392 385 3]
New shape --> [32 468 459 3]
New shape --> [32 466 461 3]

Aktualizácia 2

Veľmi flexibilná možnosť, že pracuje pre všetky veľkosti dávky bude vyzerať takto:

import tensorflow as tf
import numpy as np

dataset1 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 300, 300, 3)))
dataset2 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 224, 224, 3)))
dataset3 = tf.data.Dataset.from_tensor_slices(np.random.random((32, 400, 400, 3)))
dataset = dataset1.concatenate(dataset2.concatenate(dataset3))

def resize_and_batch(dataset, batch_size):
  final_dataset = None
  duration = len(dataset)//batch_size
  random_sizes = [tf.random.uniform((2,), minval=300, maxval=500, dtype=tf.int32) for _ in range(duration)]

  for i, size in zip(range(duration), random_sizes):
    idx = i * batch_size
    if i == 0:
      final_dataset = tf.data.Dataset.from_tensor_slices([tf.image.resize(x, size) for x in dataset.take(batch_size)])
    else:
      final_dataset = final_dataset.concatenate(tf.data.Dataset.from_tensor_slices([tf.image.resize(x, size) for x in dataset.skip(idx).take(batch_size)]))
  return final_dataset

batch_size = 10
ds = resize_and_batch(dataset, batch_size)
ds = ds.batch(batch_size).shuffle(len(ds))
for images in ds:
 tf.print('New shape -->', images.shape)
New shape --> TensorShape([10, 399, 348, 3])
New shape --> TensorShape([10, 356, 329, 3])
New shape --> TensorShape([10, 473, 373, 3])
New shape --> TensorShape([10, 489, 489, 3])
New shape --> TensorShape([10, 421, 335, 3])
New shape --> TensorShape([10, 447, 455, 3])
New shape --> TensorShape([10, 355, 382, 3])
New shape --> TensorShape([10, 310, 396, 3])
New shape --> TensorShape([10, 345, 356, 3])
2021-12-01 14:51:04

Je to dobre vyzerá. Avšak stále to nie je práca pre mňa. Keď sa snažím trénovať modelu, to dáva chybu, ako je to uvedené nižšie: INVALID_ARGUMENT: Cannot add tensor to the batch: number of elements does not match. Shapes are: [tensor]: [640,426,3], [batch]: [480,640,3] Aj keď som dal SIZE = (300, 300) v tf.obraz.veľkosť(obrázky, VEĽKOSŤ), dávka má VEĽKOSŤ = (480, 640). A ako ďalší obrázok má inú VEĽKOSŤ = (640, 426), to nepodarilo sa pridať k dávke. To znamená, že nejako to nie je možné uplatniť .mapa() funkcia na každej jednotlivej dávky. Akákoľvek pomoc/nápad ?
Avid Learner

Mohli by ste pridať kód na to, ako ste vytváranie súborov dát na vašu otázku? Myslím, že som tušenia, aký problém môže byť.
AloneTogether

Aktualizoval som otázku, ako som vytváraní súboru. Čaká na vašu odpoveď.
Avid Learner

Aktualizované odpoveď-
AloneTogether

batch_size=16. Je to hádzanie rovnaké chybové s batch_size > 1.
Avid Learner

Jeho ťažké pochopiť, čo presne robíte bez akéhokoľvek prístupu k súboru používate a premenné, ktoré ste definovali niekde inde. Problém je pravdepodobne, že každá dávka nemá obrázky všetkých rovnaký tvar.
AloneTogether

Avid Learner

V iných jazykoch

Táto stránka je v iných jazykoch

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................