Контекст

Во время обучения нейронной сети я понял, что время, затрачиваемое на пакет, увеличилось, когда я увеличил размер своего набора данных (без изменения размера пакета). Важная часть заключается в том, что мне нужно получить 20 .npy файлов на каждую точку данных, это число не зависит от размера набора данных .

Проблема

Обучение идет от 2 с / итерация до 10 с / итерация ... Нет очевидной причины, по которой обучение могло бы занять больше времени. Однако мне удалось найти узкое место. Похоже, это связано с загрузкой файлов .npy.


Чтобы воспроизвести это поведение, вот небольшой сценарий, который вы можете запустить для создания 10 000 фиктивных файлов .npy:

def path(i):
    return os.sep.join(('../datasets/test', str(i)))

def create_dummy_files(N=10000):
    for i in range(N):
        x = np.random.random((100, 100))
        np.save(path(random.getrandbits(128)), x)

Затем вы можете запустить следующие два сценария и сравнить их самостоятельно:

  • Первый сценарий, в котором случайным образом выбираются и загружаются 20 файлов .npy:

    L = os.listdir('../datasets/test')
    S = random.sample(L, 20)
    for s in S:
        np.load(path(s)) # <- timed this
    
  • Вторая версия, где выбираются и загружаются 20 .npy ' последовательных файлов.

    L = os.listdir('../datasets/test')
    i = 100
    S = L[i: i + 20]
    for s in S:
        np.load(path(s)) # <- timed this
    

Я протестировал оба сценария и запустил их по 100 раз каждый (во втором сценарии я использовал счетчик итераций как значение для i, чтобы одни и те же файлы не загружались дважды). Я завершил строку np.load(path(s)) вызовами time.time(). Я не рассчитываю выборку, а только загрузку . Вот результаты:

  • Случайные нагрузки (время примерно составляет от 0,1 до 0,4 с, в среднем 0,25 с ):

    введите описание изображения здесь

  • Неслучайные нагрузки (время примерно составляет от 0,010 до 0,014 с, в среднем 0,01 с ):

    введите описание изображения здесь


Я предполагаю, что это время связано с активностью процессора при загрузке скриптов. Однако это не объясняет этот пробел. Почему эти два результата такие разные? Есть ли какое-то отношение к способу индексации файлов?

Изменить : я напечатал S в случайном образце скрипта, скопировал список из 20 имен файлов, затем снова запустил его с S как списком, определенным буквально. Время, которое потребовалось, сопоставимо с «последовательным» сценарием. Это означает, что это не связано с тем, что файлы не являются последовательными в fs или чем-то еще. Кажется, что случайная выборка засчитывается в таймере, но время определяется как:

t = time.time()
np.load(path(s))
print(time.time() - t)

Я также пробовал обернуть np.load ( исключительно ) с cProfile: результат тот же.

2
Ivan 27 Ноя 2020 в 00:11

1 ответ

Лучший ответ

Я сказал:

Я протестировал оба сценария и запускал их по 100 раз каждый (во втором сценарии я использовал счетчик итераций в качестве значения для i, поэтому одни и те же файлы не загружаются дважды)

Но, как упоминалось в tevemadar

i следует рандомизировать

Я полностью испортил операцию выбора разных файлов во второй версии. Мой код синхронизировал скрипты 100 раз следующим образом:

for i in trange(100):
   if rand:
      S = random.sample(L, 20)
   else:
      S = L[i: i+20] # <- every loop there's only 1 new file added in the selection, 
                     #    19 files will have already been cached in the previous fetch

Для второго скрипта это должно быть S = L[100*i, 100*i+20]!

И да, по срокам результаты сопоставимы.

1
Ivan 29 Ноя 2020 в 10:54