Одна вещь, которую вы не должны делать, это загружать модель для каждого изображения. Нужно загрузить модель один раз, а затем выполнить вывод на всех ваших 600 изображениях.
Например, вы можете изменить свой код следующим образом:
def load_model(self):
'''Load the model'''
model_metadata = onnx_mxnet.get_model_metadata(self.__model)
data_names = [inputs[0]
for inputs in model_metadata.get('input_tensor_data')]
Batch = namedtuple('Batch', 'data')
ctx = mx.eia() # Set the context to elastic inference
'''Load the model'''
sym, arg, aux = onnx_mxnet.import_model(self.__model)
mod = mx.mod.Module(symbol=sym, data_names=data_names,
context=ctx, label_names=None)
mod.bind(data_shapes=[(data_names[0], image_data.shape)],
label_shapes=None, for_training=False)
mod.set_params(arg_params=arg, aux_params=aux,
allow_missing=True, allow_extra=True)
return mod
def infer(self, mod, target_image_path):
target_image_path = self.__output_directory + '/' + target_image_path
image_data = self.__get_image_data(target_image_path) # Get pixel data
'''Run inference on the image'''
mod.forward(Batch([mx.nd.array(image_data)]))
predictions = mod.get_outputs()[0].asnumpy()
predictions = predictions[0].tolist()
'''Apply emotion labels'''
zipb_object = zip(self.__emotion_labels, predictions)
prediction_dictionary = dict(zipb_object)
return prediction_dictionary
MXNet работает на асинхронном движке, вам не нужно ждать окончания обработки изображения, чтобы поставить в очередь новое.
Некоторые вызовы в MXNet являются асинхронными, например, когда вы вызываете mod.forward()
, эти вызовы немедленно возвращаются и не ожидают вычисления результата. Другие вызовы являются синхронными, например mod.get_outputs()[0].asnumpy()
, при этом данные копируются в ЦП, поэтому они должны быть синхронными. Синхронный вызов между каждой итерацией немного замедляет обработку.
Предполагая, что у вас есть доступ к списку image_paths, вы можете обрабатывать их следующим образом, чтобы минимизировать время ожидания и иметь точку синхронизации только в конце:
results = []
for target_image_path in image_paths:
image_data = self.__get_image_data(target_image_path) # Get pixel data
'''Run inference on the image'''
mod.forward(Batch([mx.nd.array(image_data)]))
results.append(mod.get_outputs()[0])
predictions = [result.asnumpy()[0].tolist() for result in results]
Подробнее об асинхронном программировании в MXNet вы можете прочитать здесь: http://d2l.ai/chapter_computational-performance/async-computation.html
Еще лучше, если вы знаете, что у вас есть N изображений для обработки, вы можете объединить их в пакеты, например, по 16, чтобы увеличить параллельность обработки. Однако это увеличит потребление памяти. Поскольку вы, похоже, используете контекст упругого вывода, ваша общая память будет ограничена, и я бы посоветовал придерживаться меньшего размера пакета, чтобы не рисковать исчерпать память.