Tensorflow Seturi de date: a Culturilor/Redimensiona imagini pe lot după setul de date.lot()

0

Problema

Este posibil sa Culturilor/Redimensiona imagini pe lot ?

Eu sunt, folosind Tensorflow set de date API-ul de mai jos:

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

Vreau, în lotul toate imaginile ar trebui să aibă aceeași dimensiune. Cu toate acestea, pe loturi, acesta poate avea diferite dimensiuni.

De exemplu, lot 1 are toate imaginile de forma (batch_size, 300, 300, 3). Următorul lot poate avea imagini de formă (batch_size, 224, 224, 3). Un alt lot poate avea imagini de formă (batch_size, 400, 400, 3).

Practic vreau sa am dymanically în formă de loturi, cu toate acestea, toate imaginile din lot au forme statice.

Dacă vom face după cum urmează:

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

Are cele de mai sus .harta() se aplică pentru fiecare lot separat sau asupra întregului set de date ?

În cazul de mai sus .harta() nu se aplică pentru fiecare lot separat, cum putem face acest lucru ? Putem defini orice iterator după setul de date.lot(), se aplică tf.imagine.crop_and_resize() peste fiecare imagine pe lot și mai târziu folosi setul de date.join() pentru a combina toate transformate loturi ?

Am creat setul de date de mai jos:

# 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

Cel mai bun răspuns

1

În general, poți încerca ceva de genul asta:

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]

Ai putea folosi, de asemenea, tf.image.resize_with_crop_or_pad dacă doriți:

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))

Rețineți că utilizarea repeat() va crea un infinit de date.

Update 1

Dacă doriți o dimensiune aleatorie pentru fiecare lot, încercați ceva de genul asta:

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]

Update 2

O opțiune flexibilă, care funcționează pentru orice mărime a lotului ar arata astfel:

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

Se pare bun. Cu toate acestea, încă nu este de lucru pentru mine. Când m-am încercați să tren model, vă oferă eroare de genul de mai jos: INVALID_ARGUMENT: Cannot add tensor to the batch: number of elements does not match. Shapes are: [tensor]: [640,426,3], [batch]: [480,640,3] Chiar dacă am dat SIZE = (300, 300), în tf.imagine.resize(imagini, DIMENSIUNE), lot SIZE = (480, 640). Și, ca în următoarea imagine are DIMENSIUNI diferite = (640, 426), acesta nu a reușit să-l adăugați la lot. Asta înseamnă cumva că nu e capabil să aplice .harta (funcția) pe fiecare lot. Orice ajutor/idee ?
Avid Learner

Ai putea adăuga codul de pe modul în care sunt crearea de seturi de date la întrebarea ta? Cred că am o idee despre ce problema ar putea fi.
AloneTogether

Am actualizat întrebarea cu cât sunt crearea setului de date. De așteptare pentru răspunsul dumneavoastră.
Avid Learner

Actualizat răspuns-
AloneTogether

batch_size=16. Se dă aceeași eroare cu batch_size > 1.
Avid Learner

Este greu de înțeles exact ceea ce faci fara a avea acces la setul de date pe care îl utilizați și variabilele pe care le-am definit în altă parte. Problema este, probabil, că fiecare lot nu au imagini toate de aceeași formă.
AloneTogether

Avid Learner

În alte limbi

Această pagină este în alte limbi

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