Videó a Cloud Object Detectorról a Raspberry Pi-n

prológus

Most egy videó kering az interneten, amelyen látható, hogy a Tesla robotpilótája hogyan látja az utat.

Régóta vágyom arra, hogy detektorral dúsított videót sugározzak, méghozzá valós időben.

Videó a Cloud Object Detectorról a Raspberry Pi-n

A probléma az, hogy a Raspberry-ről szeretnék videót sugározni, és a neurális hálózati detektor teljesítménye hagy kívánnivalót maga után.

Intel Neural Computer Stick

Különféle megoldásokon gondolkodtam.

В utolsó cikk kísérletezett az Intel Neural Computer Stick segítségével. A hardver erős, de saját hálózati formátumot igényel.

Annak ellenére, hogy az Intel konvertereket biztosít a főbb keretrendszerekhez, számos buktató van.

Például előfordulhat, hogy a kívánt hálózat formátuma nem kompatibilis, és ha kompatibilis, akkor előfordulhat, hogy egyes rétegek nem támogatottak az eszközön, ha pedig támogatottak, akkor a konverziós folyamat során hibák léphetnek fel, amelyek következtében furcsa dolgokat kapunk a kimeneten.

Általánosságban elmondható, hogy ha valamilyen tetszőleges neurális hálózatot szeretne, akkor az NCS-el nem működik. Ezért úgy döntöttem, hogy megpróbálom megoldani a problémát a legelterjedtebb és legelérhetőbb eszközökkel.

felhő

A helyi hardveres megoldás kézenfekvő alternatívája a felhő használata.

Kész lehetőségek – vadul a szemem.

Minden vezető:

... És több tucat kevésbé ismert.

Egyáltalán nem könnyű választani e fajta közül.

És úgy döntöttem, hogy nem választok, hanem becsomagolom a jó öreg működő sémát az OpenCV-n a Dockerbe, és futtatom a felhőben.

Ennek a megközelítésnek az előnye a rugalmasság és az irányítás - megváltoztathatja a neurális hálózatot, a tárhelyet, a szervert - általában bármilyen szeszélyt.

Сервер

Kezdjük egy helyi prototípussal.

Hagyományosan a Flask-ot használom REST API-hoz, OpenCV-hez és MobileSSD hálózathoz.

A Docker jelenlegi verzióinak telepítése után rájöttem, hogy az OpenCV 4.1.2 nem működik a Mobile SSD v1_coco_2018_01_28-mal, és vissza kellett térnem a bevált 11.

A szolgáltatás indításakor betöltjük az osztályneveket és a hálózatot:

def init():
    tf_labels.initLabels(dnn_conf.DNN_LABELS_PATH)
    return cv.dnn.readNetFromTensorflow(dnn_conf.DNN_PATH, dnn_conf.DNN_TXT_PATH)

Egy helyi dockeren (egy nem túl fiatal laptopon) 0.3 másodpercig tart, a Raspberry-n - 3.5.

Kezdjük a számítást:

def inference(img):
    net.setInput(cv.dnn.blobFromImage(img, 1.0/127.5, (300, 300), (127.5, 127.5, 127.5), swapRB=True, crop=False))
    return net.forward()

Docker - 0.2 mp, Raspberry - 1.7.

Tenzorkipufogó átalakítása olvasható json-ba:

def build_detection(data, thr, rows, cols):
    ret = []
    for detection in data[0,0,:,:]:
        score = float(detection[2])
        if score > thr:
            cls = int(detection[1])
            a = {"class" : cls, "name" : tf_labels.getLabel(cls),  "score" : score}
            a["x"] = int(detection[3] * cols)
            a["y"] = int(detection[4] * rows)
            a["w"] = int(detection[5] * cols ) - a["x"]
            a["h"] = int(detection[6] * rows) - a["y"]
            ret.append(a)
    return ret

további exportálja ezt a műveletet a Lombik segítségével(a bemenet egy kép, a kimenet a detektor eredményei json-ban).

Alternatív lehetőség, amelyben több munka hárul a szerverre: maga körözi a talált objektumokat, és visszaadja a kész képet.

Ez az opció akkor jó, ha nem akarjuk az opencv-t a szerverre húzni.

Dokkmunkás

Összegyűjtjük a képet.

A kód kifésülve és felkerül Github, a dokkoló közvetlenül onnan viszi el.

Platformként ugyanazt a Debian Stretchet használjuk, mint a Raspberry-n – nem térünk el a bevált technológiai stacktől.

Telepítenie kell a flask-ot, a protobuf-ot, a requests-t, az opencv_python-t, le kell töltenie a Mobile SSD-t, a szerverkódot a Githubról, és el kell indítania a szervert.

FROM python:3.7-stretch

RUN pip3 install flask
RUN pip3 install protobuf
RUN pip3 install requests
RUN pip3 install opencv_python

ADD http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz /
RUN tar -xvf /ssd_mobilenet_v1_coco_11_06_2017.tar.gz

ADD https://github.com/tprlab/docker-detect/archive/master.zip /
RUN unzip /master.zip

EXPOSE 80

CMD ["python3", "/docker-detect-master/detect-app/app.py"]

Egyszerű detektor kliens kérések alapján.

Közzététel a Docker Hub-on

A Docker-nyilvántartások olyan sebességgel szaporodnak, mint a felhődetektorok.

Hogy ne zavarjuk, konzervatív módon megyünk végig DockerHub.

  1. Regisztráció
  2. Belépés:
    dokkoló bejelentkezés
  3. Találjunk ki egy értelmes nevet:
    docker címke opencv-detect tprlab/opencv-detect-ssd
  4. Töltsd fel a képet a szerverre:
    docker push tprlab/opencv-detect-ssd

Elindulunk a felhőben

A konténer üzemeltetési helyének választéka is meglehetősen széles.

Minden nagy szereplő (Google, Microsoft, Amazon) ingyenes mikropéldányt kínál az első évben.
A Microsoft Azure és a Google Cloud kísérletezése után az utóbbi mellett döntöttem, mert gyorsabban beindult.

Nem írtam ide utasításokat, mivel ez a rész nagyon specifikus a kiválasztott szolgáltatóra.

Különféle hardver opciókat próbáltam,
Alacsony szintek (megosztott és dedikált) - 0.4 - 0.5 másodperc.
Erősebb autók - 0.25 - 0.3.
Nos, még a legrosszabb esetben is háromszoros a nyeremény, meg lehet próbálni.

Videó

Elindítunk egy egyszerű OpenCV videó streamert a Raspberry-n, amely a Google Cloudon keresztül észlel.
A kísérlethez egy videofájlt használtak, amelyet egykor egy véletlenszerű kereszteződésben vettek fel.


def handle_frame(frame):
    return detect.detect_draw_img(frame)
       
def generate():
    while True:
        rc, frame = vs.read()
        outFrame = handle_frame(frame)
        if outFrame is None:
            (rc, outFrame) = cv.imencode(".jpg", frame)
        yield(b'--framern' b'Content-Type: image/jpegrnrn' + bytearray(outFrame) + b'rn')

@app.route("/stream")
def video_feed():
    return Response(generate(), mimetype = "multipart/x-mixed-replace; boundary=frame")

A detektorral legfeljebb három képkockát kapunk másodpercenként, minden nagyon lassan megy.
Ha egy erős gépet viszel be a GCloudba, akkor másodpercenként 4-5 képkocka érzékelhető, de a különbség szinte láthatatlan a szemnek, így is lassú.

Videó a Cloud Object Detectorról a Raspberry Pi-n

A felhőnek és a szállítási költségeknek ehhez semmi köze, a detektor normál hardveren működik, és ilyen sebességgel működik.

Neural Computer Stick

Nem tudtam ellenállni, és lefutottam a benchmarkot az NCS-n.

A detektor sebessége valamivel kisebb volt, mint 0.1 másodperc, mindenesetre 2-3-szor gyorsabb, mint a felhő egy gyenge gépen, azaz 8-9 képkocka másodpercenként.

Videó a Cloud Object Detectorról a Raspberry Pi-n

Az eredmények különbségét az magyarázza, hogy az NCS Mobile SSD 2018_01_28-as verzióját futtatta.

PS Ráadásul a kísérletek azt mutatták, hogy egy meglehetősen erős asztali gép I7 processzorral valamivel jobb eredményeket mutat, és kiderült, hogy másodpercenként 10 képkocka kipréselhető rajta.

Fürt

A kísérlet tovább ment, és a detektort öt csomópontra telepítettem a Google Kubernetesben.
Maguk a pod-ok gyengék voltak, és egyikük sem tudott másodpercenként 2 képkockánál többet feldolgozni.
De ha egy fürtöt futtat N csomóponttal és N szálban elemzi a keretet, akkor elegendő számú csomóponttal (5) elérheti a kívánt 10 képkocka másodpercenkénti sebességét.

def generate():
    while True:
        rc, frame = vs.read()
        if frame is not None:
            future = executor.submit(handle_frame, (frame.copy()))
            Q.append(future)

        keep_polling = len(Q) > 0
        while(keep_polling):            
            top = Q[0]
            if top.done():
                outFrame = top.result()
                Q.popleft()
                if outFrame:
                    yield(b'--framern' b'Content-Type: image/jpegrnrn' + bytearray(outFrame) + b'rn')
                keep_polling = len(Q) > 0
            else:
                keep_polling = len(Q) >= M

Íme, mi történt:

Videó a Cloud Object Detectorról a Raspberry Pi-n

Kicsit kevésbé gyors, mint az NCS-nél, de erőteljesebb, mint egy adatfolyamban.

A nyereség természetesen nem lineáris – vannak átfedések az opencv képek szinkronizálására és mélymásolására.

Következtetés

Összességében a kísérlet arra enged következtetni, hogy ha megpróbálja, megúszhatja egy egyszerű felhőt.

De egy nagy teljesítményű asztali számítógép vagy helyi hardver lehetővé teszi, hogy jobb eredményeket érjen el, és minden trükk nélkül.

referenciák

Forrás: will.com

Hozzászólás