Mengakses Akses Intel Neural Computer Stick melalui REST

Masalah tugas tunggal


Dalam seri terakhir , saya meletakkan Intel Neural Computer Stick 2 di tangki dan melemparkan semua perhitungan jaringan saraf ke atasnya, meninggalkan Tensorflow dan OpenCV-DNN.

Ada masalah yang sudah saya temui saat itu - ketidakmampuan untuk bekerja dengan NCS dari beberapa proses secara bersamaan. Lalu itu tidak kritis, tapi sekarang saatnya untuk mencari tahu.

Ketika mencoba memuat model dari proses kedua, OpenVino mulai bersumpah:

E: [ncAPI] [ 926029] resetAll:348 Failed to connect to stalled device, rc: X_LINK_ERROR E: [ncAPI] [ 933282] ncDeviceOpen:672 Failed to find suitable device, rc: X_LINK_DEVICE_NOT_FOUND 

Dengan mencari di Forum Dukungan Intel, masalah serupa ditemukan .

Dari sana kami dipindahkan ke dokumentasi yang dinyatakan dengan jelas:

Perangkat tunggal tidak dapat dibagi di berbagai proses.

Pada percobaan ini, Anda dapat meminimalkan dan mulai membuat akses multiproses.

Layanan NCS


Sangat logis untuk menempatkan kerja langsung dengan NCS dalam layanan terpisah, dan untuk mendistribusikan API ke semua klien yang akan digunakan untuk bekerja.

Secara umum, ini seharusnya menjadi topik tentang robot dan pencapaian baru dalam hal jaringan saraf. Tetapi ternyata materi pada API NCS cukup tertarik ke artikel terpisah.

API NCS


Pada level rendah, API NCS sangat sederhana:
- model beban
- mulai perhitungan
- dapatkan daftar model
- dapatkan properti model

Jika semuanya tidak ambigu saat memuat model, maka knalpot kalkulasi adalah tensor sensitif konteks yang mungkin tidak perlu semua klien.

Memperoleh daftar model juga cukup transparan, dan dari properti dimensi tensor input langsung terlintas dalam pikiran - dalam istilah manusia ini berarti bahwa akan lebih baik untuk menyesuaikan gambar di muka dengan pengaturan jaringan.

Selain itu, level rendah baik, tetapi jika Anda mendukung operasi khusus, itu menyederhanakan logika dan data.

Jadi, selain pangkalan, ada tugas untuk mendukung API untuk klasifikasi, deteksi, dan segmentasi.

Sayangnya, model segmentasi yang paling menarik tidak didukung pada NCS, jadi Anda harus membatasi diri hingga yang paling sederhana, dengan jalan dan markup.

Setiap operasi ini menggunakan perhitungan dasar model, tetapi mereka berbeda dalam interpretasi tensor output.

Antarmuka utama


Jadi, antarmuka utama meliputi metode:

  • POST: / load - memuat model
  • POST: / unload / $ model - hapus model (dari layanan, tidak mungkin untuk menghapus dari perangkat)
  • DAPATKAN: / daftar - dapatkan daftar model
  • DAPATKAN: / input / shape / $ model - cari tahu dimensi tensor input
  • POST: / inference / file / $ model - buat perhitungan dengan data dari memori
  • POST: / inference / path / $ model - membuat perhitungan dengan data dalam sistem file

Berikut adalah dua kata tentang data dari memori dan sistem file:

Jika layanan NCS dan penggunanya menjalankan Raspberry yang sama, maka masuk akal untuk menghemat mentransfer gambar dan alih-alih memindahkan jalur sehingga layanan itu sendiri membaca file.
Jika gambar sudah ada dalam memori (atau tidak ada dalam sistem file), maka kami mentransfernya langsung dari sana.

Pengujian menunjukkan bahwa mentransfer byte dari memori secara signifikan lebih lambat (pengukuran dilakukan untuk 1000 upaya):

Dari memori: 87,5 detik
Jalur File: 63.3150 detik

Namun, kedua opsi ini didukung untuk metode apa pun, baik untuk perhitungan umum dan untuk kasus khusus di bawah ini.

Secara umum, metode inferensi mengambil gambar dalam bentuk array numpy sebagai input dan menghasilkan tensor dalam format yang sama.
Bagaimana menafsirkan knalpot sudah menjadi masalah pelanggan.
Untuk memfasilitasi tugas ini, layanan mendukung metode khusus yang mengekstrak informasi signifikan dalam bentuk manusia dari tensor keluaran.

Klasifikasi


Untuk klasifikasi, kami membuat metode REST terpisah, yang mengubah tensor output menjadi satu set pasangan (kelas, skor).

 def get_class_tensor(data): ret = [] thr = 0.01 while(True): cls = np.argmax(data) if data[cls] < thr: break; logging.debug(("Class", cls, "score", data[cls])) c = {"class" : int(cls), "score" : int(100 * data[cls])} data[cls] = 0 ret.append(c) return ret def classify(model_id, img): rc, out = run_inference(model_id, img) if not rc: return rc, out return True, get_class_tensor(out) 

Seperti halnya dengan output normal, dua metode didukung - melalui file dalam memori dan jalur pada disk.

  • POST: / mengklasifikasikan / file / $ model
  • POST: / mengklasifikasikan / path / $ model

Deteksi


Tensor output detektor berisi satu set (kelas, probabilitas, koordinat dinormalkan) dan terlihat agak rumit.

Kami mengubahnya menjadi bentuk yang dapat dimengerti, sambil memotong opsi yang tidak mungkin:

 def get_detect_from_tensor(t, rows, cols): score = int(100 * t[2]) cls = int(t[1]) left = int(t[3] * cols) top = int(t[4] * rows) right = int(t[5] * cols) bottom = int(t[6] * rows) return {"class" : cls, "score" : score, "x" : left, "y" : top, "w" : (right - left), "h" : (bottom - top)} def build_detection(data, thr, rows, cols): T = {} for t in data: score = t[2] if score > thr: cls = int(t[1]) if cls not in T: T[cls] = get_detect_from_tensor(t, rows, cols) else: a = T[cls] if a["score"] < score: T[cls] = get_detect_from_tensor(t, rows, cols) return list(T.values()) def detect(model_id, img): rc, out = run_inference(model_id, img) if not rc: return rc, out rows, cols = img.shape[:2] return True, build_detection(out[0], 0.01, rows, cols) 

Seperti biasa, kedua metode ini didukung:

  • POST: / detect / file / $ model
  • POST: / detect / path / $ model

Segmentasi


Tensor segmentasi berisi probabilitas berdasarkan kelas dan bahkan dalam dimensi jaringan saraf.
Konversikan ini menjadi mask kelas:

 def segment(model_id, img): rc, out = run_inference(model_id, img) if not rc: return rc, out out = np.argmax(out, axis=0) out = cv.resize(out, (img.shape[1], img.shape[0]),interpolation=cv.INTER_NEAREST) return True, out 

  • POST: / segment / file / $ model
  • POST: / segment / path / $ model

Kesimpulan


Seperti yang telah disebutkan, saya awalnya berencana untuk berbicara tentang layanan di salah satu bab artikel tentang penggunaannya, tetapi ternyata volumenya menarik pada dokumen terpisah.

Sekali lagi, saya menggunakan layanan pada Raspberry Pi, tetapi dapat dijalankan pada platform apa pun yang memiliki python dan OpenVino dengan NCS.

Referensi


Source: https://habr.com/ru/post/id469265/


All Articles