Tensorflow Veri Kümeleri: Veri kümesinden sonra toplu iş başına görüntüleri kırpın / yeniden boyutlandırın.toplu()

0

Soru

Toplu iş başına görüntüleri kırpmak / yeniden boyutlandırmak mümkün mü ?

Aşağıdaki gibi Tensorflow veri kümesi API'sini kullanıyorum:

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

Toplu iş içinde tüm görüntülerin aynı boyutta olmasını istiyorum. Bununla birlikte, gruplar arasında farklı boyutlara sahip olabilir.

Örneğin, 1. parti şeklin tüm görüntülerine sahiptir (batch_size, 300, 300, 3). Bir sonraki parti şekil görüntülerine sahip olabilir (batch_size, 224, 224, 3). Başka bir toplu iş, şekil görüntülerine sahip olabilir (batch_size, 400, 400, 3).

Temel olarak, dinamik olarak şekillendirilmiş partilere sahip olmak istiyorum, ancak parti içindeki tüm görüntülerin statik şekilleri var.

Eğer aşağıdaki gibi yaparsak:

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

Yukarıdakileri yapar .map() her parti için ayrı ayrı mı yoksa tüm veri kümesi üzerinde mi uygulanır ?

Yukarıdaysa .map() her parti için ayrı ayrı geçerli değildir, bunu nasıl yapabiliriz ? Veri kümesinden sonra herhangi bir yineleyiciyi tanımlayabilir miyiz?batch(), tf uygulayın.görüntü.toplu iş başına her görüntünün üzerine crop_and_resize() ve daha sonra dataset kullanın.dönüştürülen tüm partileri birleştirmek için concatenate ()?

Veri kümesini aşağıdaki gibi oluşturuyorum:

# 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

En iyi cevabı

1

Genel olarak, böyle bir şey deneyebilirsiniz:

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]

Ayrıca kullanabilirsiniz tf.image.resize_with_crop_or_pad Eğer isterseniz:

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

Bunu kullanarak unutmayın repeat() sonsuz bir veri kümesi oluşturur.

Güncelleme 1

Her parti için rastgele bir boyut istiyorsanız, bunun gibi bir şey deneyin:

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]

Güncelleme 2

Herhangi bir parti boyutu için çalışan çok esnek bir seçenek şöyle görünür:

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

Bu iyi görünüyor. Ancak hala benim için işe yaramıyor. Modeli eğitmeye çalıştığımda, aşağıdaki gibi hata veriyor: INVALID_ARGUMENT: Cannot add tensor to the batch: number of elements does not match. Shapes are: [tensor]: [640,426,3], [batch]: [480,640,3] Tf'de SİZE = (300, 300) vermiş olmama rağmen.görüntü.yeniden boyutlandır(resimler, BOYUT), toplu iş BOYUTU = (480, 640). Ve bir sonraki görüntü farklı boyutta olduğu için = (640, 426), partiye eklenemedi. Bu, bir şekilde uygulanamayacağı anlamına geliyor .her bir partide map() işlevi. Herhangi bir yardım/fikir ?
Avid Learner

Sorunuza veri kümelerinizi nasıl oluşturduğunuzla ilgili kodu ekleyebilir misiniz? Sanırım sorunun ne olabileceğine dair bir fikrim var.
AloneTogether

Soruyu veri kümesini nasıl oluşturduğumla güncelledim. Lütfen cevap bekliyorum.
Avid Learner

Güncellenmiş cevap-
AloneTogether

batch_size = 16. Batch_size > 1 ile aynı hatayı atıyor.
Avid Learner

Kullandığınız veri kümesine ve başka bir yerde tanımladığınız değişkenlere erişiminiz olmadan tam olarak ne yaptığınızı anlamak zor. Sorun, muhtemelen her partinin aynı şekle sahip görüntülere sahip olmamasıdır.
AloneTogether

Avid Learner

Diğer dillerde

Bu sayfa diğer dillerde

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