Кириш сөз
Азыр интернетте Тесланын автопилоту жолду кандай көрөрүн көрсөткөн видео тарады.
Мен детектор менен байытылган видеону жана реалдуу убакыт режиминде берүү үчүн көптөн бери кычышып келе жатам.
Маселе, мен Raspberryден видеону уктурууну каалап жатам жана андагы нейрондук тармак детекторунун иштеши көп нерсени каалагандай калтырат.
Intel Neural Computer Stick
Мен ар кандай чечимдерди карап чыктым.
В
Intel негизги алкактар үчүн конвертерлерди камсыз кылганына карабастан, бир катар каталар бар.
Мисалы, талап кылынган тармактын форматы шайкеш келбей калышы мүмкүн, эгер ал шайкеш болсо, анда кээ бир катмарлар түзмөктө колдоого алынбашы мүмкүн, ал эми алар колдоого алынса, конверсия процессинде каталар пайда болушу мүмкүн, анын натыйжасында чыгарууда кээ бир кызык нерселерди алабыз.
Жалпысынан алганда, эгер сиз кандайдыр бир ыктыярдуу нейрон тармагын кааласаңыз, анда ал NCS менен иштебей калышы мүмкүн. Ошондуктан, мен эң кеңири таралган жана жеткиликтүү куралдарды колдонуу менен маселени чечүүгө аракет кылууну чечтим.
булут
Жергиликтүү аппараттык чечимге айкын альтернатива булутка өтүү болуп саналат.
Даяр варианттар - менин көздөрүм чуркайт.
Бардык лидерлер:
...Ал эми ондогон анча белгилүү эмес.
Бул сорттун арасынан тандоо оңой эмес.
Мен тандабайм, бирок Dockerдеги OpenCVдеги эски иштөө схемасын ороп, аны булутта иштетүүнү чечтим.
Бул ыкманын артыкчылыгы ийкемдүүлүк жана башкаруу болуп саналат - сиз нейрон тармагын, хостингди, серверди - жалпысынан каалаган капризди өзгөртө аласыз.
Server
Жергиликтүү прототиби менен баштайлы.
Салттуу түрдө мен REST API, OpenCV жана MobileSSD тармагы үчүн Flask колдоном.
Учурдагы версияларды Dockerге орнотуп алып, мен OpenCV 4.1.2 Mobile SSD v1_coco_2018_01_28 менен иштебестигин байкадым жана мен далилденген 11/06_2017ге кайра кайтууга туура келди.
Кызматтын башталышында биз класстын атын жана тармагын жүктөйбүз:
def init():
tf_labels.initLabels(dnn_conf.DNN_LABELS_PATH)
return cv.dnn.readNetFromTensorflow(dnn_conf.DNN_PATH, dnn_conf.DNN_TXT_PATH)
Жергиликтүү докерде (өтө жаш эмес ноутбукта) 0.3 секунд, Raspberryде - 3.5.
Эсептөөнү баштайлы:
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()
Докер - 0.2 сек, Raspberry - 1.7.
Тензордук газды окула турган jsonга айландыруу:
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
андан ары
Альтернативдүү вариант, анда көбүрөөк жумуш серверге которулат: ал өзү табылган объекттерди тегеретет жана даяр сүрөттү кайтарат.
Бул параметр биз opencvди серверге сүйрөп кетүүнү каалабаган жерде жакшы.
Докер
Биз сүрөттү чогултабыз.
Код таралып, жайгаштырылат
Платформа катары биз Raspberryдегидей эле Debian Stretch программасын алабыз - биз далилденген технологиялык стектен тайбайбыз.
Сиз колбаны, протобуфты, суроо-талаптарды, opencv_python орнотуп, Mobile SSDди, Github'дан сервер кодун жүктөп алып, серверди башташыңыз керек.
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"]
жөнөкөй
Docker Hub'га жарыялоо
Докер реестрлери булут детекторлорунан кем эмес ылдамдыкта көбөйүүдө.
Убара болбош үчүн биз консервативдүү жол менен өтөбүз
- Каттоо
- Кирүү:
докер кирүү - Маанилүү ат менен келели:
докер теги opencv-аныктоо tprlab/opencv-detect-ssd - Сүрөттү серверге жүктөө:
docker push tprlab/opencv-detect-ssd
Биз булутта ишке киргизебиз
Контейнерди кайда иштетүүнү тандоо да бир топ кеңири.
Бардык чоң оюнчулар (Google, Microsoft, Amazon) биринчи жылы микро-инстанцияны бекер сунушташат.
Microsoft Azure жана Google Cloud менен эксперимент жүргүзгөндөн кийин, мен экинчисине макул болдум, анткени ал тезирээк учуп кетти.
Мен бул жерде инструкцияларды жазган жокмун, анткени бул бөлүк тандалган камсыздоочу үчүн өзгөчө.
Мен ар кандай аппараттык опцияларды аракет кылдым,
Төмөн деңгээлдер (жалпы жана арналган) - 0.4 - 0.5 секунд.
Күчтүү машиналар - 0.25 - 0.3.
Ооба, эң начар сценарийде да, утуш үч эсе, сиз аракет кыла аласыз.
Видео
Биз Raspberryде Google Cloud аркылуу аныктоочу жөнөкөй OpenCV видео агымын ишке киргизебиз.
Эксперимент үчүн бир жолу туш келди кесилиште тартылган видео файл колдонулган.
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")
Детектор менен биз секундасына үч кадрдан ашык эмес алабыз, баары өтө жай жүрөт.
Эгер сиз GCloud'ка күчтүү машинаны алсаңыз, секундасына 4-5 кадрды аныктай аласыз, бирок айырма көзгө дээрлик көрүнбөйт, ал дагы эле жай.
Булуттун жана транспорттук чыгымдардын муну менен эч кандай байланышы жок; детектор кадимки жабдыкта иштейт жана ошол ылдамдыкта иштейт.
Нейрондук компьютер таякчасы
Мен туруштук бере алган жокмун жана NCSде эталонду иштеттим.
Детектордун ылдамдыгы 0.1 секунддан бир аз жайыраак, кандай болгон күндө да алсыз машинадагы булуттан 2-3 эсе тез, башкача айтканда, секундасына 8-9 кадр.
Натыйжалардагы айырма NCS 2018_01_28 Mobile SSD версиясын иштетип жаткандыгы менен түшүндүрүлөт.
P.S. Мындан тышкары, эксперименттер I7 процессору менен жетишерлик күчтүү рабочий машина бир аз жакшыраак натыйжаларды көрсөтүп, секундасына 10 кадрды сыгып алуу мүмкүн экенин көрсөттү.
кластер
Эксперимент андан ары уланып, мен детекторду Google Kubernetesтин беш түйүнүнө орноттум.
Подоктордун өзү начар болгондуктан, алардын ар бири секундасына 2 кадрдан ашык иштете алган эмес.
Бирок, эгерде сиз N түйүндүү кластерди иштетсеңиз жана N жипте кадрларды талдасаңыз, анда жетиштүү сандагы түйүндөр (5) менен секундасына каалаган 10 кадрга жете аласыз.
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
Бул жерде эмне болуп жатат:
NCSге караганда бир аз ылдамыраак, бирок бир агымга караганда күчтүү.
Пайда, албетте, сызыктуу эмес - синхрондоштуруу жана opencv сүрөттөрүн терең көчүрүү үчүн катмарлар бар.
жыйынтыктоо
Жалпысынан алганда, эксперимент, эгер аракет кылсаңыз, жөнөкөй булуттан кутулууга болот деген жыйынтыкка келүүгө мүмкүнчүлүк берет.
Бирок күчтүү рабочий стол же жергиликтүү жабдык жакшы натыйжаларга жетүү үчүн, эч кандай айла жок.
шилтемелер
Source: www.habr.com