GluonCV - использовать графический процессор для вывода при обнаружении объектов - PullRequest
0 голосов
/ 20 января 2020

Я использую GluonCV для обнаружения объектов, в Ubuntu 18.04 и с Python.
я заново обучил модель ssd_512_resnet50_v1_custom для пользовательского набора данных, и я хотел проверить FPS логического вывода на сервере с графическим процессором GeForce RTX 2080 Ti (отлично работает на процессоре моего компьютера).

Итак, я работаю

def main():

    try:
        a = mx.nd.zeros((1,), ctx=mx.gpu(1))
        ctx = [mx.gpu(1)]
    except:
        ctx = [mx.cpu()]

    # -------------------------
    # Load model
    # -------------------------
    classes = ['Guitar', 'face']
    net = model_zoo.get_model('ssd_512_resnet50_v1_custom', ctx=ctx, classes=classes, pretrained_base=False)
    net.load_parameters('saved_weights/test_000/ep_30.params')

    # Load the webcam handler
    cap = cv2.VideoCapture("video/video_01.mp4")

    count_frame = 0

    loading_frame_FPSs = np.zeros(844)
    pre_processing_FPSs = np.zeros(844)
    inference_FPSs = np.zeros(844)
    total_FPSs = np.zeros(844)

    while(True):
        print(f"Frame: {count_frame}")

        total_t_frame = 0

        #######
        start_t = time.time()
        #######
        # Load frame from the camera
        ret, frame = cap.read()
        #######
        stop_t = time.time()
        total_t_frame += (stop_t - start_t)
        FPS = 1/(stop_t-start_t)
        loading_frame_FPSs[count_frame] = FPS
        print(f"\tloading frame time = {(stop_t-start_t)} -> FPS = {FPS}")
        #######

        if (cv2.waitKey(25) & 0xFF == ord('q')) or (ret == False):
            cv2.destroyAllWindows()
            cap.release()
            print("Done!!!")
            break

        #######
        start_t = time.time()
        #######
        # Image pre-processing
        frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8')
        rgb_nd, frame = gcv.data.transforms.presets.ssd.transform_test(frame, short=512, max_size=700)
        #######
        stop_t = time.time()
        total_t_frame += (stop_t - start_t)
        FPS = 1/(stop_t-start_t)
        pre_processing_FPSs[count_frame] = FPS
        print(f"\timage pre-processing time = {(stop_t-start_t)} -> FPS = {FPS}")
        #######

        #######
        start_t = time.time()
        #######
        # Run frame through network
        class_IDs, scores, bounding_boxes = net(rgb_nd)
        #######
        stop_t = time.time()
        total_t_frame += (stop_t - start_t)
        FPS = 1/(stop_t-start_t)
        inference_FPSs[count_frame] = FPS
        print(f"\tinference time = {(stop_t-start_t)} -> FPS = {1/(stop_t-start_t)}")
        #######

        print(f"\tTotal frame FPS = {1/total_t_frame}")
        total_FPSs[count_frame] = 1/total_t_frame


        count_frame += 1


    cv2.destroyAllWindows()
    cap.release()


    print(f"Average FPS for:")
    print(f"\tloading frame: {np.average(loading_frame_FPSs)}")
    print(f"\tpre-processingg frame: {np.average(pre_processing_FPSs)}")
    print(f"\tinference frame: {np.average(inference_FPSs)}")
    print(f"\ttotal process: {np.average(total_FPSs)}")



if __name__ == "__main__":
    main()

Итак, в основном я измеряю требуемое время для каждого шага логического вывода (загрузка кадра, изменение размера, логический вывод) и вычисления FPS для каждого из этих шагов и всего.

Глядя на вывод:

Average FPS for:
loading frame: 813.3313447171636
pre-processingg frame: 10.488629638752457
inference frame: 101.50787170217922
total process: 9.300166489874748

, кажется, что Узкое место в основном определяется предварительной обработкой изображений. При проверке вывода nvidia-smi я получил:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.56       Driver Version: 418.56       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 208...  Off  | 00000000:18:00.0 Off |                  N/A |
| 36%   63C    P0    79W / 250W |     10MiB / 10989MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce RTX 208...  Off  | 00000000:3B:00.0 Off |                  N/A |
| 37%   65C    P2    84W / 250W |    715MiB / 10989MiB |      5%      Default |
+-------------------------------+----------------------+----------------------+
|   2  GeForce RTX 208...  Off  | 00000000:86:00.0 Off |                  N/A |
| 37%   64C    P0    70W / 250W |     10MiB / 10989MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  GeForce RTX 208...  Off  | 00000000:AF:00.0 Off |                  N/A |
| 37%   62C    P2   116W / 250W |   2401MiB / 10989MiB |     47%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    1      2955      C   python                                       705MiB |
|    3     15558      C   python                                      2389MiB |
+-----------------------------------------------------------------------------+


, что, я думаю, разумно, так как для вывода я использую только одно изображение за раз, поэтому я не ожидаю использования графического процессора быть таким же высоким, как во время тренировки.

Однако на данный момент есть пара вещей, в которых я не уверен:

  1. при чтении о среднем FPS о моделях SSD они обычно упоминаются в диапазоне 25-30 FPS. Как мне добраться до этих значений? Это все о предварительной обработке изображения?
  2. Я пытался изменить блок
try:
    a = mx.nd.zeros((1,), ctx=mx.gpu(1))
    ctx = [mx.gpu(1)]
except:
    ctx = [mx.cpu()]

просто:

ctx = mx.gpu(1)

, но кажется, что это способ запуска процесса на CPU (даже те 715 МБ не заняты на GPU). Почему это так?

Ответы [ 3 ]

1 голос
/ 10 февраля 2020

Я не загружал изображения на GPU должным образом, мне пришлось добавить строку перед запуском вывода:

rgb_nd = rgb_nd.as_in_context(ctx)
class_IDs, scores, bounding_boxes = net(rgb_nd)

, что увеличило использование памяти GPU и решило проблему с начальной инициализацией контекста.

Кроме того, при оценке скорости вывода мне приходилось использовать блок для ожидания фактической доступности результатов, поэтому теперь я получаю частоту кадров вывода в диапазоне 20 кадров в секунду, как и ожидалось:

    class_IDs, scores, bounding_boxes = net(rgb_nd)
    if isinstance(class_IDs, mx.ndarray.ndarray.NDArray):
        class_IDs.wait_to_read()
    if isinstance(scores, mx.ndarray.ndarray.NDArray):
        scores.wait_to_read()
    if isinstance(bounding_boxes, mx.ndarray.ndarray.NDArray):
        bounding_boxes.wait_to_read()
0 голосов
/ 20 января 2020

Вы пробовали скрипт на следующей странице? Это выполняет то же самое? Возможно, используйте вашу модель и попробуйте использовать тот же подход предварительной обработки изображений

https://github.com/dmlc/gluon-cv/blob/master/scripts/detection/demo_webcam_run.py

0 голосов
/ 20 января 2020

Как насчет ctx = mx.gpu(0) или ctx = mx.gpu()?

...