3

I am getting the following error when calling keras model.fit().

AttributeError: 'RepeatDataset' object has no attribute 'ndim'

I am using TensorFlow 1.7 and Keras. Unfortunately, I must use TF 1.7. Any idea what's going on? The code, adapted from a tensorflow demo:

import tensorflow as tf
from IPython import embed
from tensorflow.python import keras
from tensorflow.python.keras import layers

model = tf.keras.Sequential()
model.add(layers.Dense(64, input_shape=(32,), activation='relu'))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

model.compile(
    optimizer=tf.train.AdamOptimizer(0.001),
    loss='categorical_crossentropy',
    metrics=['accuracy'])

import numpy as np

# Generate random data using numpy
def random_one_hot_labels(shape):
    n, n_class = shape
    classes = np.random.randint(0, n_class, n)
    labels = np.zeros((n, n_class))
    labels[np.arange(n), classes] = 1
    return labels

data = np.random.random((1000, 32))
labels = random_one_hot_labels((1000, 10))

datasetA = tf.data.Dataset.from_tensor_slices((data, labels))
datasetB = datasetA.batch(32)
dataset = datasetB.repeat()

model.fit(
    dataset, 
    epochs=10,
    steps_per_epoch=30
)
Salvatore
  • 10,815
  • 4
  • 31
  • 69
Robert Lugg
  • 1,090
  • 2
  • 12
  • 40

1 Answers1

1

This error arises because repeat() is returning a generator, which you are passing to fit. fit expects a numpy array which has a defined ndim. Support for generators with fit was added later on. Try using the now deprecated fit_generator instead:

model.fit_generator(
    dataset, 
    epochs=10,
    steps_per_epoch=30
)

Also note that without any arguments, repeat() will use -1, which may or may not be the behavior you are looking for. Something like repeat(1) or repeat(2) is probably what you're looking for. Source for RepeatDataset as of release 1.7:

class RepeatDataset(Dataset):
  """A `Dataset` that repeats its input several times."""

  def __init__(self, input_dataset, count):
    """See `Dataset.repeat()` for details."""
    super(RepeatDataset, self).__init__()
    self._input_dataset = input_dataset
    if count is None:
      self._count = constant_op.constant(-1, dtype=dtypes.int64, name="count")
    else:
      self._count = ops.convert_to_tensor(
          count, dtype=dtypes.int64, name="count")

I tried reproducing it, but it'll take me a little more effort to be able to get the right version installed.

If that doesn't work, it may be worth it to try to manually iterate through your dataset generator and create a numpy array from it first, then pass that to fit. I'm not sure if there's a Keras way of doing this in 1.7, but this answer might be useful if you have to go down that route.

Salvatore
  • 10,815
  • 4
  • 31
  • 69