Частично случайные элементы в пакете после Dataset.shuffle () - PullRequest
0 голосов
/ 02 марта 2020

Я использую tf.data.Dataset и tf.keras в TF2.1 для обучения на наборе данных. Но я видел странное поведение, что полученные партии не показываются полностью случайно, как я ожидал. Я имею в виду, я обычно вижу элементы только из 2 классов в одном пакете, даже если мой набор данных имеет 4 класса. Мой код выглядит следующим образом:

def process_train_sample(file_path):
  sp = tf.strings.regex_replace(file_path, train_data_dir, '')
  cls = tf.math.argmax(tf.cast(tf.math.equal(tf.strings.split(sp, os.path.sep)[0],['A','B','C','D']), tf.int64))

  img = tf.io.read_file(file_path)
  img = tf.image.decode_jpeg(img, channels=3)  # RGB
  img = tf.image.resize(img, (224, 224))
  img = tf.cast(img, tf.float32)
  img = img - np.array([123.68, 116.779, 103.939])
  img = img / 255.0
  cls = tf.expand_dims(cls, 0)
  return img, cls

train_data_list = glob.glob(os.path.join(train_data_dir, '**', '*.jpg'), recursive=True)
train_data_list = tf.data.Dataset.from_tensor_slices(train_data_list)
train_ds = train_data_list.map(process_train_sample, num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_ds = train_ds.shuffle(10000)
train_ds = train_ds.batch(batch_size)

for img,  cls in train_ds.take(10):
  print('img: ', img.numpy().shape,  'cls: ', cls.numpy())

model.compile(loss='categorical_crossentropy',  
      optimizer=optimizers.SGD(lr=0.0001, momentum=0.9),
      metrics=['categorical_accuracy', 'categorical_crossentropy'])
model.fit(train_ds, epochs=50)

Когда я тренируюсь на наборе данных с 4 классами - A, B, C, D, я обнаружил, что точность обучения не увеличивается стабильно, вместо этого она колеблется вверх и вниз. Затем я проверил свой конвейер ввода данных, показав метки пакета за партией, как в for-l oop, и обнаружил, что каждая партия содержит только элементы из 2 классов вместо 4. Кажется, набор данных не перетасовывается, как я ожидал, что может заставить точность не увеличиваться постоянно. Но я не вижу, что не так в моем коде.

1 Ответ

0 голосов
/ 03 марта 2020

В .shuffle(10 000), 10 000 - это размер буфера, что означает, что он будет производить выборку из первых 10 000 изображений. Поскольку у вас есть ~ 30 000 изображений, это приводит к изображениям только из первого и второго классов в первых партиях. Продолжая тренировку, вы начнете делать выборки из класса (1,2,3), затем только (2,3), затем (2,3,4), затем (3,4), затем (3,4, 1), затем (4,1), затем (4,1,2), затем (1,2), затем (1,2,3) и т. Д. Попробуйте установить размер буфера перемешивания до 30 000, если у вас есть память, или если у вас нет, сначала перетасуйте список путей, а затем используйте большой размер пакета.

...