Я обучаю ConvNet ( Keras, python ) для некоторых пользовательских наборов данных изображений непосредственно с помощью графического процессора моего ноутбука ( GeForce GTX 1050 ). Контролируя мой GPU во время тренировок, я заметил, что он использовался только на 10% от его емкости или даже меньше. Дальнейшие исследования позволили мне понять, что обучение было узким местом при доступе к данным с моего диска хранения (я использую генератор данных).
Я также заметил, что, хотя диск использовался на 100%, моя Память не использовалась (около 65%). Я подумал: давайте загрузим в память «заранее» следующую партию данных (или несколько следующих партий), пока графический процессор обучается текущей партии, , а затем получим прямой доступ к загруженной партии из Память, избегая дорогостоящих операций чтения с диска . Я искал документацию или код для переполнения стека и других платформ, но не нашел ничего подходящего.
Одним из временных решений, которое я нашел, чтобы избежать этого узкого места чтения диска, было вставка моих данных на диск с операционной системой, который является SSD. Он работал довольно хорошо, сокращая время обучения в 10-15 раз , Но поскольку у меня ограниченная емкость хранилища на диске SSD (100 Гб), это решение не будет работать, когда я перейду к более тяжелым данным (обычно я сейчас использую пересчитанный образ (64, 64), но я планирую увеличить его масштабирование). до (128, 128) или даже больше).
Введите код моего генератора, чтобы вы могли лучше понять ситуацию:
def generator(self, passes=np.inf):
# initialize the epoch count
db = self.db
epochs = 0
# keep looping infinitely -- the model will stop once we have
# reach the desired number of epochs
while epochs < passes:
# shuffle dataset_indices for stochasticity
if self.shuffle == True: np.random.shuffle(self.dataset_indices)
# loop over the HDF5 dataset_indices
for i in np.arange(0, self.numImages, self.batchSize):
X, Y = [], []
if self.gaussian_test == True: # TODO : Add gaussian testing
for j in self.dataset_indices[i:i + self.batchSize]:
y = db[db[self.gen_type + "_indices"][j]]["label"][()]
X.append(np.random.normal(loc=y, scale=0.2, size=(1, 64, 64)))
Y.append(y)
else:
for j in self.dataset_indices[i:i + self.batchSize]:
X.append(db[db[self.gen_type + "_indices"][j]]["array"][()])
Y.append(db[db[self.gen_type + "_indices"][j]]["label"][()])
X = np.array(X)
Y = np.array(Y)
Y = to_categorical(Y, num_classes=6)
# yield a tuple of images and labels
yield (X, Y)
# increment the total number of epochs
epochs += 1
Я не уверен, как поступить, но я почти уверен, что это должно быть возможно ...