Для ускорения обучения модели представляется целесообразным заполнять / генерировать пакеты на процессоре и параллельно проводить обучение модели на графическом процессоре.Для этого на Python может быть написан класс генератора, который наследует класс Sequence
.
Вот ссылка на документацию: https://www.tensorflow.org/api_docs/python/tf/keras/utils/Sequence
Важная вещь, о которой говорится в документеis:
Sequence
- это более безопасный способ многопроцессорной обработки.Эта структура гарантирует, что сеть будет обучаться только один раз для каждой выборки за эпоху, что не относится к генераторам.
И это дает простой пример кода:
from skimage.io import imread
from skimage.transform import resize
import numpy as np
import math
# Here, `x_set` is list of path to the images
# and `y_set` are the associated classes.
class CIFAR10Sequence(Sequence):
def __init__(self, x_set, y_set, batch_size):
self.x, self.y = x_set, y_set
self.batch_size = batch_size
def __len__(self):
return math.ceil(len(self.x) / self.batch_size)
def __getitem__(self, idx):
batch_x = self.x[idx * self.batch_size:(idx + 1) *
self.batch_size]
batch_y = self.y[idx * self.batch_size:(idx + 1) *
self.batch_size]
return np.array([
resize(imread(file_name), (200, 200))
for file_name in batch_x]), np.array(batch_y)
Что, на мой взгляд, в идеале нужно сделать в модели, это создать экземпляр этого класса генератора и передать его функции fit_generator(...)
.
gen = CIFAR10Sequence(x_set, y_set, batch_size)
# Train the model
model.fit_generator(generator=gen,
use_multiprocessing=True,
workers=6)
Вот цитата из документации Keras:
Использование keras.utils.Sequence
гарантирует порядок и гарантирует однократное использование каждого входа за эпоху при использовании use_multiprocessing=True
.
В этой форме я предполагаю, что эта установка является поточно-ориентированной. Вопрос 1) Правильно ли мое предположение?
Одна сбивающая с толку вещь заключается в том, что параметр use_multiprocessing
не может быть установлен в True в Windows 10. Keras не допускает этого;По-видимому, это может быть установлено в True только в Linux.(Я не знаю, как это происходит на других платформах.) Но для параметра workers
все равно можно установить значение, которое больше 0.
Давайте посмотрим на определение этих двух параметров:
workers:
Целое число.Максимальное количество процессов, которые могут ускоряться при использовании потоков на основе процессов.Если не указано, рабочие по умолчанию будут равны 1. Если 0, генератор будет выполняться в главном потоке.
use_multiprocessing:
Boolean.Если True, используйте основанные на процессах потоки.Если не указано, use_multiprocessing по умолчанию будет False.Обратите внимание, что поскольку эта реализация опирается на многопроцессорность, вы не должны передавать невыгружаемые аргументы генератору, поскольку их нелегко передать дочерним процессам.
Итак, используя параметр workers
представляется возможным создать несколько процессов для ускорения обучения независимо от того, является ли use_multiprocessing
Истиной или нет.
Если кто-то хочет использовать класс генератора, наследующий Sequence
( в Windows10 ), он / она должен установить для use_multiprocessing
значение False следующим образом:
gen = CIFAR10Sequence(x_set, y_set, batch_size)
# Train the model
model.fit_generator(generator=gen,
use_multiprocessing=False, # CHANGED
workers=6)
И здесь все еще выполняется несколько процессов, потому что рабочий = 6.
Вопрос 2) Эта настройка все еще поддерживает потокобезопасность или характеристика потока безопасна теперь, если для параметра use_multiprocessing
установлено значение False?Я не могу объяснить это на основании документации.
Вопрос 3) По-прежнему относится к этой теме ... Когда обучение выполняется таким образом, когда данные генерируются процессором, а обучение на графическом процессореесли обучаемая модель является мелкой, загрузка графического процессора заканчивается на очень низком уровне, а загрузка процессора становится значительно выше, поскольку графический процессор продолжает ожидать данные, поступающие из процессора.В таких случаях, есть ли способ использовать ресурсы GPU для генерации данных?