Tensorflow kann "image.shape" nicht von der Methode in "dataset.map (mapFn)" abrufen

10

Ich versuche , das zu tun tensorflowÄquivalent torch.transforms.Resize(TRAIN_IMAGE_SIZE), das die die Größe kleinsten zu Bilddimension TRAIN_IMAGE_SIZE. Etwas wie das

def transforms(filename):
  parts = tf.strings.split(filename, '/')
  label = parts[-2]

  image = tf.io.read_file(filename)
  image = tf.image.decode_jpeg(image)
  image = tf.image.convert_image_dtype(image, tf.float32)

  # this doesn't work with Dataset.map() because image.shape=(None,None,3) from Dataset.map()
  image = largest_sq_crop(image) 

  image = tf.image.resize(image, (256,256))
  return image, label

list_ds = tf.data.Dataset.list_files('{}/*/*'.format(DATASET_PATH))
images_ds = list_ds.map(transforms).batch(4)

Die einfache Antwort lautet hier: Tensorflow : Beschneidet den größten zentralen quadratischen Bereich des Bildes

Aber wenn ich die Methode mit benutze tf.data.Dataset.map(transforms), komme ich shape=(None,None,3)von innen largest_sq_crop(image). Die Methode funktioniert gut, wenn ich sie normal aufrufe.

Michael
quelle
1
Ich glaube, das Problem hat mit der Tatsache zu tun, dass sie EagerTensorsnicht verfügbar sind, Dataset.map()sodass die Form unbekannt ist. Gibt es eine Problemumgehung?
Michael
Können Sie die Definition von aufnehmen largest_sq_crop?
Jakub

Antworten:

1

Ich habe die Antwort gefunden. Es hatte damit zu tun, dass meine Größenänderungsmethode bei eifriger Ausführung gut funktionierte, z. B. tf.executing_eagerly()==Truefehlschlug, wenn sie innerhalb verwendet wurde dataset.map(). Anscheinend in dieser Ausführungsumgebung tf.executing_eagerly()==False.

Mein Fehler lag in der Art und Weise, wie ich die Form des Bildes entpackte, um Abmessungen für die Skalierung zu erhalten. Die Ausführung von Tensorflow-Diagrammen scheint den Zugriff auf das tensor.shapeTupel nicht zu unterstützen .

  # wrong
  b,h,w,c = img.shape
  print("ERR> ", h,w,c)
  # ERR>  None None 3

  # also wrong
  b = img.shape[0]
  h = img.shape[1]
  w = img.shape[2]
  c = img.shape[3]
  print("ERR> ", h,w,c)
  # ERR>  None None 3

  # but this works!!!
  shape = tf.shape(img)
  b = shape[0]
  h = shape[1]
  w = shape[2]
  c = shape[3]
  img = tf.reshape( img, (-1,h,w,c))
  print("OK> ", h,w,c)
  # OK>  Tensor("strided_slice_2:0", shape=(), dtype=int32) Tensor("strided_slice_3:0", shape=(), dtype=int32) Tensor("strided_slice_4:0", shape=(), dtype=int32)

Ich habe in meiner dataset.map()Funktion nachgeschaltete Formabmessungen verwendet, und es wurde die folgende Ausnahme ausgelöst, da Noneanstelle eines Werts ein Wert angezeigt wurde.

TypeError: Failed to convert object of type <class 'tuple'> to Tensor. Contents: (-1, None, None, 3). Consider casting elements to a supported type.

Als ich zum manuellen Auspacken der Form überging tf.shape(), funktionierte alles einwandfrei.

Michael
quelle