AI yang tidak meminta roti

Artikel tentang cara kami membuat AI selangkah demi selangkah. Waktu membaca 10+ menit.







Pendahuluan . Sebuah startup computer vision yang menggunakan pengembangan berbiaya rendah sebagai konsep intinya. Tim ini cukup konsisten dengan semangat: 3 - 5 siswa pengembang dari berbagai tingkat dan arah, tergantung pada hari dan waktu (dari tarif 0,25 hingga 1,25). Pengalaman saya bermain tag sangat berguna di sini.



Secara singkat tentang produk (pc + software) - sistem pengawasan video cerdas yang terhubung ke jaringan lokal dan menghasilkan pemrosesan video sendiri . Dua prasyarat: keberadaan antarmuka pengguna dengan hak berbeda dan otonomi maksimum algoritme.



Di sisi teknis, tidak ada batasan pada perangkat keras, yang utama adalah itu berfungsi dengan baik; tetapi dengan keuangan itu. Untuk segala sesuatu tentang segalanya ~ $ 500. Tentunya hanya komponen baru dan modern. Pilihan mereka tidak bagus, tapi ada!



Kami memutuskan perangkat kerasnya, lalu perangkat lunaknya. Pilihannya jatuh pada arsitektur layanan mikro yang menggunakan buruh pelabuhan untuk beberapa alasan yang cukup.



Pengembangan fitur berubah dari yang sederhana dan perlu (bekerja dengan streaming dan file video) menjadi kompleks, dengan tinjauan berkala. Kami mengumpulkan MVP, beberapa sprint pengoptimalan membawa kami secara nyata lebih dekat ke tujuan yang kami dambakan - untuk menyelesaikan semua 4 poin secara bersamaan, dan tidak secara terpisah:



  1. 16+ Kamera IP (FHD / 25fps) Live, Acara atau Waktu Putar & Rekaman
  2. Operasi paralel dari semua algoritma CV yang tersedia
  3. Pengguna secara intensif menggunakan antarmuka tanpa penundaan - menonton streaming
  4. Beban CPU kurang dari 90% dan semuanya berfungsi (!)


Sedikit tentang tumpukan, pilihan jatuh pada: C / C +, Python + TensorFlow, PHP, NodeJS, TypeScript, VueJS, PostgreSQL + Socket.io dan hal-hal kecil lainnya.



Fitur yang diterapkan sengaja disembunyikan untuk membahas lebih detail, mungkin, fitur yang paling menarik dan menyenangkan dari area CV dan, sampai batas tertentu, ML.



"Pengguna Unik"



Contoh penggunaannya adalah mengumpulkan riwayat kunjungan setiap pengunjung tertentu, dan karyawan harus diperhitungkan secara terpisah, bahkan jika kita tidak tahu bahwa ini adalah karyawan (Contoh - pusat perbelanjaan)

Dan tampaknya masalah ini telah diselesaikan 100.500+ kali dan telepon serta hal lain sudah dapat mengenali wajah dan mengingatnya, mengirimnya ke suatu tempat, menyimpannya. Tetapi 95% solusi digunakan di ACS, di mana pengguna sendiri, mencoba untuk dikenali, berdiri di depan kamera 5MP pada jarak 30-50 cm selama beberapa detik, sampai wajahnya memeriksa dengan satu atau beberapa wajah dari database.



Dalam kasus kami, kondisi seperti itu merupakan kemewahan. Pengguna bergerak tidak menentu, melihat ponsel cerdas mereka pada jarak yang cukup dari kamera yang dipasang di langit-langit. Selain itu, kameranya sendiri mengalami kesulitan, yang paling sering adalah kamera anggaran dengan 1,3-2MP dan semacam rendering warna yang tidak dapat dipahami, selalu berbeda.



Sebagian, masalah ini diatasi dengan pembentukan spesifikasi teknis untuk kondisi pemasangan kamera, tetapi secara umum sistem seharusnya dapat mengenali dalam kondisi seperti itu (tentu saja, lebih buruk).



Pendekatan solusi: tugas itu diuraikan menjadi 2 tugas + struktur database.



Ingatan jangka pendek



Layanan terpisah, di mana proses real-time terutama terjadi, pada input adalah bingkai dari kamera (sebenarnya, layanan lain), pada output - permintaan http dengan vektor X 512-dimensi (face-id) yang dinormalisasi dan beberapa meta-data, misalnya cap waktu.

Ada banyak solusi menarik di bidang logika dan optimasi di dalamnya, tapi itu saja; untuk sekarang semuanya ...



Ingatan jangka panjang



Layanan terpisah di mana persyaratan waktu nyata tidak penting, tetapi dalam beberapa kasus penting (misalnya, seseorang dari daftar berhenti). Secara umum, kami membatasi diri pada 3 detik untuk diproses.

Di pintu masuk ke layanan - http dari memori jangka pendek dengan vektor 512 dimensi di dalamnya; di pintu keluar - Id pengunjung.



Pikiran pertama sudah jelas, solusi untuk masalah ini cukup sederhana: mendapat http β†’ pergi ke database, mengambil apa β†’ dibandingkan dengan http mengisi, jika ada, maka itu; jika tidak, maka baru.

Keuntungan dari solusi semacam itu tidak terhitung jumlahnya, tetapi hanya satu minus - itu tidak berhasil.



Masalahnya terpecahkan, meskipun kami mengikuti jejak samurai, mencoba berbagai pendekatan, secara berkala melihat luasnya Internet. Secara umum, keputusan tersebut ternyata cukup singkat. Konsepnya cukup sederhana dan didasarkan pada clustering:



  1. Setiap vektor (a-vektor) akan menjadi milik beberapa Pengguna; setiap cluster (tidak lebih dari M vektor, di luar kotak M = 30) milik beberapa Pengguna. Apakah a-vector milik cluster A bukanlah fakta. Vektor di cluster menentukan interaksi cluster, vektor di Pengguna hanya menentukan sejarah Pengguna.
  2. Setiap cluster akan memiliki pusat massa (sebenarnya, vektor A) dan jari-jarinya sendiri (selanjutnya disebut sebagai rentang) interaksi dengan vektor atau cluster lain.
  3. Centroid dan range akan menjadi fungsi cluster, bukan statis.
  4. Kedekatan vektor ditentukan oleh jarak Euclidean kuadrat (dalam kasus khusus, sebaliknya). Meskipun ada beberapa metode lain yang layak di sini, kami hanya berhenti di situ.


Catatan: sejak Kami menggunakan vektor yang dinormalisasi, jarak antara mereka dijamin dari 0 hingga 2. Selanjutnya, tentang algoritma untuk mengimplementasikan konsep tersebut.



# 1 Lingkaran tersangka. Centroid sebagai fungsi hash



Vektor-X yang diperoleh dari memori jangka pendek dibandingkan dengan sentroid cluster (vektor A) yang tersedia dalam database untuk kedekatan, yang jauh, di mana rentang [X, A]> 1 - dibuang. Jika tidak ada yang tersisa, cluster baru dibuat.



Selanjutnya, minimum antara vektor-X dan semua vektor-a yang tersisa dicari (rentang_minimal [X, a])



# 2 Properti unik dari cluster. Entitas yang mengatur dirinya sendiri



Range_A milik cluster dihitung, yang vektornya paling dekat dengan vektor X. Di sini kita menggunakan fungsi linier terbalik dari jumlah vektor (N) yang sudah ada di cluster ini (const * (1 - N / 2M)); di luar kotak const = 0.67).



# 3 Validasi dan kesalahpahaman. Jika bukan seseorang - lalu siapa!?



Jika range_A> min_range [X, a], maka vektor X ditandai sebagai milik A-cluster. Jika tidak, maka ... Oh ... Ini agak mirip dengan deskripsi model kesalahpahaman matematika.

Kami memutuskan bahwa dalam hal ini kami akan membuat cluster baru, sehingga sengaja membuat kesalahan jenis pertama "Target yang hilang".



# 4 Pelatihan tambahan. Bagaimana angka membentuk tanda



Pengalaman subyektif adalah saat data menjadi alat. Kami mengenali sebelumnya, tetapi mungkin dengan kesalahan. Haruskah saya mempercayai vektor X untuk menggunakannya di pertandingan berikutnya !? Memeriksa! Vektor X harus:



  • cukup dekat dengan sentroid A (range_A> range [X, A])
  • berguna dan beragam, karena di satu sisi, kami meminimalkan risiko kesalahan, di sisi lain, kami juga tidak memerlukan salinan (Config_Max [0.35]> range [X, a]> Config_Max [0.125]). Dengan demikian, konfigurasi menentukan kecepatan dan ketepatan "belajar".


Memenuhi kondisi ini, vektor X termasuk dalam cluster A (sebelumnya hanya menjadi milik Pengguna). Jika ada lebih banyak vektor dalam cluster, maka kita menghapus yang paling sentral (min_range [A, a]) - itu memperkenalkan variasi paling sedikit dan hanya fungsi dari yang lain; Selain itu, centroid sudah terlibat dalam pencocokan.



# 5 Bekerja pada bug. Kami mengubah kerugian menjadi keuntungan



Di setiap pilihan yang sulit, kami mengambil langkah menuju kesalahan "Target tidak ada" - kami membuat cluster dan Pengguna baru. Saatnya mengunjungi mereka kembali ... semua. Setelah # 4 kita memiliki cluster A. Selanjutnya, kita menghitung ulang centroidnya (vektor A) dan mencari jarak minimum ke semua centroid yang tersedia di ruang 512-dimensi kita. Dalam hal ini, jarak dianggap lebih sulit, tetapi sekarang tidak begitu penting. Ketika jarak_minimal [A, B] kurang dari nilai tertentu (di luar kotak range_unity = 0,25) kita menggabungkan dua set, menghitung pusat massa baru dan menyingkirkan vektor yang kurang "berguna" jika jumlahnya terlalu banyak.

Dengan kata lain: jika ada 2+ cluster, sebenarnya, milik Pengguna yang sama, maka, setelah serangkaian deteksi, cluster tersebut akan menjadi dekat dan bergabung menjadi satu bersama story mereka.



# 6 Fitur kombinatorial. Ketika mobil ... berpikir!?



Perlu mendefinisikan istilah baru di sini di artikel ini. Vektor hantu adalah vektor yang diperoleh bukan sebagai hasil aktivitas memori jangka pendek, tetapi sebagai hasil dari fungsi di atas vektor N cluster (a1, a2, a3, a4 ...). Tentu saja, vektor yang diperoleh dengan cara ini disimpan dan dihitung secara terpisah dan tidak mewakili nilai apa pun hingga, sebagai hasil dari pencocokan, mereka ditentukan sebagai yang terdekat (lihat # 3). Manfaat utama vektor hantu adalah untuk mempercepat pembelajaran awal sebuah cluster .



Sistem sudah dalam produksi. Hasilnya diperoleh pada data nyata di luar lingkungan pengujian untuk 5000+ Pengguna; sekelompok "kelemahan" juga diperhatikan, yang diperkuat dan diperhitungkan dalam teks ini.



Menariknya, pendekatan ini tidak memiliki pengaturan pengguna dan semua pekerjaan tidak dikontrol dengan cara apa pun, semuanya sepenuhnya otonom . Selain itu, analisis deret waktu memungkinkan Anda mengklasifikasikan Pengguna ke dalam berbagai kategori dengan cara yang sama, sehingga membangun asosiasi. Beginilah pertanyaan itu diselesaikan - siapa karyawan dan siapa pengunjung.



Peran pengguna sistem sederhana - Anda perlu memeriksa email Anda secara berkala atau antarmuka sistem untuk laporan aktivitas baru.



Hasil



Nilai proximity untuk pengenalan berdasarkan memori jangka panjang adalah ~ 0,12-0,25 untuk cluster yang cukup terlatih (berisi 6-15 a-vektor). Selanjutnya, pembelajaran melambat karena peningkatan probabilitas "salinan vektor", tetapi dalam jangka panjang kedekatannya cenderung ke nilai ~ 0,04-0,12, ketika cluster sudah berisi 20+ vektor-a. Perhatikan bahwa di dalam memori jangka pendek, dari bingkai ke bingkai, parameter yang sama memiliki nilai ~ 0,5-1,2, yang berbunyi seperti: "Seseorang lebih mirip dirinya dengan kacamata 2 tahun yang lalu daripada 100 md yang lalu." Peluang tersebut dibuka dengan penggunaan clustering dalam memori jangka panjang .



Teka-teki



Salah satu tes menghasilkan observasi yang menarik.



Kondisi awal:



  • Pada dua PC yang benar-benar identik, sistem pengawasan video yang benar-benar identik dengan pengaturan yang benar-benar identik diterapkan. Mereka terhubung ke satu ip-camera, terletak dengan benar, menurut TOR.


Bertindak:



  • Sistem dimulai pada waktu yang sama dan dibiarkan selama seminggu dengan semua algoritme berfungsi. Lalu lintas sesuai dengan lalu lintas normal tanpa perubahan.


Hasil:



  • Jumlah Pengguna yang dibuat, cluster dan a-vektor sama, tetapi centroidnya berbeda, tidak signifikan - tetapi berbeda. Pertanyaannya kenapa? Siapa tahu - tulis di komentar atau di sini )


Sayang sekali saya tidak bisa menulis tentang banyak hal di sini, tapi mungkin saya bisa menjelaskan sesuatu dengan detail yang sama di artikel lain. Mungkin semua ini telah dijelaskan dalam beberapa manual yang bagus, tetapi saya menyesal, saya tidak pernah menemukannya.



Sebagai kesimpulan, saya akan mengatakan bahwa sangat menarik untuk mengamati dari dalam bagaimana sistem AI otonom mengklasifikasikan ruang di sekitarnya, menerapkan berbagai fitur yang melekat di dalamnya. Orang tidak memperhatikan banyak hal karena akumulasi pengalaman persepsi (langkah # 4).




Saya sangat berharap artikel ini bermanfaat bagi siapa pun dalam proyeknya.



All Articles