D
D
Dmitry2018-11-23 17:47:56
Python
Dmitry, 2018-11-23 17:47:56

How to not pull up the weights every time during asynchronous processing using neural networks?

Good day, everyone!
Faced a problem.
There is a darknet-based neural network . Works great and fast.
The problem is that we get the image via http and process it with python rq , but it drags weights for each task.
Question: How can I make the weights be pulled up only 1 time and used in subsequent asynchronous tasks?
Flask App

import copy
import os

import cv2
import werkzeug
from flask import Flask, flash, request
from redis import Redis
from rq import Queue

from jobs import detect
...
app = Flask(__name__)
q = Queue(connection=Redis())
...

@app.route('/url/', methods=['GET', 'POST'], strict_slashes=False)
def webhook():
    if request.method == 'POST':
        ...
        detect_job = q.enqueue(detect, args=(cam_id, timestamp, file_path)) # распознаем объекты
        ...
    return "", 200

jobs.py
import copy
import urllib

import cv2
from rq import get_current_job

from pydarknet import Image
from utils import write_to_sheet


def detect(spreadsheet_id, timestamp, file_path):
    from detector import detector

    img = Image(cv2.imread(file_path))

    return {
        ...
    }

detector.py
from pydarknet import Detector

detector = Detector(bytes('cfg/yolov3.cfg', encoding='utf-8'),
                    bytes('weights/yolov3.weights', encoding='utf-8'),
                    0,
                    bytes('cfg/coco.data',encoding='utf-8'))

Now the code looks like this. I tried to put in different places, but the result is the same.
I would be grateful for any hint to solve this problem!

Answer the question

In order to leave comments, you need to log in

3 answer(s)
D
Dmitry, 2018-11-28
@pyHammer

After learning more about python rq, we did the following, instead of running rq worker , we run the python script run_rq.py . Almost unchanged example from the documentation.

# run_rq.py
import sys
from rq import Connection

from worker import CustomWorker

# Preload libraries
from pydarknet import Detector

detector = Detector(bytes('cfg/yolov3.cfg', encoding='utf-8'),
                    bytes('weights/yolov3.weights', encoding='utf-8'),
                    0,
                    bytes('cfg/coco.data',encoding='utf-8'))

# Provide queue names to listen to as arguments to this script,
# similar to rq worker
with Connection():
    qs = sys.argv[1:] or ['default']

    w = CustomWorker(qs)
    w.detector = detector
    w.work()


# worker.py
from rq.worker import (DEFAULT_JOB_MONITORING_INTERVAL, DEFAULT_RESULT_TTL,
                       DEFAULT_WORKER_TTL, Worker)

import settings


class CustomWorker(Worker):
    def __init__(self, queues, name=None, default_result_ttl=DEFAULT_RESULT_TTL,
                 connection=None, exc_handler=None, exception_handlers=None,
                 default_worker_ttl=DEFAULT_WORKER_TTL, job_class=None,
                 queue_class=None,
                 job_monitoring_interval=DEFAULT_JOB_MONITORING_INTERVAL):

        super(CustomWorker, self).__init__(queues, name, default_result_ttl,
            connection, exc_handler, exception_handlers, default_worker_ttl,
            job_class, queue_class,job_monitoring_interval)

        self.detector = None

    def execute_job(self, job, queue):
        if not self.detector is None:
            job.detector = self.detector

        super(CustomWorker, self).execute_job(job, queue)

# tasks.py
from rq import get_current_job

import settings


def send():
    job = get_current_job()
    if not job.detector is None:
        # do more work

Further, inside the custom worker, in the execute_job method, we pass the detector instance into the Job.
Thus, each Job instance receives a Detector already calculated in advance.

R
rPman, 2018-11-23
@rPman

I look at the examples on github, everything looks different from yours:
https://github.com/pjreddie/darknet/blob/master/ex...
in the same place, right in the example, a single loading of the neural network and configs is shown and then pictures are sequentially substituted

A
Arseny Kravchenko, 2018-11-25
@Arseny_Info

Now on each call `detector` is re-initialized, you need to do it once at the very beginning and close / curry it into a function that is passed in the task.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question