Skip to content

ImageDataGenerator.flow_from_directory models neither its iteration protocol nor the (x, y) batch tuple it yields #830

Description

@khatchad

What The Summary Models

The summary for tensorflow/keras/preprocessing/image/flow_from_directory returns a fresh instance of its own class and nothing else:

<class name="flow_from_directory" allocatable="true">
  <method name="do" descriptor="()LRoot;" numArgs="16" paramNames="self directory target_size ...">
    <new def="x" class="Ltensorflow/keras/preprocessing/image/flow_from_directory"/>
    <return value="x"/>
  </method>
</class>

The class declares no __iter__ and no __next__, and no summary anywhere creates the value the iterator actually produces.

What The API Does

A DirectoryIterator is an iterable of batches, and each batch is a two-element tuple (x, y): a rank-4 float32 image batch and a label array whose shape follows class_mode. The ordinary consuming idiom below therefore yields a tuple of two tensors at run time, where the analysis sees an opaque flow_from_directory instance with no element structure and no tensor typing on either position.

train_generator = ImageDataGenerator(rescale=1.0 / 255).flow_from_directory(directory, target_size=(112, 112), batch_size=512, class_mode="categorical")
train_dataset = iter(train_generator)
batch = next(train_dataset)     # (images, labels)

Why It Matters

This is the standard image-classification input pipeline, and the batch is normally forwarded straight into a training step that destructures it:

def train_step(inputs):
    images, labels = inputs
    ...

distributed_train_step(next(train_dataset))

Anything reasoning about that parameter's structure therefore has nothing to reason from: the tuple arity, the image batch's rank-4 float32 typing, and the label position all go missing at the generator boundary rather than at the destructuring. I hit this while reproducing ponder-lab/Hybridize-Functions-Refactoring#888, where the same tuple-parameter shape works when the tuple is visible in source and stays invisible when it arrives through this generator.

Suggested Shape

Give the class an iteration model whose element is a two-position container holding a dense rank-4 float32 tensor and a label tensor, so next(iter(gen)) carries the tuple structure. Both target_size and batch_size are summary parameters, so the image batch's extents are recoverable rather than ⊤ where the call passes literals. The label position's shape depends on class_mode, which is also a parameter, though a dtype-only element there would already be a large improvement over an opaque object.

Verified by reading the summary in com.ibm.wala.cast.python.ml/data/tensorflow.xml at the currently consumed release. I have not attributed any particular downstream verdict to it beyond the missing structure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions