Как добавить измерение к объекту класса tenensflow python .data.ops.dataset_ops.DatasetV1Adapter в Python? - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть набор данных изображения, который я хочу использовать для обучения CNN. Я инициализировал объект класса tenensflow. python .data.ops.dataset_ops.DatasetV1Adapter, который, как я понимаю, по сути является итератором, который кэширует изображения поездов в пакетах, так что весь набор данных не нужно загружать сразу.

Я получил эту ошибку при попытке вызвать model.fit ():

ValueError: Error when checking input: expected conv2d_input to have 4 dimensions, but got array with 
shape (None, 1)

Я понимаю, что мне нужно добавить измерение к входу моей модели. Я хочу добавить измерение каналов к моим изображениям. Я пытался использовать np.expand_dims () и tf.expand_dims () в моем классе «tenensflow. python .data.ops.dataset_ops.DatasetV1Adapter», но первый изменяет тип объекта, а второй не поддерживается для объекта объект класса. Любая помощь приветствуется. Ниже приведена структура моей модели:

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))


model.summary()

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
history = model.fit(train_data, epochs=10, validation_data=(val_data),steps_per_epoch=x, 
validation_steps=y)

Я следовал учебному пособию в приведенном здесь примере, https://www.tensorflow.org/tutorials/load_data/images, но попытался создать и загрузить свой собственный набор данных.

Ниже мой tf конвейер:

BATCH_SIZE = 32
IMG_HEIGHT = 224
IMG_WIDTH = 224
STEPS_PER_EPOCH = np.ceil(image_count/BATCH_SIZE)

data_dir = 'C:\\Users\\rtlum\\Documents\\DataSci_Projects\\PythonTensorFlowProjects\\google-images-download\\images'
list_ds = tf.data.Dataset.list_files(str(data_dir+"*.jpg"))  #Make dataset of file paths
class_names = ['sad', 'angry']

size = 0
for count in enumerate(list_ds):
    size += 1
val_data_size = size * .2

for f in list_ds.take(5):#test for correct file paths
  print(f.numpy())

def get_label(file_path):
  # convert the path to a list of path components
  parts = tf.strings.split(file_path, os.path.sep)
  # The second to last is the class-directory
  return parts[-2] == class_names

def decode_img(img):
  # convert the compressed string to a 3D uint8 tensor
  img = tf.image.decode_jpeg(img, channels=3)
  # Use `convert_image_dtype` to convert to floats in the [0,1] range.
  img = tf.image.convert_image_dtype(img, tf.float32)
  # resize the image to the desired size.
  return tf.image.resize(img, [64, 64])

def process_path(file_path):
  label = get_label(file_path)
  # load the raw data from the file as a string
  img = tf.io.read_file(file_path)
  img = decode_img(img)
  return img, label

# Set `num_parallel_calls` so multiple images are loaded/processed in parallel.
labeled_ds = list_ds.map(process_path)

for image, label in labeled_ds.take(1):
  print("Image shape: ", image.numpy().shape)
  print("Label: ", label.numpy())

shuffle_buffer_size=1000

def prepare_for_training(ds, cache=True, shuffle_buffer_size=1000):
  # This is a small dataset, only load it once, and keep it in memory.
  # use `.cache(filename)` to cache preprocessing work for datasets that don't
  # fit in memory.
  if cache:
    if isinstance(cache, str):
      ds = ds.cache(cache)
    else:
      ds = ds.cache()
  ds = ds.shuffle(buffer_size=shuffle_buffer_size)
  # Repeat forever
  ds = ds.repeat()
  ds = ds.batch(BATCH_SIZE)
  # `prefetch` lets the dataset fetch batches in the background while the model
  # is training.
  ds = ds.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
  return ds

ds = prepare_for_training(list_ds)


val_data = ds.take(int(val_data_size))
train_data = ds.skip(int(val_data_size))

1 Ответ

0 голосов
/ 14 апреля 2020

Две проблемы,

Кажется, что ваш шаблон для сопоставления каталогов неверен.

При просмотре кода кажется, что ваши данные должны соответствовать структуре, такой как

data
 |- sad
     |- 1.jpg
        ...
 |- angry
     |- 1.jpg
        ...

Это не то, что вы подходите, когда говорите,

tf.data.Dataset.list_files(str(data_dir+"*.jpg"))

должно быть,

tf.data.Dataset.list_files(str(data_dir+os.path.sep+"*"+os.path.sep+"*.jpg"))

У вас неправильный набор данных,

У вас есть,

ds = prepare_for_training(list_ds)

должно быть,

ds = prepare_for_training(labeled_ds)

Другое проблемы,

  • Вы изменяете размер данных до 64x64, но ваша модель принимает модель 32x32.
  • У вас есть 2 метки, но ваша модель ожидает 10 классов.
  • У вас нет строки компиляции модели (т.е. model.compile(...))
...