π TL;DR
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ Π½Π°ΡΠ½Π΅ΠΌ ΡΠ΅ΡΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°ΡΡ ΠΏΠ΅ΡΠ°ΡΠ½ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ Π² ΠΊΠ½ΠΈΠ³Π°Ρ ΠΈΠ»ΠΈ ΠΆΡΡΠ½Π°Π»Π°Ρ ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡΠ½ΡΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΊΠ°ΠΌΠ΅ΡΡ ΡΠΌΠ°ΡΡΡΠΎΠ½Π°.
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ TensorFlow 2 Object Detection API ΠΌΡ Π½Π°ΡΡΠΈΠΌ TensorFlow ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΠΈ Π³Π°Π±Π°ΡΠΈΡΡ ΡΡΡΠΎΠΊ https://
Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
(Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΊΠ°Π΄ΡΠ΅ Π²ΠΈΠ΄Π΅ΠΎ ΠΈΠ· ΠΊΠ°ΠΌΠ΅ΡΡ ΡΠΌΠ°ΡΡΡΠΎΠ½Π°).
Π’Π΅ΠΊΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΡΠ»ΠΊΠΈ, ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΠΏΠΎ ΠΏΡΠ°Π²ΡΡ ΡΡΠΎΡΠΎΠ½Ρ ΠΎΡ https://
, Π±ΡΠ΄Π΅Ρ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Tesseract. Π Π°Π±ΠΎΡΠ° Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ Tesseract Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠΎΠΌ ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ, Π½ΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΉΡΠΈ ΠΏΠΎΠ»Π½ΡΠΉ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ links-detector repository Π½Π° GitHub.
π <strong>ΠΠ°ΠΏΡΡΡΠΈΡΡ Links Detector</strong> ΡΠΎ ΡΠΌΠ°ΡΡΡΠΎΠ½Π°, ΡΡΠΎΠ±Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ.
π <strong>ΠΡΠΊΡΡΡΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ links-detector</strong> Π½Π° GitHub Ρ ΠΏΠΎΠ»Π½ΡΠΌ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
ΠΠΎΡ ΡΠ°ΠΊ Π² ΠΈΡΠΎΠ³Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΏΠ΅ΡΠ°ΡΠ½ΡΡ ΡΡΡΠ»ΠΎΠΊ:
β οΈ ΠΠ° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΡΠ°Π΄ΠΈΠΈ ΠΈ ΠΈΠΌΠ΅Π΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π½Π΅Π΄ΠΎΡΠ°Π±ΠΎΡΠΎΠΊ ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠΉ. ΠΠΎΡΡΠΎΠΌΡ, Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π²ΡΡΠ΅ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π½Π΅Π΄ΠΎΡΠ°Π±ΠΎΡΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π»ΠΈΠΊΠ²ΠΈΠ΄ΠΈΡΠΎΠ²Π°Π½Ρ, Π½Π΅ ΠΎΠΆΠΈΠ΄Π°ΠΉΡΠ΅ ΠΎΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΎΠ³ΠΎ π€·π»β. Π’Π°ΠΊΠΆΠ΅ ΡΡΠΎΠΈΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ ΡΠ΅Π»ΡΡ Π΄Π°Π½Π½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Ρ TensorFlow 2 Object Detection API, Π° Π½Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ production-ready ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
Π ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ Π±Π»ΠΎΠΊΠΈ Ρ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ Π² ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ Π±Π΅Π· ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΈ ΠΊΠΎΠ΄Π° Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ Π½Π° GitHub Π²Π΅ΡΡΠΈΡ ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ
π€·π»βοΈ ΠΡΠΎΠ±Π»Π΅ΠΌΠ°
Π― ΡΠ°Π±ΠΎΡΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠΎΠΌ, ΠΈ Π² ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ΅ ΠΎΡ ΡΠ°Π±ΠΎΡΡ Π²ΡΠ΅ΠΌΡ ΡΡΡ Machine Learning Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Ρ ΠΎΠ±Π±ΠΈ. ΠΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π½Π΅ Π² ΡΡΠΎΠΌ.
Π― ΠΊΡΠΏΠΈΠ» ΠΊΠ½ΠΈΠ³Ρ ΠΏΠΎ ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠΌΡ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ ΠΈ, ΡΠΈΡΠ°Ρ ΠΏΠ΅ΡΠ²ΡΠ΅ Π³Π»Π°Π²Ρ, ΡΡΠΎΠ»ΠΊΠ½ΡΠ»ΡΡ Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎΠΌ ΠΏΠ΅ΡΠ°ΡΠ½ΡΡ
ΡΡΡΠ»ΠΎΠΊ Π½Π° ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠΈ https://tensorflow.org/
ΠΈΠ»ΠΈ https://some-url.com/which/may/be/even/longer?and_with_params=true
.
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, ΠΊΠ»ΠΈΠΊΠ°ΡΡ ΠΏΠΎ ΠΏΠ΅ΡΠ°ΡΠ½ΡΠΌ ΡΡΡΠ»ΠΊΠ°ΠΌ Π½Π΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ»ΠΎΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠΌ (ΡΠΏΠ°ΡΠΈΠ±ΠΎ, ΠΡΠΏ!). Π§ΡΠΎΠ±Ρ ΠΎΡΠΊΡΡΡΡ ΡΡΡΠ»ΠΊΠΈ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅ ΠΌΠ½Π΅ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΠ»ΠΎΡΡ Π½Π°Π±ΠΈΡΠ°ΡΡ ΠΈΡ ΠΏΠΎΡΠΈΠΌΠ²ΠΎΠ»ΡΠ½ΠΎ Π² Π°Π΄ΡΠ΅ΡΠ½ΠΎΠΉ ΡΡΡΠΎΠΊΠ΅, ΡΡΠΎ Π±ΡΠ»ΠΎ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. Π ΡΠΎΠΌΡ ΠΆΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΊΠΈ Π½ΠΈΠΊΡΠΎ Π½Π΅ ΠΎΡΠΌΠ΅Π½ΡΠ».
π‘ ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅
Π― ΠΏΠΎΠ΄ΡΠΌΠ°Π», Π° ΡΡΠΎ Π΅ΡΠ»ΠΈ, ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ Ρ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΠ΅Π»Π΅ΠΌ QR ΠΊΠΎΠ΄ΠΎΠ², ΠΌΡ "Π½Π°ΡΡΠΈΠΌ" ΡΠΌΠ°ΡΡΡΠΎΠ½ (1) ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΠΌΠ΅ΡΡΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ (2) ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΡ ΠΏΠ΅ΡΠ°ΡΠ½ΡΠ΅ Π³ΠΈΠΏΠ΅Ρ-ΡΡΡΠ»ΠΊΠΈ ΠΈ Π΄Π΅Π»Π°ΡΡ ΠΈΡ
ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡΠ½ΡΠΌΠΈ? Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΠΈΡΠ°ΡΠ΅Π»Ρ Π΄Π΅Π»Π°Π» Π±Ρ Π²ΡΠ΅Π³ΠΎ ΠΎΠ΄ΠΈΠ½ ΠΊΠ»ΠΈΠΊ Π²ΠΌΠ΅ΡΡΠΎ ΠΏΠΎΡΠΈΠΌΠ²ΠΎΠ»ΡΠ½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π° Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎΠΌ Π½Π°ΠΆΠ°ΡΠΈΠΉ Π½Π° ΠΊΠ»Π°Π²ΠΈΡΠΈ. ΠΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°Ρ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡ Π²ΡΠ΅ΠΉ ΡΡΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΠΌΠ΅Π½ΡΡΠΈΠ»Π°ΡΡ Π±Ρ Ρ O(N)
Π΄ΠΎ O(1)
.
ΠΠΎΡ ΡΠ°ΠΊ Π±Ρ ΡΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ Π²ΡΠ³Π»ΡΠ΄Π΅Π»:
π Π’ΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΊ ΡΠ΅ΡΠ΅Π½ΠΈΡ
ΠΠ°ΠΊ Ρ ΡΠΆΠ΅ ΡΠΏΠΎΠΌΡΠ½ΡΠ» Π²ΡΡΠ΅, Ρ Π½Π΅ ΡΠΊΡΠΏΠ΅ΡΡ Π² ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠΌ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠΈ. ΠΠ»Ρ ΠΌΠ΅Π½Ρ ΡΡΠΎ Π±ΠΎΠ»ΡΡΠ΅ ΠΊΠ°ΠΊ Ρ ΠΎΠ±Π±ΠΈ. ΠΠΎΡΡΠΎΠΌΡ ΠΈ ΡΠ΅Π»Ρ ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π±ΠΎΠ»ΡΡΠ΅ Π² ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΈ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠΈ ΡΠ°Π±ΠΎΡΠ΅ Ρ TensorFlow 2 Object Detection API, ΡΠ΅ΠΌ Π² ΠΏΠΎΠΏΡΡΠΊΠ΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ production-ready ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
Π‘ ΡΡΠ΅ΡΠΎΠΌ Π²ΡΡΠ΅ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ, Ρ ΡΠΏΡΠΎΡΡΠΈΠ» ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΊ ΡΠΈΠ½Π°Π»ΡΠ½ΠΎΠΌΡ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΈ ΡΠ²Π΅Π» ΠΈΡ ΠΊ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΏΡΠ½ΠΊΡΠ°ΠΌ:
- ΠΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ Π±Π»ΠΈΠ·ΠΊΠ° ΠΊ ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ,
0.5-1
ΠΊΠ°Π΄ΡΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ Π½Π° ΡΡΡΡΠΎΠΉΡΡΠ²Π΅ ΡΡ ΠΎΠΆΠ΅ΠΌ ΠΏΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ Ρ iPhone X). ΠΡΠΎ Π±ΡΠ΄Π΅Ρ ΠΎΠ·Π½Π°ΡΠ°ΡΡ, ΡΡΠΎ Π²Π΅ΡΡ ΠΏΡΠΎΡΠ΅ΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ + ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡΡ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ Π·Π°2
ΡΠ΅ΠΊΡΠ½Π΄Ρ. - ΠΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΡΠ»ΠΊΠΈ Π½Π° Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠΌ ΡΠ·ΡΠΊΠ΅.
- ΠΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΡΠ»ΠΊΠΈ ΡΠ΅ΡΠ½ΠΎΠ³ΠΎ (ΡΠ΅ΠΌΠ½ΠΎ-ΡΠ΅ΡΠΎΠ³ΠΎ) ΡΠ²Π΅ΡΠ° Π½Π° Π±Π΅Π»ΠΎΠΌ (ΡΠ²Π΅ΡΠ»ΠΎ-ΡΠ΅ΡΠΎΠΌ) ΡΠΎΠ½Π΅.
- ΠΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ
https://
ΡΡΡΠ»ΠΊΠΈ (Π΄ΠΎΠΏΡΡΠΊΠ°Π΅ΡΡΡ, ΡΡΠΎhttp://
,ftp://
,tcp://
ΠΈ ΠΏΡΠΎΡΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Ρ).
𧩠ΠΠ°Ρ ΠΎΠ΄ΠΈΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅
ΠΠ±ΡΠΈΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄
ΠΠ°ΡΠΈΠ°Π½Ρ β1: ΠΠΎΠ΄Π΅Π»Ρ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΡΠ΅ΡΠ²Π΅ΡΠ°
ΠΠ»Π³ΠΎΡΠΈΡΠΌ Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ:
- ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ Π²ΠΈΠ΄Π΅ΠΎ-ΠΏΠΎΡΠΎΠΊ (ΠΊΠ°Π΄Ρ Π·Π° ΠΊΠ°Π΄ΡΠΎΠΌ) Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
- ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΊΠ°Π΄Ρ Π½Π° ΡΠ΅ΡΠ²Π΅Ρ.
- ΠΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΠΌ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΡ.
- ΠΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΠΌ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ Π½ΠΈ ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΈ Π΄Π΅Π»Π°Π΅ΠΌ ΠΈΡ ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡΠ½ΡΠΌΠΈ.
ΠΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°:
- π Π‘ΠΊΠΎΡΠΎΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΡΡΠ»ΠΎΠΊ Π½Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡΡ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ³ΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²Π°. ΠΡΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΊΠΎΡΠΈΡΡ ΡΠΊΠΎΡΠΎΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΡΡΡΠ»ΠΎΠΊ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΡΡ Π½Π°ΡΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ° Π³ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»ΡΠ½ΠΎ (Π±ΠΎΠ»ΡΡΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ²) ΠΈΠ»ΠΈ Π²Π΅ΡΡΠΈΠΊΠ°Π»ΡΠ½ΠΎ (Π±ΠΎΠ»ΡΡΠ΅ ΡΠ΄Π΅Ρ ΠΈ GPUs).
- π ΠΠΎΠ΄Π΅Π»Ρ ΠΌΠΎΠΆΠ΅Ρ ΠΈΠΌΠ΅ΡΡ Π±ΠΎΠ»ΡΡΠΈΠΉ ΡΠ°Π·ΠΌΠ΅Ρ (ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π±ΠΎΠ»ΡΡΡΡ ΡΠΎΡΠ½ΠΎΡΡΡ), ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Π΅Π΅ Π·Π°Π³ΡΡΠ·ΠΊΠΈ Π½Π° ΡΡΠΎΡΠΎΠ½Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°. ΠΠ°Π³ΡΡΠ·ΠΈΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ
~10Mb
Π½Π° ΡΡΠΎΡΠΎΠ½Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ΅Π°Π»ΠΈΡΡΠΈΡΠ½ΡΠΌ, Π½ΠΎ Π²ΡΠ΅-ΠΆΠ΅ Π·Π°Π³ΡΡΠ·ΠΈΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ~100Mb
ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°ΡΠΈΡΠ½ΡΠΌ Ρ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ UX (user experience). - π Π£ Π½Π°Ρ ΠΏΠΎΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΌΠΎΠ΄Π΅Π»ΠΈ. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΠΎΠ΄Π΅Π»Ρ "ΡΠΏΡΡΡΠ°Π½Π°" Π·Π° ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ API, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠ°ΠΊΠΈΠΌ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°ΠΌ ΠΎΠ½Π° Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ½Π°.
ΠΠ΅Π΄ΠΎΡΡΠ°ΡΠΊΠΈ:
- π Π‘Π»ΠΎΠΆΠ½ΠΎΡΡΡ ΡΠΈΡΡΠ΅ΠΌΡ ΡΠ°ΡΡΠ΅Ρ. ΠΠΌΠ΅ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π»ΠΈΡΡ
JavaScript
Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π±ΡΠ΄Π΅Ρ ΡΠ°ΠΊ ΠΆΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ,Python
ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΡΠ΅ΡΠ²Π΅ΡΠ°. ΠΠ°ΠΌ ΡΠ°ΠΊ ΠΆΠ΅ Π±ΡΠ΄Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ·Π°Π±ΠΎΡΠΈΡΡΡΡ ΠΎΠ± Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΌ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΡΠ΅ΡΠ²ΠΈΡΠ°. - π Π Π°Π±ΠΎΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΎΡΡΠ»Π°ΠΉΠ½ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΈΠ½ΡΠ΅ΡΠ½Π΅ΡΡ.
- π ΠΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ HTTP Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΊ ΡΠ΅ΡΠ²ΠΈΡΡ ΡΠΎ ΡΡΠΎΡΠΎΠ½Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°ΡΡ ΡΠ»Π°Π±ΡΠΌ ΠΌΠ΅ΡΡΠΎΠΌ ΡΠΈΡΡΠ΅ΠΌΡ Ρ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΠΌΡ Ρ
ΠΎΡΠΈΠΌ ΡΠ»ΡΡΡΠΈΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΡΡΠ»ΠΎΠΊ Ρ
1
Π΄ΠΎ10+
ΠΊΠ°Π΄ΡΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ. Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ Π±ΡΠ΄Π΅Ρ ΡΠ»Π°ΡΡ10+
Π·Π°ΠΏΡΠΎΡΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ Π½Π° ΡΠ΅ΡΠ²Π΅Ρ. ΠΠ»Ρ10
ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ², ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ, ΡΡΠΎ ΡΠΆΠ΅ Π±ΡΠ΄Π΅Ρ ΠΎΠ·Π½Π°ΡΠ°ΡΡ100+
Π·Π°ΠΏΡΠΎΡΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ. ΠΠ° ΠΏΠΎΠΌΠΎΡΡ ΠΌΠΎΠ³ΡΡ ΠΏΡΠΈΠΉΡΠΈ Π΄Π²ΡΡΡΠΎΡΠΎΠ½Π½ΠΈΠΉ ΡΡΡΠΈΠΌΠΈΠ½Π³HTTP/2
ΠΈgRPC
, Π½ΠΎ ΠΌΡ ΡΠ½ΠΎΠ²Π° Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΡ ΠΊ ΠΏΠ΅ΡΠ²ΠΎΠΌΡ ΠΏΡΠ½ΠΊΡΡ, ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠΌΡ Ρ ΡΠ°ΡΡΡΡΠ΅ΠΉ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡΡ ΡΠΈΡΡΠ΅ΠΌΡ. - π Π‘ΡΠΎΠΈΠΌΠΎΡΡΡ ΡΠΈΡΡΠ΅ΠΌΡ ΡΠ°ΡΡΠ΅Ρ. Π ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΡΡΠΎ ΡΠ²ΡΠ·Π°Π½ΠΎ Ρ ΠΎΠΏΠ»Π°ΡΠΎΠΉ Π·Π° Π°ΡΠ΅Π½Π΄Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ².
ΠΠ°ΡΠΈΠ°Π½Ρ β2: ΠΠΎΠ΄Π΅Π»Ρ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
ΠΠ»Π³ΠΎΡΠΈΡΠΌ Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ:
- ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ Π²ΠΈΠ΄Π΅ΠΎ-ΠΏΠΎΡΠΎΠΊ (ΠΊΠ°Π΄Ρ Π·Π° ΠΊΠ°Π΄ΡΠΎΠΌ) Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
- ΠΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΠΌ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° (Π±Π΅Π· ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π½Π° ΡΠ΅ΡΠ²Π΅Ρ).
- ΠΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΠΌ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ Π½ΠΈ ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΈ Π΄Π΅Π»Π°Π΅ΠΌ ΠΈΡ ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡΠ½ΡΠΌΠΈ.
ΠΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°:
- π ΠΠ΅Π½Π΅Π΅ ΡΠ»ΠΎΠΆΠ½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ°. ΠΠ΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π² ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠ½ΠΎΠΉ ΡΠ°ΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ API.
- π ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΎΡΡΠ»Π°ΠΉΠ½. ΠΠΎΠ΄Π΅Π»Ρ Π·Π°Π³ΡΡΠΆΠ΅Π½Π° Π½Π° ΡΡΠΎΡΠΎΠ½Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΈ Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π² Π΄ΠΎΡΡΡΠΏΠ΅ ΠΊ ΠΈΠ½ΡΠ΅ΡΠ½Π΅ΡΡ (ΡΠΌ. Progressive Web Application)
- π Π‘ΠΈΡΡΠ΅ΠΌΠ° "ΠΏΠΎΡΡΠΈ" Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΡΠ΅ΠΌΠ°. ΠΠ°ΠΆΠ΄ΡΠΉ Π½ΠΎΠ²ΡΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ "ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ" ΡΠΎ ΡΠ²ΠΎΠΈΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠΎΠΌ ΠΈ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°ΡΡΠΎΠΉ. ΠΡΠΎ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ ΠΆΠ΅ Π½Π΅ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎΠ΅ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ (ΠΌΡ Π·Π°ΡΡΠΎΠ½Π΅ΠΌ ΠΏΡΠΈΡΠΈΠ½Ρ Π½ΠΈΠΆΠ΅).
- π Π‘ΠΈΡΡΠ΅ΠΌΠ° Π³ΠΎΡΠ°Π·Π΄ΠΎ Π΄Π΅ΡΠ΅Π²Π»Π΅. ΠΠ°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΏΠ»Π°ΡΠΈΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π·Π° ΡΠ΅ΡΠ²Π΅Ρ ΡΠΎ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ (
HTML
,JS
,CSS
, ΡΠ°ΠΉΠ»Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΈ ΠΏΡ.). Π ΡΠ»ΡΡΠ°Π΅ Ρ GitHub, ΡΠ°ΠΊΠΎΠΉ ΡΠ΅ΡΠ²Π΅Ρ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½ Π±Π΅ΡΠΏΠ»Π°ΡΠ½ΠΎ. - π ΠΡΡΡΡΡΡΠ²ΡΠ΅Ρ (ΡΠ°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ ΡΠ΅ΡΠ²Π΅ΡΡ) ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° HTTP Π·Π°ΠΏΡΠΎΡΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ ΠΊ ΡΠ΅ΡΠ²Π΅ΡΠ°ΠΌ.
ΠΠ΅Π΄ΠΎΡΡΠ°ΡΠΊΠΈ:
- π ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π³ΠΎΡΠΈΠ·ΠΎΠ½ΡΠ°Π»ΡΠ½ΠΎΠ΅ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅, ΠΊΠΎΠ³Π΄Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΈΠΌΠ΅Π΅Ρ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΡ ΠΈ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΡΡ ΠΊΠ°ΡΡΡ. ΠΠ΅ΡΡΠΈΠΊΠ°Π»ΡΠ½ΠΎΠ΅ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ²Π»ΠΈΡΡΡ Π½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ³ΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²Π°. Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°ΡΡ Π±ΡΡΡΡΠΎΠ³ΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΡΡΠ»ΠΎΠΊ Π΄Π»Ρ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΡΡ ΡΡΡΡΠΎΠΉΡΡΠ².
- π ΠΠ΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°ΠΌΠΈ. ΠΠ°ΠΆΠ΄ΡΠΉ ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π³ΡΡΠ·ΠΈΡΡ ΠΊ ΡΠ΅Π±Π΅ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π΅ Π³Π΄Π΅ ΠΈ ΠΊΠ°ΠΊ ΡΠ³ΠΎΠ΄Π½ΠΎ.
- π Π‘ΠΊΠΎΡΠΎΡΡΡ ΡΠ°ΡΡ ΠΎΠ΄Π° Π±Π°ΡΠ°ΡΠ΅ΠΈ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ³ΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²Π° ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ. ΠΠΎΠ΄Π΅Π»Ρ ΠΏΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ ΠΏΠΎΡΡΠ΅Π±Π»ΡΠ΅Ρ Π²ΡΡΠΈΡΠ»ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠ΅ΡΡΡΡΡ. ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π½Π΅Π΄ΠΎΠ²ΠΎΠ»ΡΠ½Ρ ΡΠ΅ΠΌ, ΡΡΠΎ ΠΈΡ iPhone ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π²ΡΠ΅ ΡΠ΅ΠΏΠ»Π΅Π΅ ΠΈ ΡΠ΅ΠΏΠ»Π΅Π΅ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π±ΠΎΡΡ.
ΠΡΠ±ΠΈΡΠ°Π΅ΠΌ ΠΎΠ±ΡΠΈΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ΅Π»Ρ ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ ΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ° Π² ΡΠ΅Π»ΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅, Π° Π½Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΊΠΎΠΌΠΌΠ΅ΡΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΡΠΎΠ²Π½Ρ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ±ΡΠ°ΡΡ Π²ΡΠΎΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΈ Ρ ΡΠ°Π½ΠΈΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°. ΠΡΠΎ ΡΠ΄Π΅Π»Π°Π΅Ρ Π²Π΅ΡΡ ΠΏΡΠΎΠ΅ΠΊΡ ΠΌΠ΅Π½Π΅Π΅ Π·Π°ΡΡΠ°ΡΠ½ΡΠΌ ΠΈ Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΡΡΠΎΠΊΡΡΠΈΡΠΎΠ²Π°ΡΡΡΡ Π½Π° ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠΌ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠΈ, Π° Π½Π΅ Π½Π° ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΡΠ΅ΠΌΠΎΠΉ ΡΠ΅ΡΠ²Π΅ΡΠ½ΠΎΠΉ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΡ.
Π£Π³Π»ΡΠ±Π»ΡΠ΅ΠΌΡΡ Π² Π΄Π΅ΡΠ°Π»ΠΈ
ΠΡΠ°ΠΊ, ΠΌΡ Π²ΡΠ±ΡΠ°Π»ΠΈ Π²Π°ΡΠΈΠ°Π½Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π±Π΅Π· ΡΠ΅ΡΠ²Π΅ΡΠ½ΠΎΠΉ ΡΠ°ΡΡΠΈ. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ ΡΠ΅ΠΏΠ΅ΡΡ, ΡΡΠΎ Ρ Π½Π°Ρ Π½Π° Π²Ρ ΠΎΠ΄Π΅ Π΅ΡΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ (ΠΊΠ°Π΄Ρ) ΠΈΠ· Π²ΠΈΠ΄Π΅ΠΎ-ΠΏΠΎΡΠΎΠΊΠ° ΠΊΠ°ΠΌΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ:
ΠΠ°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ΅ΡΠΈΡΡ Π΄Π²Π΅ ΠΏΠΎΠ΄Π·Π°Π΄Π°ΡΠΈ:
- ΠΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ (Π½Π°ΠΉΡΠΈ ΠΏΠΎΠ·ΠΈΡΠΈΡ ΠΈ Π³Π°Π±Π°ΡΠΈΡΡ ΡΡΡΠ»ΠΎΠΊ Π½Π° ΡΡΡΠ°Π½ΠΈΡΠ΅)
- Π Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ (ΡΠ°ΡΠΏΠΎΠ·Π½Π°ΡΡ ΡΠ΅ΠΊΡΡ ΡΡΡΠ»ΠΎΠΊ)
ΠΠ°ΡΠΈΠ°Π½Ρ β1: Π Π΅ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Tesseract
ΠΠ΅ΡΠ²ΡΠΌ ΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΡΠΌ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ Π·Π°Π΄Π°ΡΠΈ ΠΎΠΏΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² (OCR) ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ° Π²ΡΠ΅Π³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Tesseract.js. ΠΠ½Π° ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Π²Ρ ΠΎΠ΄ ΠΈ Π²ΡΠ΄Π°Π΅Ρ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡΠ΅ ΠΏΠ°ΡΠ°Π³ΡΠ°ΡΡ, ΡΠ΅ΠΊΡΡΠΎΠ²ΡΠ΅ ΡΡΡΠΎΠΊΠΈ, Π±Π»ΠΎΠΊΠΈ ΡΠ΅ΠΊΡΡΠ° ΠΈ ΡΠ»ΠΎΠ²Π° ΠΈ Π²ΠΌΠ΅ΡΡΠ΅ Ρ Π³Π°Π±Π°ΡΠΈΡΠ°ΠΌΠΈ ΠΈ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠ°ΠΌΠΈ.
ΠΠ°Π»Π΅Π΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΏΡΡΠ°ΡΡΡΡ Π½Π°ΠΉΡΠΈ ΡΡΡΠ»ΠΊΠΈ Π² ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΠΎΠΌ ΡΠ΅ΠΊΡΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎΠ³ΠΎ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΏΠΎΡ ΠΎΠΆΠ΅Π³ΠΎ Π½Π° ΡΡΠΎ (ΠΏΡΠΈΠΌΠ΅Ρ Π½Π° TypeScript):
const URL_REG_EXP = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi;
const extractLinkFromText = (text: string): string | null => {
const urls: string[] | null = text.match(URL_REG_EXP);
if (!urls || !urls.length) {
return null;
}
return urls[0];
};
π ΠΠΎΡ ΠΎΠΆΠ΅, ΡΡΠΎ Π·Π°Π΄Π°ΡΠ° ΡΠ΅ΡΠ΅Π½Π° Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΏΡΡΠΌΠΎΠ»ΠΈΠ½Π΅ΠΉΠ½ΡΠΌ ΠΈ ΠΏΡΠΎΡΡΡΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ:
- ΠΡ Π·Π½Π°Π΅ΠΌ Π³Π°Π±Π°ΡΠΈΡΡ ΠΈ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ ΡΡΡΠ»ΠΎΠΊ.
- ΠΡ ΡΠ°ΠΊ ΠΆΠ΅ Π·Π½Π°Π΅ΠΌ ΡΠ΅ΠΊΡΡ ΡΡΡΠ»ΠΎΠΊ ΠΈ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°ΡΡ ΠΈΡ ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡΠ½ΡΠΌΠΈ.
π ΠΡΠΎΠ±Π»Π΅ΠΌΠ° Π² ΡΠΎΠΌ, ΡΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ + ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΌΠΎΠΆΠ΅Ρ Π²Π°ΡΡΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΎΡ 2
Π΄ΠΎ 20+
ΡΠ΅ΠΊΡΠ½Π΄ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠ°Π·ΠΌΠ΅ΡΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, Π΅Π³ΠΎ ΠΊΠ°ΡΠ΅ΡΡΠ²Π° ΠΈ "ΠΏΠΎΡ
ΠΎΠΆΠΈΡ
Π½Π° ΡΠ΅ΠΊΡΡ" ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ. Π ΠΈΡΠΎΠ³Π΅ Π±ΡΠ΄Π΅Ρ ΠΎΡΠ΅Π½Ρ ΡΠ»ΠΎΠΆΠ½ΠΎ Π΄ΠΎΡΡΠΈΡΡ ΡΠΎΠΉ Π±Π»ΠΈΠ·ΠΊΠΎΠΉ ΠΊ ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ Π² 0.5-1
ΠΊΠ°Π΄ΡΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ.
π Π’Π°ΠΊΠΆΠ΅, Π΅ΡΠ»ΠΈ ΠΏΠΎΠ΄ΡΠΌΠ°ΡΡ, ΡΠΎ ΠΌΡ ΠΏΡΠΎΡΠΈΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°ΡΡ Π²Π΅ΡΡ ΡΠ΅ΠΊΡΡ Π½Π° ΠΊΠ°ΡΡΠΈΠ½ΠΊΠ΅, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π² ΡΠ΅ΠΊΡΡΠ΅ ΡΠΎΠ²ΡΠ΅ΠΌ Π½Π΅Ρ ΡΡΡΠ»ΠΎΠΊ ΠΈΠ»ΠΈ Π΅ΡΠ»ΠΈ Π² ΡΠ΅ΠΊΡΡΠ΅ Π΅ΡΡΡ ΠΎΠ΄Π½Π°-Π΄Π²Π΅ ΡΡΡΠ»ΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΡΡΠ°Π²Π»ΡΡΡ, ΠΏΡΡΠΊΠ°ΠΉ, ~10% ΠΎΡ Π²ΡΠ΅Π³ΠΎ ΠΎΠ±ΡΠ΅ΠΌΠ° ΡΠ΅ΠΊΡΡΠ°. ΠΡΠΎ Π·Π²ΡΡΠΈΡ ΠΊΠ°ΠΊ Π½Π΅ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½Π°Ρ ΡΡΠ°ΡΠ° Π²ΡΡΠΈΡΠ»ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΠ΅ΡΡΡΡΠΎΠ².
ΠΠ°ΡΠΈΠ°Π½Ρ β2: Π Π΅ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Tesseract ΠΈ TensorFlow (+1 ΠΌΠΎΠ΄Π΅Π»Ρ)
ΠΡ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ Π·Π°ΡΡΠ°Π²ΠΈΡΡ Tesseract ΡΠ°Π±ΠΎΡΠ°ΡΡ Π±ΡΡΡΡΠ΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ "Π°Π»Π³ΠΎΡΠΈΡΠΌ-ΡΠΎΠ²Π΅ΡΡΠΈΠΊ" ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΡΠΈΡΡΡΠΏΠΈΡΡ ΠΊ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΡΡΠ»ΠΎΠΊ. ΠΡΠΎΡ "Π°Π»Π³ΠΎΡΠΈΡΠΌ-ΡΠΎΠ²Π΅ΡΡΠΈΠΊ" Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ (Π½ΠΎ Π½Π΅ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΡ) Π½Π°ΡΠ°Π»ΠΎ ΡΡΡΠ»ΠΎΠΊ (ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ ΡΠ°ΠΌΠΎΠΉ Π»Π΅Π²ΠΎΠΉ Π³ΡΠ°Π½ΠΈΡΡ ΡΡΡΠ»ΠΊΠΈ) Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΡΠ»ΠΊΠΈ Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ Π½Π°ΠΌ ΡΡΠΊΠΎΡΠΈΡΡ Π·Π°Π΄Π°ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ° ΡΡΡΠ»ΠΎΠΊ, Π΅ΡΠ»ΠΈ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΏΡΠ°Π²ΠΈΠ»Π°ΠΌ:
- ΠΡΠ»ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΡΡΡΠ»ΠΊΠΈ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ Tesseract.
- ΠΡΠ»ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΡΠ»ΠΊΠΈ, ΡΠΎ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ "ΠΏΠΎΠΏΡΠΎΡΠΈΡΡ" Tesseract ΡΠ°ΡΠΏΠΎΠ·Π½Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ ΡΠ°ΡΡΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ ΡΠ΅ΠΊΡΡ ΡΡΡΠ»ΠΎΠΊ. ΠΡ Ρ ΠΎΡΠΈΠΌ ΡΡΠ°ΡΠΈΡΡ Π²ΡΠ΅ΠΌΡ Π½Π° ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ "ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ³ΠΎ" Π΄Π»Ρ Π½Π°ΡΠ΅ΠΉ Π·Π°Π΄Π°ΡΠΈ ΡΠ΅ΠΊΡΡΠ°.
ΠΡΠΎΡ "Π°Π»Π³ΠΎΡΠΈΡΠΌ-ΡΠΎΠ²Π΅ΡΡΠΈΠΊ", ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΡΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ Tesseract Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· Π·Π° ΠΎΠ΄Π½ΠΎ ΠΈ ΡΠΎ ΠΆΠ΅ Π²ΡΠ΅ΠΌΡ, Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΠΊΠ°ΡΠ΅ΡΡΠ²Π° ΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ. ΠΠ½ ΡΠ°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π±ΡΡΡΡΡΠΌ ΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ Π½Π°Π»ΠΈΡΠΈΠ΅ ΠΈ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΡΡΡΠ»ΠΎΠΊ Π±ΡΡΡΡΠ΅Π΅ ΡΠ΅ΠΌ Π·Π° 1
ΡΠ΅ΠΊΡΠ½Π΄Ρ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π° iPhone X). Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΏΡΡΠ°ΡΡΡΡ Π·Π°ΡΡΠ°Π²ΠΈΡΡ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ Π±Π»ΠΈΠ·ΠΊΠΎΠΌ ΠΊ ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ (ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ "Π±Π»ΠΈΠ·ΠΎΡΡΠΈ" ΠΌΡ Π΄Π°Π»ΠΈ Π²ΡΡΠ΅).
π‘ ΠΡΠ°ΠΊ, ΡΡΠΎ Π΅ΡΠ»ΠΈ ΠΌΡ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ Π΅ΡΠ΅ ΠΎΠ΄Π½ΠΈΠΌ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠΌ (Π΅ΡΠ΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΡΡ) ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π½Π°ΠΌ Π½Π°ΠΉΡΠΈ ΡΡΡΠΎΠΊΠΈ
https://
Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ (ΠΊΠ°ΠΆΠ΄Π°Ρ Π·Π°ΡΠΈΡΠ΅Π½Π½Π°Ρ ΡΡΡΠ»ΠΊΠ° Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ Ρhttps://
, Π½Π΅ ΡΠ°ΠΊ Π»ΠΈ?). Π’ΠΎΠ³Π΄Π°, Π·Π½Π°Ρ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π³Π°Π±Π°ΡΠΈΡΡ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠ²https://
Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ, ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ Π½Π° ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Tesseract ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ ΡΠ°ΡΡΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ ΠΏΠΎ ΠΏΡΠ°Π²ΡΡ ΡΡΠΎΡΠΎΠ½Ρ ΠΎΡ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠ²https://
ΠΈ ΡΠ²Π»ΡΡΡΡΡ ΠΈΡ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ΠΌ.
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½ΠΈΠΆΠ΅:
ΠΠ° ΡΡΠΎΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Tesseract Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ Π³ΠΎΡΠ°Π·Π΄ΠΎ ΠΌΠ΅Π½ΡΡΠ΅ ΡΠ°Π±ΠΎΡΡ ΠΏΠΎ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ°, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠ΄ΡΠΊΠ°ΠΆΠ΅ΠΌ Π΅ΠΌΡ, Π³Π΄Π΅ Π² ΡΠ΅ΠΊΡΡΠ΅ ΠΌΠΎΠ³ΡΡ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡΡ ΡΡΡΠ»ΠΊΠΈ (ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π³ΠΎΠ»ΡΠ±ΡΡ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊΠΎΠ², ΡΠ΅ΠΌ Π½Π΅ Π΄ΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΡΡΡΠ²ΠΎ π€).
ΠΡΠ°ΠΊ, Π²ΠΎΠΏΡΠΎΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡΠ²Π΅ΡΠΈΡΡ ΡΠ΅ΠΏΠ΅ΡΡ, ΠΊΠ°ΠΊΡΡ ΠΆΠ΅ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π½Π°ΠΌ Π²ΡΠ±ΡΠ°ΡΡ ΠΈ ΠΊΠ°ΠΊ "Π½Π°ΡΡΠΈΡΡ" Π΅Π΅ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΠΏΡΠ΅ΡΠΈΠΊΡΡ https://
.
ΠΠ°ΠΊΠΎΠ½Π΅Ρ-ΡΠΎ ΠΌΡ ΠΏΠΎΠ΄ΠΎΠ±ΡΠ°Π»ΠΈΡΡ Π±Π»ΠΈΠΆΠ΅ ΠΊ TensorFlow π
π€ ΠΡΠ±ΠΈΡΠ°Π΅ΠΌ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²
Π’ΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠ° Π½ΠΎΠ²ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ Π½ΡΠ»Ρ Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ Ρ ΠΎΡΠΎΡΠΈΠΌ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠΌ Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΏΡΠΈΡΠΈΠ½Π°ΠΌ:
- π Π’ΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π½ΡΡΡ Π΄Π½ΠΈ/Π½Π΅Π΄Π΅Π»ΠΈ ΠΈ ΡΡΠΎΠΈΡΡ ΠΌΠ½ΠΎΠ³ΠΎ Π΄Π΅Π½Π΅Π³ (Π·Π° Π°ΡΠ΅Π½Π΄Ρ ΡΠ΅Ρ -ΠΆΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² Ρ GPU).
- π Π£ Π½Π°Ρ ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΡΠΎΠ±ΡΠ°ΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
, ΡΠΎΡΡΠΎΡΡΠΈΠΉ ΠΈΠ· ΡΠΎΡΠ΅Π½ ΡΡΡΡΡ ΡΠΎΡΠΎΠ³ΡΠ°ΡΠΈΠΉ ΠΊΠ½ΠΈΠ³ ΠΈ ΠΆΡΡΠ½Π°Π»ΠΎΠ² ΡΠΎ ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ. Π’Π΅ΠΌ-Π±ΠΎΠ»Π΅Π΅, ΡΡΠΎ Π½Π°ΠΌ Π½ΡΠΆΠ½Ρ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, Π½ΠΎ Π΅ΡΠ΅ ΠΈ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠ²
https://
Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ . Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΏΡΡΠ°ΡΡΡΡ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΊΠΎΠΉ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ , Π½ΠΎ ΠΎΠ± ΡΡΠΎΠΌ Π½ΠΈΠΆΠ΅.
ΠΡΠ°ΠΊ, Π²ΠΌΠ΅ΡΡΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π½ΠΎΠ²ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΎΠ±ΡΡΠ°ΡΡ ΡΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΡΡ ΠΈ Π½Π°ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ Π½ΠΎΠ²ΡΠΉ Π΄Π»Ρ Π½Π΅Π΅ ΠΊΠ»Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² (ΡΠΌ. transfer learning). Π Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎΠ΄ "Π½ΠΎΠ²ΡΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ" ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΌΡ ΠΈΠΌΠ΅Π΅ΠΌ Π² Π²ΠΈΠ΄Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΏΡΠ΅ΡΠΈΠΊΡΠ° https://
. Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°:
- π ΠΠ°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π³ΠΎΡΠ°Π·Π΄ΠΎ ΠΌΠ΅Π½ΡΡΠΈΠΌ. ΠΠ΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠΎΠ±ΠΈΡΠ°ΡΡ ΡΠΎΡΠ½ΠΈ ΡΡΡΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°ΡΠΈΡΠΌΠΈ (ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠ°ΠΌΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ). ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΠΎΠΉΡΠΈΡΡ ΡΠΎΡΠ½Π΅ΠΉ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΈ ΡΠ΄Π΅Π»Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π²ΡΡΡΠ½ΡΡ. ΠΡΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎ ΡΠΎΠΉ ΠΏΡΠΈΡΠΈΠ½Π΅, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠΆΠ΅ Π½Π°ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°Π½Π½Π° Π½Π° ΠΎΠ±ΡΠ΅ΠΌ Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ ΡΠΈΠΏΠ° COCO ΠΈ ΡΠΆΠ΅ ΡΠΌΠ΅Π΅Ρ ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΡΠ΅ Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (Π½Π°ΡΡΠΈΡΡ "ΠΏΠ΅ΡΠ²ΠΎΠΊΡΡΡΠ½ΠΈΠΊΠ°" Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π°Π»Π³Π΅Π±ΡΠ΅, ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, Π»Π΅Π³ΡΠ΅, ΡΠ΅ΠΌ "ΠΏΠ΅ΡΠ²ΠΎΠΊΠ»Π°ΡΡΠ½ΠΈΠΊΠ°").
- π ΠΡΠ΅ΠΌΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ ΡΠ°ΠΊ ΠΆΠ΅ Π±ΡΠ΄Π΅Ρ Π³ΠΎΡΠ°Π·Π΄ΠΎ ΠΌΠ΅Π½ΡΡΠΈΠΌ (Π½Π° GPU ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΌΠΈΠ½ΡΡΡ/ΡΠ°ΡΡ Π²ΠΌΠ΅ΡΡΠΎ Π΄Π½Π΅ΠΉ/Π½Π΅Π΄Π΅Π»Ρ). ΠΡΠ΅ΠΌΡ ΡΠΎΠΊΡΠ°ΡΠ°Π΅ΡΡΡ Π·Π° ΡΡΠ΅Ρ ΠΌΠ΅Π½ΡΡΠ΅Π³ΠΎ ΠΎΠ±ΡΠ΅ΠΌΠ° Π΄Π°Π½Π½ΡΡ (ΠΌΠ΅Π½ΡΡΠΈΡ ΠΏΠ°ΡΡΠΈΠΉ Π΄Π°Π½Π½ΡΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ) ΠΈ ΠΌΠ΅Π½ΡΡΠ΅Π³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΡΡΠ΅Π½ΠΈΡΡΠ΅ΠΌΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΌΠΎΠ΄Π΅Π»ΠΈ.
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ±ΡΠ°ΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈΠ· "Π·ΠΎΠΎΠΏΠ°ΡΠΊΠ°" ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ TensorFlow 2, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π½Π°ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
Π½Π° Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ
COCO 2017. ΠΠ° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΡΡΠ° ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ ~40
ΡΠ°Π·Π½ΡΡ
Π²Π°ΡΠΈΠ°ΡΠΈΠΉ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ.
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ "Π½Π°ΡΡΠΈΡΡ" ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ Π½ΠΎΠ²ΡΠ΅, ΡΠ°Π½Π΅Π΅ Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅ Π΅ΠΉ ΠΎΠ±ΡΠ΅ΠΊΡΡ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ TensorFlow 2 Object Detection API. TensorFlow Object Detection API - ΡΡΠΎ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ TensorFlow, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΊΠΎΠ½ΡΡΡΡΠΈΡΠΎΠ²Π°ΡΡ ΠΈ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
ΠΡΠ»ΠΈ Π²Ρ ΠΏΠ΅ΡΠ΅ΠΉΠ΄Π΅ΡΠ΅ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅ Π½Π° "Π·ΠΎΠΎΠΏΠ°ΡΠΊ" ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π²Ρ ΡΠ²ΠΈΠ΄ΠΈΡΠ΅, ΡΡΠΎ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΡΠ°ΠΌ ΡΠΊΠ°Π·Π°Π½Π° ΡΠΊΠΎΡΠΎΡΡΡ ΠΈ ΡΠΎΡΠ½ΠΎΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
ΠΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π²Π·ΡΡΠΎ Ρ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ TensorFlow Model Zoo
ΠΠΎΠ½Π΅ΡΠ½ΠΎ ΠΆΠ΅, Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ Π²ΡΠ±ΡΠ°ΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ, Π½Π°ΠΌ Π²Π°ΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ Π±Π°Π»Π°Π½Ρ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΊΠΎΡΠΎΡΡΡΡ ΠΈ ΡΠΎΡΠ½ΠΎΡΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ. ΠΠΎ ΡΡΠΎ Π΅ΡΠ΅ Π²Π°ΠΆΠ½Π΅Π΅ Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅, ΡΡΠΎ ΡΠ°Π·ΠΌΠ΅Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ ΠΏΠ»Π°Π½ΠΈΡΡΠ΅ΠΌ Π·Π°Π³ΡΡΠΆΠ°ΡΡ Π΅Π΅ Π½Π° ΡΡΠΎΡΠΎΠ½Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
Π Π°Π·ΠΌΠ΅Ρ Π°ΡΡ
ΠΈΠ²Π° Ρ ΠΌΠΎΠ΄Π΅Π»ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π²Π°ΡΡΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΎΡ ~20Mb
Π΄ΠΎ ~1Gb
. ΠΠΎΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ²:
1386 (Mb)
centernet_hg104_1024x1024_kpts_coco17_tpu-32
330 (Mb)
centernet_resnet101_v1_fpn_512x512_coco17_tpu-8
195 (Mb)
centernet_resnet50_v1_fpn_512x512_coco17_tpu-8
198 (Mb)
centernet_resnet50_v1_fpn_512x512_kpts_coco17_tpu-8
227 (Mb)
centernet_resnet50_v2_512x512_coco17_tpu-8
230 (Mb)
centernet_resnet50_v2_512x512_kpts_coco17_tpu-8
29 (Mb)
efficientdet_d0_coco17_tpu-32
49 (Mb)
efficientdet_d1_coco17_tpu-32
60 (Mb)
efficientdet_d2_coco17_tpu-32
89 (Mb)
efficientdet_d3_coco17_tpu-32
151 (Mb)
efficientdet_d4_coco17_tpu-32
244 (Mb)
efficientdet_d5_coco17_tpu-32
376 (Mb)
efficientdet_d6_coco17_tpu-32
376 (Mb)
efficientdet_d7_coco17_tpu-32
665 (Mb)
extremenet
427 (Mb)
faster_rcnn_inception_resnet_v2_1024x1024_coco17_tpu-8
424 (Mb)
faster_rcnn_inception_resnet_v2_640x640_coco17_tpu-8
337 (Mb)
faster_rcnn_resnet101_v1_1024x1024_coco17_tpu-8
337 (Mb)
faster_rcnn_resnet101_v1_640x640_coco17_tpu-8
343 (Mb)
faster_rcnn_resnet101_v1_800x1333_coco17_gpu-8
449 (Mb)
faster_rcnn_resnet152_v1_1024x1024_coco17_tpu-8
449 (Mb)
faster_rcnn_resnet152_v1_640x640_coco17_tpu-8
454 (Mb)
faster_rcnn_resnet152_v1_800x1333_coco17_gpu-8
202 (Mb)
faster_rcnn_resnet50_v1_1024x1024_coco17_tpu-8
202 (Mb)
faster_rcnn_resnet50_v1_640x640_coco17_tpu-8
207 (Mb)
faster_rcnn_resnet50_v1_800x1333_coco17_gpu-8
462 (Mb)
mask_rcnn_inception_resnet_v2_1024x1024_coco17_gpu-8
86 (Mb)
ssd_mobilenet_v1_fpn_640x640_coco17_tpu-8
44 (Mb)
ssd_mobilenet_v2_320x320_coco17_tpu-8
20 (Mb)
ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8
20 (Mb)
ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
369 (Mb)
ssd_resnet101_v1_fpn_1024x1024_coco17_tpu-8
369 (Mb)
ssd_resnet101_v1_fpn_640x640_coco17_tpu-8
481 (Mb)
ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8
480 (Mb)
ssd_resnet152_v1_fpn_640x640_coco17_tpu-8
233 (Mb)
ssd_resnet50_v1_fpn_1024x1024_coco17_tpu-8
233 (Mb)
ssd_resnet50_v1_fpn_640x640_coco17_tpu-8
ΠΠΎΠ΄Π΅Π»Ρ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
Π²ΡΠ³Π»ΡΠ΄ΠΈΡ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠ΅ΠΉ Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅:
- π ΠΠ½Π° ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½Π΅Π±ΠΎΠ»ΡΡΠ°Ρ -
20Mb
Π² Π°ΡΡ ΠΈΠ²Π΅. - π ΠΠ½Π° Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π±ΡΡΡΡΠ°Ρ -
39ms
Π½Π° ΠΎΠ΄Π½ΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅. - π ΠΠ½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΠ΅ΡΡ MobileNet v2 Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠΊΡΡΡΠ°ΠΊΡΠΎΡΠ° ΡΠ²ΠΎΠΉΡΡΠ² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (feature extractor), ΠΊΠΎΡΠΎΡΠ°Ρ Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π° ΠΏΠΎΠ΄ ΡΠ°Π±ΠΎΡΡ Π½Π° ΠΌΠΎΠ±ΠΈΠ»ΡΠ½ΡΡ ΡΡΡΡΠΎΠΉΡΡΠ²Π°Ρ ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΠΌΠ΅Π½ΡΡΠΈΠΉ ΡΠ°ΡΡ ΠΎΠ΄ Π±Π°ΡΠ°ΡΠ΅ΠΈ.
- π ΠΠ½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΡ Π΅ΠΉ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ Π·Π° ΠΎΠ΄ΠΈΠ½ ΠΏΡΠΎΡ ΠΎΠ΄ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ ΡΠ°Π³ regions proposal, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ ΡΠ°Π±ΠΎΡΡ ΡΠ΅ΡΠΈ Π±ΡΡΡΡΠ΅Π΅).
- π Π ΡΠΎ ΠΆΠ΅ Π²ΡΠ΅ΠΌΡ ΡΡΠΎ Π½Π΅ ΡΠ°ΠΌΠ°Ρ ΡΠΎΡΠ½Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ (Π²ΡΠ΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠΎΠΌΠΏΡΠΎΠΌΠΈΡΡΠΎΠΌ βοΈ)
ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ Π΅Π΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π°ΠΆΠ½ΡΡ Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊ, Ρ ΠΊΠΎΡΠΎΡΡΠΌΠΈ Π²Ρ ΠΏΡΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Π΄Π΅ΡΠ°Π»ΡΠ½Π΅Π΅:
- ΠΠΆΠΈΠ΄Π°Π΅ΠΌΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π½Π° Π²Ρ
ΠΎΠ΄Π΅ -
640x640px
. - ΠΠΎΠ΄Π΅Π»Ρ ΠΏΠΎΡΡΡΠΎΠ΅Π½Π° Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Single Shot MultiBox Detector (SSD) ΠΈ Feature Pyramid Network (FPN).
- Π‘Π²Π΅ΡΡΠΎΡΠ½Π°Ρ Π½Π΅ΠΉΡΠΎΠ½Π½Π°Ρ ΡΠ΅ΡΡ (CNN) MobileNet v2 ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠΊΡΡΡΠ°ΠΊΡΠΎΡΠ° ΡΠ²ΠΎΠΉΡΡΠ² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (feature extractor).
- ΠΠΎΠ΄Π΅Π»Ρ Π±ΡΠ»Π° ΠΎΠ±ΡΡΠ΅Π½Π° Π½Π° Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ COCO
π Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Object Detection API
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ Tensorflow 2 Object Detection API Π² Π²ΠΈΠ΄Π΅ ΠΏΠ°ΠΊΠ΅ΡΠ° Python. ΠΡΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΠ΄ΠΎΠ±Π½ΠΎ, Π² ΡΠ»ΡΡΠ°Π΅ Π΅ΡΠ»ΠΈ Π²Ρ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΡΠ΅ΡΠ΅ Π² Google Colab (ΠΏΡΠ΅Π΄ΠΏΠΎΡΡΠΈΡΠ΅Π»ΡΠ½ΠΎ) ΠΈΠ»ΠΈ Π² Jupyter. Π ΠΎΠ±ΠΎΠΈΡ ΡΠ»ΡΡΠ°ΡΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΈΠ½ΡΡΠ°Π»Π»ΡΡΠΈΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² ΠΈ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅.
Π’Π°ΠΊΠΆΠ΅ Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Object Detection API ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Docker, ΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ.
ΠΡΠ»ΠΈ Ρ Π²Π°Ρ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡ ΡΡΡΠ΄Π½ΠΎΡΡΠΈ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ API ΠΈΠ»ΠΈ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ (ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΠ°Π·Π΄Π΅Π»Ρ), Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΠΊ ΡΡΠ°ΡΡΠ΅ TensorFlow 2 Object Detection API tutorial, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π΅ΡΡΡ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΡΡ Π΄Π΅ΡΠ°Π»Π΅ΠΉ ΠΈ ΡΠΎΠ²Π΅ΡΠΎΠ².
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΊΠ»ΠΎΠ½ΠΈΡΡΠ΅ΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Ρ API:
git clone --depth 1 https://github.com/tensorflow/models
output β
Cloning into 'models'...
remote: Enumerating objects: 2301, done.
remote: Counting objects: 100% (2301/2301), done.
remote: Compressing objects: 100% (2000/2000), done.
remote: Total 2301 (delta 561), reused 922 (delta 278), pack-reused 0
Receiving objects: 100% (2301/2301), 30.60 MiB | 13.90 MiB/s, done.
Resolving deltas: 100% (561/561), done.
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΉΠ»Ρ-ΠΏΡΠΎΡΠΎΡΠΈΠΏΡ API Π² Python ΡΠΎΡΠΌΠ°Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ protoc:
cd ./models/research
protoc object_detection/protos/*.proto --python_out=.
Π‘Π»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠ°Π³ΠΎΠΌ Π±ΡΠ΄Π΅Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° API Π΄Π»Ρ Π²Π΅ΡΡΠΈΠΈ TensorFlow 2 ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ pip
ΠΈ ΡΠ°ΠΉΠ» setup.py`:
cp ./object_detection/packages/tf2/setup.py .
pip install . --quiet
ΠΡΠ»ΠΈ Π½Π° ΡΡΠΎΠΌ ΡΠ°Π³Π΅ Π²Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ, ΡΠ²ΡΠ·Π°Π½Π½ΡΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΎΠΉ Π·Π°Π²ΠΈΡΠΈΠΌΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², ΠΏΠΎΠΏΡΠΎΠ±ΡΠΉΡΠ΅ Π·Π°ΠΏΡΡΡΠΈΡΡ
pip install . --quiet
Π²ΠΎ Π²ΡΠΎΡΠΎΠΉ ΡΠ°Π·.
ΠΡΠΎΠ²Π΅ΡΠΈΡΡ ΡΡΠΏΠ΅ΡΠ½ΠΎΡΡΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°ΠΏΡΡΡΠΈΠ² ΡΠ΅ΡΡ:
python object_detection/builders/model_builder_tf2_test.py
Π ΠΈΡΠΎΠ³Π΅ Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΠ΄Π΅ΡΠ΅ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ, ΡΡΠΎ-ΡΠΎ Π²ΡΠΎΠ΄Π΅ ΡΡΠΎΠ³ΠΎ:
[ OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
----------------------------------------------------------------------
Ran 20 tests in 45.072s
OK (skipped=1)
TensorFlow Object Detection API ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π°! Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΊΡΠΈΠΏΡΡ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡ ΡΡΠΎΠΉ API, Π΄Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ , ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ ΠΈΠ»ΠΈ Π΄ΠΎΡΠ°Π±ΠΎΡΠΊΠΈ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ.
β¬οΈ ΠΠ°Π³ΡΡΠΆΠ°Π΅ΠΌ Π·Π°ΡΠ°Π½Π΅Π΅ ΠΎΠ±ΡΡΠ΅Π½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ
ΠΠ°Π²Π°ΠΉΡΠ΅ Π·Π°Π³ΡΡΠ·ΠΈΠΌ ΡΠ°Π½Π΅Π΅ Π²ΡΠ±ΡΠ°Π½Π½ΡΡ Π½Π°ΠΌΠΈ ΠΌΠΎΠ΄Π΅Π»Ρ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
ΠΈΠ· ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ TensorFlow ΠΈ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π΅ Π΄Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠΈΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΡΠ°ΠΊΠΈΡ
ΠΊΠ°ΠΊ "ΠΊΠΎΡ", "ΡΠΎΠ±Π°ΠΊΠ°", "ΠΌΠ°ΡΠΈΠ½Π°" ΠΈ ΠΏΡ. (ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠΌΠΈ Π½Π°Π±ΠΎΡΠΎΠΌ Π΄Π°Π½Π½ΡΡ
COCO).
ΠΡ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΡΡΠΈΠ»ΠΈΡΠΎΠΉ TensorFlow get_file() Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ Π°ΡΡ ΠΈΠ²ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΏΠΎ URL ΠΈ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΉ Π΅Π΅ ΡΠ°ΡΠΏΠ°ΠΊΠΎΠ²ΠΊΠΈ.
import tensorflow as tf
import pathlib
MODEL_NAME = 'ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8'
TF_MODELS_BASE_PATH = 'http://download.tensorflow.org/models/object_detection/tf2/20200711/'
CACHE_FOLDER = './cache'
def download_tf_model(model_name, cache_folder):
model_url = TF_MODELS_BASE_PATH + model_name + '.tar.gz'
model_dir = tf.keras.utils.get_file(
fname=model_name,
origin=model_url,
untar=True,
cache_dir=pathlib.Path(cache_folder).absolute()
)
return model_dir
# Start the model download.
model_dir = download_tf_model(MODEL_NAME, CACHE_FOLDER)
print(model_dir)
output β
/content/cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
ΠΠΎΡ ΠΊΠ°ΠΊ Π½Π° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΡΡΡΠΊΡΡΡΠ° ΠΏΠ°ΠΏΠΎΠΊ:
ΠΠ°ΠΏΠΊΠ° checkpoint
ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ "ΡΠ»Π΅ΠΏΠΎΠΊ" ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΎΠ±ΡΡΠ΅Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
Π€Π°ΠΉΠ» pipeline.config
ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ. ΠΡ Π΅ΡΠ΅ Π²Π΅ΡΠ½Π΅ΠΌΡΡ ΠΊ ΡΡΠΎΠΌΡ ΡΠ°ΠΉΠ»Ρ Π½ΠΈΠΆΠ΅, ΠΊΠΎΠ³Π΄Π° Π±ΡΠ΄Π΅ΠΌ ΠΎΠ±ΡΡΠ°ΡΡ Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ.
ππ»βοΈ ΠΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ
ΠΠ° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠΏΠΎΡΠΎΠ±Π½Π° ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΊΠ»Π°ΡΡΠΎΠ², ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΡ
Π½Π°Π±ΠΎΡΠΎΠΌ Π΄Π°Π½Π½ΡΡ
COCO (ΠΈΡ
Π²ΡΠ΅Π³ΠΎ 90), ΡΠ°ΠΊΠΈΡ
, ΠΊΠ°ΠΊ car
, bird
, hot dog
ΠΈ ΠΏΡ. ΠΡΠΈ ΠΊΠ»Π°ΡΡΡ Π΅ΡΠ΅ ΠΌΠΎΠ³ΡΡ Π½Π°Π·ΡΠ²Π°ΡΡ ΡΡΠ»ΡΠΊΠ°ΠΌΠΈ (labels).
ΠΡΡΠΎΡΠ½ΠΈΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ: ΡΠ°ΠΉΡ COCO
ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ, ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡ Π»ΠΈ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΡΠΈΡ ΠΊΠ»Π°ΡΡΠΎΠ².
ΠΠ°Π³ΡΡΠΆΠ°Π΅ΠΌ ΡΡΠ»ΡΠΊΠΈ COCO
Object Detection API ΡΠΆΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΠ°ΠΉΠ» Ρ ΠΏΠΎΠ»Π½ΡΠΌ Π½Π°Π±ΠΎΡ ΠΊΠ»Π°ΡΡΠΎΠ² (ΡΡΠ»ΡΠΊΠΎΠ²) COCO Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ ΡΠ΄ΠΎΠ±ΡΡΠ²Π°.
import os
# Import Object Detection API helpers.
from object_detection.utils import label_map_util
# Loads the COCO labels data (class names and indices relations).
def load_coco_labels():
# Object Detection API already has a complete set of COCO classes defined for us.
label_map_path = os.path.join(
'models/research/object_detection/data',
'mscoco_complete_label_map.pbtxt'
)
label_map = label_map_util.load_labelmap(label_map_path)
# Class ID to Class Name mapping.
categories = label_map_util.convert_label_map_to_categories(
label_map,
max_num_classes=label_map_util.get_max_label_map_index(label_map),
use_display_name=True
)
category_index = label_map_util.create_category_index(categories)
# Class Name to Class ID mapping.
label_map_dict = label_map_util.get_label_map_dict(label_map, use_display_name=True)
return category_index, label_map_dict
# Load COCO labels.
coco_category_index, coco_label_map_dict = load_coco_labels()
print('coco_category_index:', coco_category_index)
print('coco_label_map_dict:', coco_label_map_dict)
output β
coco_category_index:
{
1: {'id': 1, 'name': 'person'},
2: {'id': 2, 'name': 'bicycle'},
...
90: {'id': 90, 'name': 'toothbrush'},
}
coco_label_map_dict:
{
'background': 0,
'person': 1,
'bicycle': 2,
'car': 3,
...
'toothbrush': 90,
}
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ
Π ΡΡΠΎΠΌ ΡΠ°Π·Π΄Π΅Π»Π΅ ΠΌΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΊ Π½Π°Π·ΡΠ²Π°Π΅ΠΌΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΡ Π½Π°ΠΌΠΈ ΡΠ°Π½Π΅Π΅ ΠΌΠΎΠ΄Π΅Π»Ρ, ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎ, Π΄Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ.
import tensorflow as tf
# Import Object Detection API helpers.
from object_detection.utils import config_util
from object_detection.builders import model_builder
# Generates the detection function for specific model and specific model's checkpoint
def detection_fn_from_checkpoint(config_path, checkpoint_path):
# Build the model.
pipeline_config = config_util.get_configs_from_pipeline_file(config_path)
model_config = pipeline_config['model']
model = model_builder.build(
model_config=model_config,
is_training=False,
)
# Restore checkpoints.
ckpt = tf.compat.v2.train.Checkpoint(model=model)
ckpt.restore(checkpoint_path).expect_partial()
# This is a function that will do the detection.
@tf.function
def detect_fn(image):
image, shapes = model.preprocess(image)
prediction_dict = model.predict(image, shapes)
detections = model.postprocess(prediction_dict, shapes)
return detections, prediction_dict, tf.reshape(shapes, [-1])
return detect_fn
inference_detect_fn = detection_fn_from_checkpoint(
config_path=os.path.join('cache', 'datasets', MODEL_NAME, 'pipeline.config'),
checkpoint_path=os.path.join('cache', 'datasets', MODEL_NAME, 'checkpoint', 'ckpt-0'),
)
Π€ΡΠ½ΠΊΡΠΈΡ inference_detect_fn
ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π½Π° Π²Ρ
ΠΎΠ΄Π΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ± ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π½ΡΡ
Π² Π½Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ°Ρ
.
ΠΠ°Π³ΡΡΠΆΠ°Π΅ΠΌ ΡΠ΅ΡΡΠΎΠ²ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π½Π°ΠΉΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ:
ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΡΠΎΡ
ΡΠ°Π½ΠΈΠΌ ΡΡΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΏΠ°ΠΏΠΊΡ inference/test/
Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ°. ΠΡΠ»ΠΈ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ Google Colab, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΡ ΠΏΠ°ΠΏΠΊΡ ΠΈ ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΡ ΡΠ°ΠΉΠ»Π° Π²ΡΡΡΠ½ΡΡ.
ΠΠΎΡ ΠΊΠ°ΠΊ ΡΡΡΡΠΊΡΡΡΠ° ΠΏΠ°ΠΏΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ Π½Π° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ:
import matplotlib.pyplot as plt
%matplotlib inline
# Creating a TensorFlow dataset of just one image.
inference_ds = tf.keras.preprocessing.image_dataset_from_directory(
directory='inference',
image_size=(640, 640),
batch_size=1,
shuffle=False,
label_mode=None
)
# Numpy version of the dataset.
inference_ds_numpy = list(inference_ds.as_numpy_iterator())
# You may preview the images in dataset like this.
plt.figure(figsize=(14, 14))
for i, image in enumerate(inference_ds_numpy):
plt.subplot(2, 2, i + 1)
plt.imshow(image[0].astype("uint8"))
plt.axis("off")
plt.show()
ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΡΠ΅ΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ
ΠΠ° Π΄Π°Π½Π½ΠΎΠΌ ΡΡΠ°ΠΏΠ΅ ΠΌΡ Π³ΠΎΡΠΎΠ²Ρ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅. ΠΠ΅ΡΠ²ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΌΠ°ΡΡΠΈΠ²Π° inference_ds_numpy[0]
ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°ΡΠ΅ ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΡΠ΅ΡΡΠΎΠ²ΠΎΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ ΠΌΠ°ΡΡΠΈΠ²Π° Numpy
.
detections, predictions_dict, shapes = inference_detect_fn(
inference_ds_numpy[0]
)
ΠΡΠΎΠ²Π΅ΡΠΈΠΌ ΡΠ°Π·ΠΌΠ΅ΡΠ½ΠΎΡΡΡ ΠΌΠ°ΡΡΠΈΠ²ΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π°ΠΌ Π²Π΅ΡΠ½ΡΠ»Π° ΡΡΠ½ΠΊΡΠΈΡ:
boxes = detections['detection_boxes'].numpy()
scores = detections['detection_scores'].numpy()
classes = detections['detection_classes'].numpy()
num_detections = detections['num_detections'].numpy()[0]
print('boxes.shape: ', boxes.shape)
print('scores.shape: ', scores.shape)
print('classes.shape: ', classes.shape)
print('num_detections:', num_detections)
output β
boxes.shape: (1, 100, 4)
scores.shape: (1, 100)
classes.shape: (1, 100)
num_detections: 100.0
ΠΠΎΠ΄Π΅Π»Ρ Π²Π΅ΡΠ½ΡΠ»Π° Π½Π°ΠΌ ΠΌΠ°ΡΡΠΈΠ² ΡΠΎ 100
"ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡΠΌΠΈ". ΠΡΠΎ Π½Π΅ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π°ΡΠ»Π° 100
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ. ΠΡΠΎ ΡΠΊΠΎΡΠ΅Π΅ Π³ΠΎΠ²ΠΎΡΠΈΡ Π½Π°ΠΌ, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈΠΌΠ΅Π΅Ρ 100
ΡΡΠ΅Π΅ΠΊ ΠΈ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌ 100
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ. ΠΠ°ΠΆΠ΄ΠΎΠ΅ "ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠ΅" ΠΈΠΌΠ΅Π΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΡΠ΅ΠΉΡΠΈΠ½Π³ (Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡ, score), ΠΊΠΎΡΠΎΡΡΠΉ Π³ΠΎΠ²ΠΎΡΠΈΡ ΠΎΠ± ΡΠ²Π΅ΡΠ΅Π½Π½ΠΎΡΡΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ. ΠΠ°Π±Π°ΡΠΈΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½Π°ΠΉΠ΄Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Ρ
ΡΠ°Π½ΡΡΡΡ Π² ΠΌΠ°ΡΡΠΈΠ²Π΅ boxes
. Π Π΅ΠΉΡΠΈΠ½Π³ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ Ρ
ΡΠ°Π½ΠΈΡΡΡ Π² ΠΌΠ°ΡΡΠΈΠ²Π΅ scores
. ΠΠ°ΡΡΠΈΠ² classes
Ρ
ΡΠ°Π½ΠΈΡ ΡΡΠ»ΡΠΊΠΈ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ "ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ".
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ ΠΏΠ΅ΡΠ²ΡΠ΅ 5 ΡΠ°ΠΊΠΈΡ "ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΠΉ":
print('First 5 boxes:')
print(boxes[0,:5])
print('First 5 scores:')
print(scores[0,:5])
print('First 5 classes:')
print(classes[0,:5])
class_names = [coco_category_index[idx + 1]['name'] for idx in classes[0]]
print('First 5 class names:')
print(class_names[:5])
output β
First 5 boxes:
[[0.17576033 0.84654826 0.25642633 0.88327974]
[0.5187813 0.12410264 0.6344235 0.34545377]
[0.5220358 0.5181462 0.6329132 0.7669856 ]
[0.50933677 0.7045719 0.5619138 0.7446198 ]
[0.44761637 0.51942706 0.61237675 0.75963426]]
First 5 scores:
[0.6950246 0.6343004 0.591157 0.5827219 0.5415643]
First 5 classes:
[9. 8. 8. 0. 8.]
First 5 class names:
['traffic light', 'boat', 'boat', 'person', 'boat']
ΠΠΎΠ΄Π΅Π»Ρ Π²ΠΈΠ΄ΠΈΡ ΡΠ²Π΅ΡΠΎΡΠΎΡ (traffic light
), ΡΡΠΈ Π»ΠΎΠ΄ΠΊΠΈ (boats
) ΠΈ ΡΠ΅Π»ΠΎΠ²Π΅ΠΊΠ° (person
). Π ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠ΄ΠΈΡΡ, ΡΡΠΎ ΡΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΡΡ Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ.
Π ΠΌΠ°ΡΡΠΈΠ²Π΅ scores
ΠΌΡ Π²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠ²Π΅ΡΠ΅Π½Π½Π° (Ρ 70% Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡΡ) Π² Π½Π°ΠΉΠ΄Π΅Π½Π½ΠΎΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ΅ ΠΊΠ»Π°ΡΡΠ° traffic light
.
ΠΠ°ΠΆΠ΄ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΌΠ°ΡΡΠΈΠ²Π° boxes
ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ [y1, x1, y2, x2]
, Π³Π΄Π΅ (x1, y1)
ΠΈ (x2, y2)
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΠΈ ΠΏΡΠ°Π²ΠΎΠ³ΠΎ Π½ΠΈΠΆΠ½Π΅Π³ΠΎ ΡΠ³Π»ΠΎΠ² Π³Π°Π±Π°ΡΠΈΡΠ½ΠΎΠ³ΠΎ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊΠ°.
ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π²ΠΈΠ·ΡΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π³Π°Π±Π°ΡΠΈΡΠ½ΡΠ΅ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊΠΈ:
# Importing Object Detection API helpers.
from object_detection.utils import visualization_utils
# Visualizes the bounding boxes on top of the image.
def visualize_detections(image_np, detections, category_index):
label_id_offset = 1
image_np_with_detections = image_np.copy()
visualization_utils.visualize_boxes_and_labels_on_image_array(
image_np_with_detections,
detections['detection_boxes'][0].numpy(),
(detections['detection_classes'][0].numpy() + label_id_offset).astype(int),
detections['detection_scores'][0].numpy(),
category_index,
use_normalized_coordinates=True,
max_boxes_to_draw=200,
min_score_thresh=.4,
agnostic_mode=False,
)
plt.figure(figsize=(12, 16))
plt.imshow(image_np_with_detections)
plt.show()
# Visualizing the detections.
visualize_detections(
image_np=tf.cast(inference_ds_numpy[0][0], dtype=tf.uint32).numpy(),
detections=detections,
category_index=coco_category_index,
)
Π ΠΈΡΠΎΠ³Π΅ ΠΌΡ ΡΠ²ΠΈΠ΄ΠΈΠΌ:
Π ΡΠΎ ΠΆΠ΅ Π²ΡΠ΅ΠΌΡ, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π½Π° ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΠΌΡ ΡΠ²ΠΈΠ΄ΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
ΠΠΎΠ΄Π΅Π»Ρ Π½Π΅ ΡΠΌΠΎΠ³Π»Π° Π½Π°ΠΉΡΠΈ Π½ΠΈΡΠ΅Π³ΠΎ Π² ΡΡΠΎΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ. ΠΡΠΎ ΠΊΠ°ΠΊ-ΡΠ°Π· ΡΠΎ, ΡΡΠΎ ΠΌΡ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌΡΡ ΠΈΡΠΏΡΠ°Π²ΠΈΡΡ ΠΈ ΡΠ΅ΠΌΡ Ρ
ΠΎΡΠΈΠΌ Π½Π°ΡΡΠΈΡΡ Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ - Π²ΠΈΠ΄Π΅ΡΡ ΠΏΡΠΈΡΡΠ°Π²ΠΊΠΈ https://
Π² ΡΠ΅ΠΊΡΡΠΎΠ²ΡΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
.
π ΠΠΎΠ΄Π³ΠΎΡΠ°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ Π½Π°ΡΡΠΈΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ Π±ΡΠ»ΠΈ ΠΎΠΏΠΈΡΠ°Π½Ρ Π² Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ
COCO Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΡ ΡΠ²ΠΎΠΉ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
ΠΈ "Π΄ΠΎΡΡΠΈΡΡ" ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π° Π½Π΅ΠΌ.
ΠΠ°Π±ΠΎΡΡ Π΄Π°Π½Π½ΡΡ Π΄Π»Ρ Π·Π°Π΄Π°ΡΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΡΠΎΡΡΠΎΡΡ ΠΈΠ· Π΄Π²ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²:
- Π‘ΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎ ΡΠ°ΠΌΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ°ΡΠ½ΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΠΊΠΈ ΠΊΠ½ΠΈΠ³ΠΈ ΠΈΠ»ΠΈ ΠΆΡΡΠ½Π°Π»Π°)
- ΠΠ°Π±Π°ΡΠΈΡΠ½ΡΠ΅ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ Π³Π΄Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½Ρ ΠΎΠ±ΡΠ΅ΠΊΡΡ.
Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π²ΡΡΠ΅ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ
ΠΈ ΠΏΡΠ°Π²ΠΎΠ³ΠΎ Π½ΠΈΠΆΠ½Π΅Π³ΠΎ
ΡΠ³Π»ΠΎΠ² ΠΈΠΌΠ΅ΡΡ Π°Π±ΡΠΎΠ»ΡΡΠ½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ (Π² ΠΏΠΈΠΊΡΠ΅Π»ΡΡ
). Π’Π°ΠΊΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠ΅ ΡΠΏΠΎΡΠΎΠ±Ρ Π·Π°ΠΏΠΈΡΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΡΠ°ΠΊΠΈΡ
Π³Π°Π±Π°ΡΠΈΡΠ½ΡΡ
ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊΠΎΠ². ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΠΈΡΠ°ΡΡ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π΅Π³ΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ ΡΠ΅Π½ΡΡΠ°
, Π° ΡΠ°ΠΊ ΠΆΠ΅ ΡΠΈΡΠΈΠ½Ρ
ΠΈ Π²ΡΡΠΎΡΡ
. ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ (ΠΏΡΠΎΡΠ΅Π½Ρ ΠΎΡ ΡΠΈΡΠΈΠ½Ρ ΠΈΠ»ΠΈ Π²ΡΡΠΎΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ). ΠΠΎ Π² ΡΠ΅Π»ΠΎΠΌ, Π΄ΡΠΌΠ°Ρ ΠΈΠ΄Π΅Ρ ΠΏΠΎΠ½ΡΡΠ½Π°: ΠΌΠΎΠ΄Π΅Π»Ρ Π΄ΠΎΠ»ΠΆΠ½Π° Π·Π½Π°ΡΡ Π³Π΄Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠΎΡ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ.
ΠΠΎΠΏΡΠΎΡ Π² ΡΠΎΠΌ, Π³Π΄Π΅ ΠΆΠ΅ Π½Π°ΠΌ Π²Π·ΡΡΡ ΡΠ°ΠΊΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ. Π£ Π½Π°Ρ Π΅ΡΡΡ ΡΡΠΈ Π²Π°ΡΠΈΠ°Π½ΡΠ°:
- ΠΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΈΠΌΠ΅ΡΡΠΈΠΌΡΡ Π½Π°Π±ΠΎΡΠΎΠΌ Π΄Π°Π½Π½ΡΡ .
- Π‘Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π½ΠΎΠ²ΡΠΉ ΠΈΡΠΊΡΡΡΡΠ²Π΅Π½Π½ΡΠΉ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ .
- Π‘ΠΎΠ·Π΄Π°ΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
Π²ΡΡΡΠ½ΡΡ ΠΏΡΡΠ΅ΠΌ ΡΠΎΡΠΎΠ³ΡΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΠ΅Π°Π»ΡΠ½ΡΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ ΠΈ
https://
ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ ΠΈ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΉ Π°Π½Π½ΠΎΡΠ°ΡΠΈΠ΅ΠΉ (ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΠΏΠΎΠ·ΠΈΡΠΈΠΉ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²) ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π²ΡΡΡΠ½ΡΡ.
ΠΠ°ΡΠΈΠ°Π½Ρ β1: ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΡ Π½Π°Π±ΠΎΡΠΎΠ² Π΄Π°Π½Π½ΡΡ
ΠΡΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΎΡΡΡΠΏΠ½ΡΡ Π½Π°Π±ΠΎΡΠΎΠ² Π΄Π°Π½Π½ΡΡ . ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌΠΈ ΡΠ΅ΡΡΡΡΠ°ΠΌΠΈ Π΄Π»Ρ ΠΏΠΎΠΈΡΠΊΠ° ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠ΅Π³ΠΎ Π½Π°Π±ΠΎΡΠ°:
- Google Dataset Search
- Kaggle Datasets
- ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ awesome-public-datasets
- ΠΈ ΠΏΡ.
π ΠΡΠ»ΠΈ Ρ Π²Π°Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ Π½Π°ΠΉΡΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΠΉ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ Ρ Π»ΠΈΡΠ΅Π½Π·ΠΈΠ΅ΠΉ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠ΅ΠΉ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, ΡΠΎ ΡΡΠΎ, ΠΏΠΎΠΆΠ°Π»ΡΠΉ, Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π±ΡΡΡΡΡΠΉ ΡΠΏΠΎΡΠΎΠ± Π½Π°ΡΠ°ΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
π ΠΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΌΠ½Π΅ Π½Π΅ ΡΠ΄Π°Π»ΠΎΡΡ Π½Π°ΠΉΡΠΈ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ , ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΊΠ½ΠΈΠ³ ΡΠΎ ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ ΠΈ ΠΈΡ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠ°ΠΌΠΈ.
ΠΡΠΎΡ Π²Π°ΡΠΈΠ°Π½Ρ Π½Π°ΠΌ ΠΏΡΠΈΠΉΠ΄Π΅ΡΡΡ ΠΏΡΠΎΠΏΡΡΡΠΈΡΡ.
ΠΠ°ΡΠΈΠ°Π½Ρ β2: ΠΠ΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΡΠΊΡΡΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ
Π‘ΡΡΠ΅ΡΡΠ²ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ keras_ocr), ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ Π½Π°ΠΌ ΠΏΠΎΠΌΠΎΡΡ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ»ΡΡΠ°ΠΉΠ½ΡΠΉ ΡΠ΅ΠΊΡΡ, ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ Π² Π½Π΅Π³ΠΎ ΡΡΡΠ»ΠΊΡ ΠΈ ΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ΅ΠΊΡΡ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΠΎΠ½Π°Ρ ΠΈ Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌΠΈ ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ.
π ΠΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²ΠΎ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΎΠ½ Π΄Π°Π΅Ρ Π½Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ Π΄Π°Π½Π½ΡΡ Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΡΡΠΈΡΡΠ°ΠΌΠΈ, Π»ΠΈΠ³Π°ΡΡΡΠ°ΠΌΠΈ, ΡΠ²Π΅ΡΠ°ΠΌΠΈ ΡΠ΅ΠΊΡΡΠ° ΠΈ ΡΠΎΠ½Π°. ΠΡΠΎ ΠΏΠΎΠΌΠΎΠ³Π»ΠΎ Π±Ρ Π½Π°ΠΌ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΏΠ΅ΡΠ΅ΡΡΠ΅Π½Π½ΠΎΡΡΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ. ΠΠΎΠ΄Π΅Π»Ρ ΠΌΠΎΠ³Π»Π°-Π±Ρ Π»Π΅Π³ΠΊΠΎ ΠΎΠ±ΠΎΠ±ΡΠ°ΡΡ ΡΠ²ΠΎΠΈ "Π·Π½Π°Π½ΠΈΡ" Π² ΡΠ»ΡΡΠ°Π΅ Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠ½Π° Π½Π΅ Π²ΠΈΠ΄Π΅Π»Π° ΡΠ°Π½Π΅Π΅.
π ΠΡΠΎΡ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ Π΄Π°Π΅Ρ Π½Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°Π·Π½ΡΠ΅ ΡΠΈΠΏΡ ΡΡΡΠ»ΠΎΠΊ, ΡΠ°ΠΊΠΈΡ
ΠΊΠ°ΠΊ: http://
, http://
, ftp://
, tcp://
ΠΈ ΠΏΡ. ΠΠ΅Π΄Ρ Π½Π°ΠΉΡΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠ΅Π°Π»ΡΠ½ΡΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ ΡΡΡΠ»ΠΎΠΊ ΠΌΠΎΠ³Π»ΠΎ Π±Ρ ΡΡΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ.
π ΠΡΠ΅ ΠΎΠ΄Π½ΠΈΠΌ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²ΠΎΠΌ ΡΡΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΠΊΠΎΠ»ΡΠΊΠΎ Ρ ΠΎΡΠΈΠΌ. ΠΡ Π½Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Ρ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎΠΌ ΡΡΡΠ°Π½ΠΈΡ ΡΠΎ ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ Π² ΠΊΠ½ΠΈΠ³Π΅, ΠΊΠΎΡΠΎΡΡΡ Π½Π°ΠΌ ΡΠ΄Π°Π»ΠΎΡΡ Π½Π°ΠΉΡΠΈ. Π£Π²Π΅Π»ΠΈΡΠ΅Π½ΠΈΠ΅ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π² ΠΈΡΠΎΠ³Π΅ ΡΠ»ΡΡΡΠΈΡΡ ΡΠΎΡΠ½ΠΎΡΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
π Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΊΠΎΠ³ΠΎ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡΠ°, ΡΡΠΎ Π² ΠΈΡΠΎΠ³Π΅ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΠΊ Π½Π°Π±ΠΎΡΡ
Π΄Π°Π½Π½ΡΡ
, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ ΠΎΡ ΡΠ΅Π°Π»ΡΠ½ΡΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΠΈΠ±ΠΎΡΠ½ΠΎ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π½Π΅ΠΏΡΠ°Π²Π΄ΠΎΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΠΈΠ·Π³ΠΈΠ±Ρ ΡΡΡΠ°Π½ΠΈΡ (Π²ΠΎΠ»Π½Π° Π²ΠΌΠ΅ΡΡΠΎ Π΄ΡΠ³ΠΈ) ΠΈΠ»ΠΈ Π½Π΅ΠΏΡΠ°Π²Π΄ΠΎΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΡΠΎΠ½Ρ. ΠΠΎΠ΄Π΅Π»Ρ Π² ΡΠ°ΠΊΠΎΠΌ ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ ΠΎΠ±ΠΎΠ±ΡΠΈΡΡ ΡΠ²ΠΎΠΈ "Π·Π½Π°Π½ΠΈΡ" Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈΠ· ΡΠ΅Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΌΠΈΡΠ°.
ΠΡΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΌΠ½Π΅ ΠΊΠ°ΠΆΠ΅ΡΡΡ ΠΎΡΠ΅Π½Ρ ΠΌΠ½ΠΎΠ³ΠΎΠΎΠ±Π΅ΡΠ°ΡΡΠΈΠΌ. ΠΠ½ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠΌΠΎΡΡ Π½Π°ΠΌ ΠΏΡΠ΅ΠΎΠ΄ΠΎΠ»Π΅ΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠ² ΠΌΠΎΠ΄Π΅Π»ΠΈ (ΠΎ Π½ΠΈΡ ΠΌΡ ΡΠΏΠΎΠΌΡΠ½Π΅ΠΌ Π½ΠΈΠΆΠ΅ Π² ΡΡΠ°ΡΡΠ΅). Π― ΠΏΠΎΠΊΠ° Π΅ΡΠ΅ Π½Π΅ ΠΏΡΠΎΠ±ΠΎΠ²Π°Π» ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΡΡΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄, Π½ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΡΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠΎΠΌ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ.
ΠΠ°ΡΠΈΠ°Π½Ρ β3: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ Π²ΡΡΡΠ½ΡΡ
ΠΠ°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΡΡΠΌΠΎΠ»ΠΈΠ½Π΅ΠΉΠ½ΡΠΉ ΡΠΏΠΎΡΠΎΠ± - ΡΡΠΎ Π²Π·ΡΡΡ ΠΊΠ½ΠΈΠ³Ρ (ΠΈΠ»ΠΈ ΠΊΠ½ΠΈΠ³ΠΈ), ΡΡΠΎΡΠΎΠ³ΡΠ°ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΡΠ°Π½ΠΈΡΠΊΠΈ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ ΠΈ ΠΎΠ±ΠΎΠ·Π½Π°ΡΠΈΡΡ Π»ΠΎΠΊΠ°ΡΠΈΠΈ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠ² https://
Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΠΊΠΈ Π²ΡΡΡΠ½ΡΡ.
Π₯ΠΎΡΠΎΡΠ°Ρ Π½ΠΎΠ²ΠΎΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΡΠΉ Π½Π°ΠΌ Π½ΡΠΆΠ΅Π½, ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π½Π΅Π±ΠΎΠ»ΡΡΠΈΠΌ (ΡΠΎΡΠ½ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ). ΠΡΠΎ ΠΎΠ±ΡΡΠ»ΠΎΠ²Π»Π΅Π½ΠΎ ΡΠ΅ΠΌ, ΡΡΠΎ ΠΌΡ Π½Π΅ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Ρ Π½ΡΠ»Ρ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ "Π΄ΠΎΡΡΠΈΠ²Π°ΡΡ" ΡΠΆΠ΅ ΠΎΠ±ΡΡΠ΅Π½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ (ΡΠΌ. transfer learning ΠΈ few-shot learning).
π Π Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ Π±ΡΠ΄Π΅Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ ΠΏΡΠΈΠ±Π»ΠΈΠΆΠ΅Π½ ΠΊ ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌΡ ΠΌΠΈΡΡ. ΠΡ Π² Π±ΡΠΊΠ²Π°Π»ΡΠ½ΠΎΠΌ ΡΠΌΡΡΠ»Π΅ Π²ΠΎΠ·ΡΠΌΠ΅ΠΌ ΠΊΠ½ΠΈΠ³Ρ, ΡΡΠΎΡΠΎΠ³ΡΠ°ΡΠΈΡΡΠ΅ΠΌ ΡΡΡΠ°Π½ΠΈΡΠΊΠΈ Ρ ΡΠ΅Π°Π»ΡΠ½ΡΠΌΠΈ ΡΡΠΈΡΡΠ°ΠΌΠΈ, ΠΈΠ·Π³ΠΈΠ±Π°ΠΌΠΈ, ΡΠ΅Π½ΡΠΌΠΈ ΠΈ ΡΠ²Π΅ΡΠ°ΠΌΠΈ.
π Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, Π΄Π°ΠΆΠ΅ Ρ ΡΡΠ΅ΡΠΎΠΌ ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π½Π°ΠΌ Π½ΡΠΆΠ½Ρ Π²ΡΠ΅Π³ΠΎ ΡΠΎΡΠ½ΠΈ ΡΡΡΠ°Π½ΠΈΡΠ΅ΠΊ, ΡΠ°Π±ΠΎΡΠ° ΠΏΠΎ ΡΠ±ΠΎΡΡ ΡΠ°ΠΊΠΈΡ ΡΡΡΠ°Π½ΠΈΡΠ΅ΠΊ ΠΈ ΠΈΡ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΉ Π°Π½Π½ΠΎΡΠ°ΡΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π½ΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ.
π Π’ΡΠΆΠ΅Π»ΠΎ Π½Π°ΠΉΡΠΈ ΡΠ°Π·Π½ΡΠ΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΈ ΠΆΡΡΠ½Π°Π»Ρ Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΡΡΠΈΡΡΠ°ΠΌΠΈ, ΡΠΈΠΏΠ°ΠΌΠΈ ΡΡΡΠ»ΠΎΠΊ, Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΡΠΎΠ½Π°ΠΌΠΈ ΠΈ Π»ΠΈΠ³Π°ΡΡΡΠ°ΠΌΠΈ. Π ΠΈΡΠΎΠ³Π΅ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΠ·ΠΊΠΎΠ½Π°ΠΏΡΠ°Π²Π»Π΅Π½Π½ΡΠΌ (Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΠ΄ΡΡ Π±ΡΡΡ ΠΊΠ½ΠΈΠ³ΠΈ ΡΠΎ ΡΡΠΈΡΡΠ°ΠΌΠΈ ΠΈ ΡΠΎΠ½Π°ΠΌΠΈ ΠΏΠΎΡ ΠΎΠΆΠΈΠΌΠΈ Π½Π° Π²Π°ΡΠΈ).
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ΅Π»ΡΡ ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ, ΠΊΠ°ΠΊ Π±ΡΠ»ΠΎ ΡΠΏΠΎΠΌΡΠ½ΡΡΠΎ Π²ΡΡΠ΅, Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΡΠΈΠ³ΡΠ°ΡΡ ΡΠΎΡΠ΅Π²Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΉΡΠΈ ΠΏΠΎ ΠΏΡΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²ΡΡΡΠ½ΡΡ.
ΠΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ ΡΠΎΡΠΎ Π΄Π»Ρ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ
Π― ΡΡΠΎΡΠΎΠ³ΡΠ°ΡΠΈΡΠΎΠ²Π°Π» 125
ΡΡΡΠ°Π½ΠΈΡΠ΅ΠΊ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠ½ΠΈΠ³ΠΈ, Π² ΠΊΠΎΡΠΎΡΡΡ
Π½Π°ΡΠ΅Π» https://
ΡΡΡΠ»ΠΊΠΈ.
ΠΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π±ΡΠ»ΠΈ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Ρ Π² ΠΏΠ°ΠΏΠΊΡ dataset/printed_links/raw
.
Π‘Π»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠ°Π³ - ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ:
- ΠΠ·ΠΌΠ΅Π½ΠΈΠΌ ΡΠ°Π·ΠΌΠ΅Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΈΡ
ΡΠΈΡΠΈΠ½Π° ΡΠΎΡΡΠ°Π²ΠΈΠ»Π°
1024px
(ΠΈΠ·Π½Π°ΡΠ°Π»ΡΠ½ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π±ΡΠ»ΠΈ ΡΠ΅ΡΠ΅ΡΡΡΡ Π±ΠΎΠ»ΡΡΠΈΠΌΠΈ Ρ ΡΠΈΡΠΈΠ½ΠΎΠΉ Π²3024px
) - ΠΠ±ΡΠ΅ΠΆΠ΅ΠΌ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΎ ΡΡΠ°Π»ΠΎ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΠΌ (ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ Π½Π΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΡΠΆΠ°ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΡ
ΠΏΡΠΎΠΏΠΎΡΡΠΈΠΉ, Π½Π΅ ΠΎΠ±ΡΠ΅Π·Π°Ρ Π΅Π³ΠΎ, Π½ΠΎ Ρ Ρ
ΠΎΡΠ΅Π» ΡΠΎΡ
ΡΠ°Π½ΠΈΡΡ Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΡΠΎΠΏΠΎΡΡΠΈΠΈ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠ²
https:
ΠΏΠ΅ΡΠ΅Π΄ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ΠΌ). - Π Π°Π·Π²Π΅ΡΠ½Π΅ΠΌ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π΄ΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠΉ ΠΎΡΠΈΠ΅Π½ΡΠ°ΡΠΈΠΈ, ΠΏΡΠΈΠΌΠ΅Π½ΠΈΠ² ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ· ΡΠ΅Π³Π° exif.
- Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ΡΠ½ΠΎ-Π±Π΅Π»ΡΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π½Π΅ Ρ ΠΎΡΠΈΠΌ, ΡΡΠΎΠ±Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π±ΡΠ°Π»Π° Π²ΠΎ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΠ²Π΅Ρ.
- Π£Π²Π΅Π»ΠΈΡΠΈΠΌ ΡΡΠΊΠΎΡΡΡ
- Π£Π²Π΅Π»ΠΈΡΠΈΠΌ ΠΊΠΎΠ½ΡΡΠ°ΡΡ
- Π£Π²Π΅Π»ΠΈΡΠΈΠΌ ΡΠ΅Π·ΠΊΠΎΡΡΡ
Π‘ΡΠΎΠΈΡΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ, ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΠ΄Π΅ΠΌ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΡΡΠΈ ΠΆΠ΅ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΠΈ Π½Π°Π΄ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ ΠΏΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ ΠΈΡ Π½Π° Π²Ρ ΠΎΠ΄ Π½Π°ΡΠ΅ΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ (Π΅ΡΠ»ΠΈ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π±ΡΠ»ΠΈ ΡΠ΅ΡΠ½ΠΎ-Π±Π΅Π»ΡΠΌΠΈ ΠΈ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΠΌΠΈ, ΡΠΎ ΠΈ ΡΠ΅Π°Π»ΡΠ½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ Π² Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΡΠ°ΠΊΠΈΠΌΠΈ ΠΆΠ΅ ΠΊΠ²Π°Π΄ΡΠ°ΡΠ½ΡΠΌΠΈ ΠΈ ΡΠ΅ΡΠ½ΠΎ-Π±Π΅Π»ΡΠΌΠΈ).
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π²ΡΠ΅ Π²ΡΡΠ΅ΠΎΠΏΠΈΡΠ°Π½Π½ΡΠ΅ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Python:
import os
import math
import shutil
from pathlib import Path
from PIL import Image, ImageOps, ImageEnhance
# Resize an image.
def preprocess_resize(target_width):
def preprocess(image: Image.Image, log) -> Image.Image:
(width, height) = image.size
ratio = width / height
if width > target_width:
target_height = math.floor(target_width / ratio)
log(f'Resizing: To size {target_width}x{target_height}')
image = image.resize((target_width, target_height))
else:
log('Resizing: Image already resized, skipping...')
return image
return preprocess
# Crop an image.
def preprocess_crop_square():
def preprocess(image: Image.Image, log) -> Image.Image:
(width, height) = image.size
left = 0
top = 0
right = width
bottom = height
crop_size = min(width, height)
if width >= height:
# Horizontal image.
log(f'Squre cropping: Horizontal {crop_size}x{crop_size}')
left = width // 2 - crop_size // 2
right = left + crop_size
else:
# Vetyical image.
log(f'Squre cropping: Vertical {crop_size}x{crop_size}')
top = height // 2 - crop_size // 2
bottom = top + crop_size
image = image.crop((left, top, right, bottom))
return image
return preprocess
# Apply exif transpose to an image.
def preprocess_exif_transpose():
# @see: https://pillow.readthedocs.io/en/stable/reference/ImageOps.html
def preprocess(image: Image.Image, log) -> Image.Image:
log('EXif transpose')
image = ImageOps.exif_transpose(image)
return image
return preprocess
# Apply color transformations to the image.
def preprocess_color(brightness, contrast, color, sharpness):
# @see: https://pillow.readthedocs.io/en/3.0.x/reference/ImageEnhance.html
def preprocess(image: Image.Image, log) -> Image.Image:
log('Coloring')
enhancer = ImageEnhance.Color(image)
image = enhancer.enhance(color)
enhancer = ImageEnhance.Brightness(image)
image = enhancer.enhance(brightness)
enhancer = ImageEnhance.Contrast(image)
image = enhancer.enhance(contrast)
enhancer = ImageEnhance.Sharpness(image)
image = enhancer.enhance(sharpness)
return image
return preprocess
# Image pre-processing pipeline.
def preprocess_pipeline(src_dir, dest_dir, preprocessors=[], files_num_limit=0, override=False):
# Create destination folder if not exists.
Path(dest_dir).mkdir(parents=False, exist_ok=True)
# Get the list of files to be copied.
src_file_names = os.listdir(src_dir)
files_total = files_num_limit if files_num_limit > 0 else len(src_file_names)
files_processed = 0
# Logger function.
def preprocessor_log(message):
print(' ' + message)
# Iterate through files.
for src_file_index, src_file_name in enumerate(src_file_names):
if files_num_limit > 0 and src_file_index >= files_num_limit:
break
# Copy file.
src_file_path = os.path.join(src_dir, src_file_name)
dest_file_path = os.path.join(dest_dir, src_file_name)
progress = math.floor(100 * (src_file_index + 1) / files_total)
print(f'Image {src_file_index + 1}/{files_total} | {progress}% | {src_file_path}')
if not os.path.isfile(src_file_path):
preprocessor_log('Source is not a file, skipping...\n')
continue
if not override and os.path.exists(dest_file_path):
preprocessor_log('File already exists, skipping...\n')
continue
shutil.copy(src_file_path, dest_file_path)
files_processed += 1
# Preprocess file.
image = Image.open(dest_file_path)
for preprocessor in preprocessors:
image = preprocessor(image, preprocessor_log)
image.save(dest_file_path, quality=95)
print('')
print(f'{files_processed} out of {files_total} files have been processed')
# Launching the image preprocessing pipeline.
preprocess_pipeline(
src_dir='dataset/printed_links/raw',
dest_dir='dataset/printed_links/processed',
override=True,
# files_num_limit=1,
preprocessors=[
preprocess_exif_transpose(),
preprocess_resize(target_width=1024),
preprocess_crop_square(),
preprocess_color(brightness=2, contrast=1.3, color=0, sharpness=1),
]
)
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π²ΡΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π±ΡΠ΄ΡΡ ΡΠΎΡ
ΡΠ°Π½Π΅Π½Ρ Π² ΠΏΠ°ΠΏΠΊΠ΅ dataset/printed_links/processed
.
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΎΡΠΌΠΎΡΡΠ΅ΡΡ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import matplotlib.pyplot as plt
import numpy as np
def preview_images(images_dir, images_num=1, figsize=(15, 15)):
image_names = os.listdir(images_dir)
image_names = image_names[:images_num]
num_cells = math.ceil(math.sqrt(images_num))
figure = plt.figure(figsize=figsize)
for image_index, image_name in enumerate(image_names):
image_path = os.path.join(images_dir, image_name)
image = Image.open(image_path)
figure.add_subplot(num_cells, num_cells, image_index + 1)
plt.imshow(np.asarray(image))
plt.show()
preview_images('dataset/printed_links/processed', images_num=4, figsize=(16, 16))
Π£ΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΠΈ Π³Π°Π±Π°ΡΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠΊΠ°Π·Π°ΡΡ ΠΏΠΎΠ·ΠΈΡΠΈΠΈ ΠΈ Π³Π°Π±Π°ΡΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² (ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠ² https://
) Π² Π½Π°ΡΠ΅ΠΌ Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ
ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΎΠΉ Π°Π½Π½ΠΎΡΠ°ΡΠΈΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ LabelImg.
ΠΠ°ΠΌ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ LabelImg Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ Π½Π° Π²Π°Ρ ΠΊΠΎΠΌΠΏΡΡΡΠ΅Ρ. ΠΠ΅ΡΠ°Π»ΡΠ½ΡΡ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡ ΠΏΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ Π²Ρ ΡΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΉΡΠΈ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ LabelImg
ΠΠΎΡΠ»Π΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ LabelImg, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈΠ· ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ, ΡΠΊΠ°Π·Π°Π² ΠΏΠ°ΠΏΠΊΡ Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ (Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ dataset/printed_links/processed
), ΠΊΠΎΡΠΎΡΡΡ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ Π°Π½Π½ΠΎΡΠΈΡΠΎΠ²Π°ΡΡ:
labelImg dataset/printed_links/processed
Π ΠΎΡΠΊΡΡΠ²ΡΠ΅ΠΌΡΡ ΠΎΠΊΠ½Π΅ Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π°Π½Π½ΠΎΡΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ dataset/printed_links/processed
ΠΈ ΡΠΎΡ
ΡΠ°Π½ΠΈΡΡ Π²ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ XML Π² ΠΏΠ°ΠΏΠΊΡ dataset/printed_links/labels/xml/
.
ΠΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠ° Π°Π½Π½ΠΎΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ XML ΡΠ°ΠΉΠ» Ρ ΠΏΠΎΠ·ΠΈΡΠΈΠ΅ΠΉ ΠΈ Π³Π°Π±Π°ΡΠΈΡΠ°ΠΌΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°:
Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΎΠ±ΡΠΈΠΉ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ Π½Π° ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΡΠΉ ΠΈ ΡΠ΅ΡΡΠΎΠ²ΡΠΉ Π½Π°Π±ΠΎΡΡ
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΏΠ΅ΡΠ΅ΡΡΠΈΠ²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ Π½Π΅Π΄ΠΎΡΡΠΈΠ²Π°Π½ΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ°Π·Π±ΠΈΡΡ Π½Π°Ρ ΠΎΠ±ΡΠΈΠΉ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
Π½Π° ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΡΠΉ ΠΈ ΡΠ΅ΡΡΠΎΠ²ΡΠΉ Π½Π°Π±ΠΎΡΡ. ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ 80%
Π²ΡΠ΅Ρ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ ΠΈ 20%
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π΄Π»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ. ΠΠ°Π΄Π°ΡΠ° ΡΠ΅ΡΡΠΎΠ²ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡΠ° - ΠΏΠΎΠ½ΡΡΡ Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ Π½Π°ΡΠ° ΠΌΠΎΠ΄Π΅Π»Ρ ΠΌΠΎΠΆΠ΅Ρ ΠΎΠ±ΠΎΠ±ΡΠΈΡΡ ΡΠ²ΠΎΠΈ "Π·Π½Π°Π½ΠΈΡ" Π½Π° Π΄Π°Π½Π½ΡΡ
, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠ½Π° Π½Π΅ "Π²ΠΈΠ΄Π΅Π»Π°" ΡΠ°Π½ΡΡΠ΅.
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΠ°Π·Π±ΠΈΠ²Π°ΡΡ ΡΠ°ΠΉΠ»Ρ ΠΏΡΡΠ΅ΠΌ ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠΈΠ²Π°Π½ΠΈΡ ΠΈ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² ΡΠ°Π·Π½ΡΠ΅ ΠΏΠ°ΠΏΠΊΠΈ (Π² ΠΏΠ°ΠΏΠΊΠΈ
test
ΠΈtrain
). Π‘ΡΠΎΠΈΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ ΡΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΌ. ΠΠΌΠ΅ΡΡΠΎ ΡΠΈΠ·ΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ² Π² ΡΠ°Π·Π½ΡΡ ΠΏΠ°ΠΏΠΊΠ°Ρ ΠΌΡ ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ°Π·Π±ΠΈΠ²Π°ΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ Π½Π° ΠΏΠΎΠ΄Π³ΡΡΠΏΠΏΡ Π½Π° Π»Π΅ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ tf.data.Dataset.
import re
import random
def partition_dataset(
images_dir,
xml_labels_dir,
train_dir,
test_dir,
val_dir,
train_ratio,
test_ratio,
val_ratio,
copy_xml
):
if not os.path.exists(train_dir):
os.makedirs(train_dir)
if not os.path.exists(test_dir):
os.makedirs(test_dir)
if not os.path.exists(val_dir):
os.makedirs(val_dir)
images = [f for f in os.listdir(images_dir)
if re.search(r'([a-zA-Z0-9\s_\\.\-\(\):])+(.jpg|.jpeg|.png)$', f, re.IGNORECASE)]
num_images = len(images)
num_train_images = math.ceil(train_ratio * num_images)
num_test_images = math.ceil(test_ratio * num_images)
num_val_images = math.ceil(val_ratio * num_images)
print('Intended split')
print(f' train: {num_train_images}/{num_images} images')
print(f' test: {num_test_images}/{num_images} images')
print(f' val: {num_val_images}/{num_images} images')
actual_num_train_images = 0
actual_num_test_images = 0
actual_num_val_images = 0
def copy_random_images(num_images, dest_dir):
copied_num = 0
if not num_images:
return copied_num
for i in range(num_images):
if not len(images):
break
idx = random.randint(0, len(images)-1)
filename = images[idx]
shutil.copyfile(os.path.join(images_dir, filename), os.path.join(dest_dir, filename))
if copy_xml:
xml_filename = os.path.splitext(filename)[0]+'.xml'
shutil.copyfile(os.path.join(xml_labels_dir, xml_filename), os.path.join(dest_dir, xml_filename))
images.remove(images[idx])
copied_num += 1
return copied_num
actual_num_train_images = copy_random_images(num_train_images, train_dir)
actual_num_test_images = copy_random_images(num_test_images, test_dir)
actual_num_val_images = copy_random_images(num_val_images, val_dir)
print('\n', 'Actual split')
print(f' train: {actual_num_train_images}/{num_images} images')
print(f' test: {actual_num_test_images}/{num_images} images')
print(f' val: {actual_num_val_images}/{num_images} images')
partition_dataset(
images_dir='dataset/printed_links/processed',
train_dir='dataset/printed_links/partitioned/train',
test_dir='dataset/printed_links/partitioned/test',
val_dir='dataset/printed_links/partitioned/val',
xml_labels_dir='dataset/printed_links/labels/xml',
train_ratio=0.8,
test_ratio=0.2,
val_ratio=0,
copy_xml=True
)
ΠΠΎΡΠ»Π΅ ΡΠ°Π·Π±ΠΈΡΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ ΡΡΡΡΠΊΡΡΡΠ° ΠΏΠ°ΠΏΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ°ΠΊ:
dataset/
βββ printed_links
βββ labels
β βββ xml
βββ partitioned
β βββ test
β βββ train
β βββ IMG_9140.JPG
β βββ IMG_9140.xml
β βββ IMG_9141.JPG
β βββ IMG_9141.xml
β ...
βββ processed
βββ raw
ΠΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
ΠΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΠ΅ΠΉ Π½Π°Π΄ Π΄Π°Π½Π½ΡΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΡ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ, Π±ΡΠ΄Π΅Ρ ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ Π΄Π°Π½Π½ΡΡ
Π² ΡΠΎΡΠΌΠ°Ρ TFRecord. Π€ΠΎΡΠΌΠ°Ρ TFRecord
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ TensorFlow Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ Π·Π°ΠΏΠΈΡΠ΅ΠΉ (Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ).
Π‘Π½Π°ΡΠ°Π»Π° ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π΄Π²Π΅ ΠΏΠ°ΠΏΠΊΠΈ: ΠΎΠ΄Π½Ρ Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ Π°Π½Π½ΠΎΡΠ°ΡΠΈΠΉ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ CSV
, Π΄ΡΡΠ³ΡΡ Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ Π½Π°ΡΠ΅ΠΉ ΡΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ
Π² ΡΠΎΡΠΌΠ°ΡΠ΅ TFRecord
.
mkdir -p dataset/printed_links/labels/csv
mkdir -p dataset/printed_links/tfrecords
Π’Π΅ΠΏΠ΅ΡΡ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ°ΠΉΠ»-ΠΏΡΠΎΡΠΎΡΠΈΠΏ dataset/printed_links/labels/label_map.pbtxt
Ρ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π°ΡΠ° ΠΌΠΎΠ΄Π΅Π»Ρ Π΄ΠΎΠ»ΠΆΠ½Π° Π½Π°ΡΡΠΈΡΡΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΡ. Π Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Π²ΡΠ΅Π³ΠΎ ΠΎΠ΄ΠΈΠ½ ΠΊΠ»Π°ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ Π½Π°Π·ΠΎΠ²Π΅ΠΌ http
. Π‘ΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΡΠ°ΠΉΠ»Π° Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ:
item {
id: 1
name: 'http'
}
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ Π³ΠΎΡΠΎΠ²Ρ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ
Π² ΡΠΎΡΠΌΠ°Ρ TFRecord ΠΈΠ· Π½Π°Π±ΠΎΡΠ° jpg
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΈ Π°Π½Π½ΠΎΡΠ°ΡΠΈΠΉ Π² xml
ΡΠΎΡΠΌΠ°ΡΠ΅:
import os
import io
import math
import glob
import tensorflow as tf
import pandas as pd
import xml.etree.ElementTree as ET
from PIL import Image
from collections import namedtuple
from object_detection.utils import dataset_util, label_map_util
tf1 = tf.compat.v1
# Convers labels from XML format to CSV.
def xml_to_csv(path):
xml_list = []
for xml_file in glob.glob(path + '/*.xml'):
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
return xml_df
def class_text_to_int(row_label, label_map_dict):
return label_map_dict[row_label]
def split(df, group):
data = namedtuple('data', ['filename', 'object'])
gb = df.groupby(group)
return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]
# Creates a TFRecord.
def create_tf_example(group, path, label_map_dict):
with tf1.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
encoded_jpg = fid.read()
encoded_jpg_io = io.BytesIO(encoded_jpg)
image = Image.open(encoded_jpg_io)
width, height = image.size
filename = group.filename.encode('utf8')
image_format = b'jpg'
xmins = []
xmaxs = []
ymins = []
ymaxs = []
classes_text = []
classes = []
for index, row in group.object.iterrows():
xmins.append(row['xmin'] / width)
xmaxs.append(row['xmax'] / width)
ymins.append(row['ymin'] / height)
ymaxs.append(row['ymax'] / height)
classes_text.append(row['class'].encode('utf8'))
classes.append(class_text_to_int(row['class'], label_map_dict))
tf_example = tf1.train.Example(features=tf1.train.Features(feature={
'image/height': dataset_util.int64_feature(height),
'image/width': dataset_util.int64_feature(width),
'image/filename': dataset_util.bytes_feature(filename),
'image/source_id': dataset_util.bytes_feature(filename),
'image/encoded': dataset_util.bytes_feature(encoded_jpg),
'image/format': dataset_util.bytes_feature(image_format),
'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
'image/object/class/label': dataset_util.int64_list_feature(classes),
}))
return tf_example
def dataset_to_tfrecord(
images_dir,
xmls_dir,
label_map_path,
output_path,
csv_path=None
):
label_map = label_map_util.load_labelmap(label_map_path)
label_map_dict = label_map_util.get_label_map_dict(label_map)
tfrecord_writer = tf1.python_io.TFRecordWriter(output_path)
images_path = os.path.join(images_dir)
csv_examples = xml_to_csv(xmls_dir)
grouped_examples = split(csv_examples, 'filename')
for group in grouped_examples:
tf_example = create_tf_example(group, images_path, label_map_dict)
tfrecord_writer.write(tf_example.SerializeToString())
tfrecord_writer.close()
print('Successfully created the TFRecord file: {}'.format(output_path))
if csv_path is not None:
csv_examples.to_csv(csv_path, index=None)
print('Successfully created the CSV file: {}'.format(csv_path))
# Generate a TFRecord for train dataset.
dataset_to_tfrecord(
images_dir='dataset/printed_links/partitioned/train',
xmls_dir='dataset/printed_links/partitioned/train',
label_map_path='dataset/printed_links/labels/label_map.pbtxt',
output_path='dataset/printed_links/tfrecords/train.record',
csv_path='dataset/printed_links/labels/csv/train.csv'
)
# Generate a TFRecord for test dataset.
dataset_to_tfrecord(
images_dir='dataset/printed_links/partitioned/test',
xmls_dir='dataset/printed_links/partitioned/test',
label_map_path='dataset/printed_links/labels/label_map.pbtxt',
output_path='dataset/printed_links/tfrecords/test.record',
csv_path='dataset/printed_links/labels/csv/test.csv'
)
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ°ΠΉΠ»Ρ test.record
ΠΈ train.record
Π² ΠΏΠ°ΠΏΠΊΠ΅ dataset/printed_links/tfrecords/
:
dataset/
βββ printed_links
βββ labels
β βββ csv
β βββ label_map.pbtxt
β βββ xml
βββ partitioned
β βββ test
β βββ train
β βββ val
βββ processed
βββ raw
βββ tfrecords
βββ test.record
βββ train.record
ΠΡΠΈ Π΄Π²Π° ΡΠ°ΠΉΠ»Π° test.record
ΠΈ train.record
ΡΠ²Π»ΡΡΡΡΡ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ Π½Π°ΡΠ΅Π³ΠΎ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ
, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
.
π Π Π°Π±ΠΎΡΠ°Π΅ΠΌ Ρ Π½Π°Π±ΠΎΡΠΎΠΌ Π΄Π°Π½Π½ΡΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ TFRecord
Π ΡΡΠΎΠΌ ΡΠ°Π·Π΄Π΅Π»Π΅ ΠΌΡ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π΄Π»Ρ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΡ Π½Π°Π±ΠΎΡΠΎΠ² Π΄Π°Π½Π½ΡΡ
Π² ΡΠΎΡΠΌΠ°ΡΠ΅ TFRecord
ΠΈΠΌΠ΅ΡΡΡΡ Π² TensorFlow 2 Object Detection API.
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² Π² Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ
ΠΠΎΡΡΠΈΡΠ°ΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import tensorflow as tf
# Count the number of examples in the dataset.
def count_tfrecords(tfrecords_filename):
raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)
# Keep in mind that the list() operation might be
# a performance bottleneck for large datasets.
return len(list(raw_dataset))
TRAIN_RECORDS_NUM = count_tfrecords('dataset/printed_links/tfrecords/train.record')
TEST_RECORDS_NUM = count_tfrecords('dataset/printed_links/tfrecords/test.record')
print('TRAIN_RECORDS_NUM: ', TRAIN_RECORDS_NUM)
print('TEST_RECORDS_NUM: ', TEST_RECORDS_NUM)
output β
TRAIN_RECORDS_NUM: 100
TEST_RECORDS_NUM: 25
ΠΡΠ°ΠΊ, ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°ΡΡ Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π° 100
ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°Ρ
ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π΅Π΅ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΡ ΠΊ ΠΎΠ±ΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π° 25
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
.
ΠΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΠΌ Π³Π°Π±Π°ΡΠΈΡΡ ΠΈ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
ΠΡΠΎΠ±ΡΠ°Π·ΠΈΡΡ Π³Π°Π±Π°ΡΠΈΡΡ ΠΈ ΠΏΠΎΠ·ΠΈΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import tensorflow as tf
import numpy as np
from google.protobuf import text_format
import matplotlib.pyplot as plt
# Import Object Detection API.
from object_detection.utils import visualization_utils
from object_detection.protos import string_int_label_map_pb2
from object_detection.data_decoders.tf_example_decoder import TfExampleDecoder
%matplotlib inline
# Visualize the TFRecord dataset.
def visualize_tfrecords(tfrecords_filename, label_map=None, print_num=1):
decoder = TfExampleDecoder(
label_map_proto_file=label_map,
use_display_name=False
)
if label_map is not None:
label_map_proto = string_int_label_map_pb2.StringIntLabelMap()
with tf.io.gfile.GFile(label_map,'r') as f:
text_format.Merge(f.read(), label_map_proto)
class_dict = {}
for entry in label_map_proto.item:
class_dict[entry.id] = {'name': entry.name}
raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)
for raw_record in raw_dataset.take(print_num):
example = decoder.decode(raw_record)
image = example['image'].numpy()
boxes = example['groundtruth_boxes'].numpy()
confidences = example['groundtruth_image_confidences']
filename = example['filename']
area = example['groundtruth_area']
classes = example['groundtruth_classes'].numpy()
image_classes = example['groundtruth_image_classes']
weights = example['groundtruth_weights']
scores = np.ones(boxes.shape[0])
visualization_utils.visualize_boxes_and_labels_on_image_array(
image,
boxes,
classes,
scores,
class_dict,
max_boxes_to_draw=None,
use_normalized_coordinates=True
)
plt.figure(figsize=(8, 8))
plt.imshow(image)
plt.show()
# Visualizing the training TFRecord dataset.
visualize_tfrecords(
tfrecords_filename='dataset/printed_links/tfrecords/train.record',
label_map='dataset/printed_links/labels/label_map.pbtxt',
print_num=3
)
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΡΠΌΠΈ Π³Π°Π±Π°ΡΠΈΡΠ°ΠΌΠΈ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²,
π Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ TensorBoard
ΠΠ΅ΡΠ΅Π΄ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ Π½Π°ΡΠ°ΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΡΡΡΠΈΡΡ TensorBoard.
TensorBoard ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π½Π°ΠΌ Π² ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π΅ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°. ΠΠ½ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π½Π°ΠΌ ΡΠ²ΠΈΠ΄Π΅ΡΡ, Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π»ΠΈ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±ΡΡΠ°Π΅ΡΡΡ ΠΈΠ»ΠΈ ΠΆΠ΅ Π½Π°ΠΌ Π»ΡΡΡΠ΅ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΡ ΠΈ ΠΏΠΎΠ΄ΠΏΡΠ°Π²ΠΈΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ. TensorBoard ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π½Π°ΠΌ ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΈ Π³Π΄Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ Π½Π°ΡΠ° ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°Π΅Ρ.
ΠΡΡΠΎΡΠ½ΠΈΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ: Π΄ΠΎΠΌΠ°ΡΠ½ΡΡ ΡΡΡΠ°Π½ΠΈΡΠ° TensorBoard
ΠΡΠ»ΠΈΡΠ½ΠΎΠΉ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΡΡ TensorBoard ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΡΡΡΠΈΡΡ Π΅Π³ΠΎ ΠΏΡΡΠΌΠΎ Π² Google Colab. ΠΡΠ»ΠΈ ΠΆΠ΅ Π²Ρ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΡΠ΅ΡΠ΅ Ρ ΠΌΠΎΠ΄Π΅Π»ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ Π² Jupyter Π½ΠΎΡΡΠ±ΡΠΊΠ΅, ΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ TensorBoard ΠΊΠ°ΠΊ Python ΠΏΠ°ΠΊΠ΅Ρ ΠΈ Π·Π°ΠΏΡΡΡΠΈΡΡ Π΅Π³ΠΎ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ ΠΈΠ· ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ.
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠ°ΠΏΠΊΡ ./logs
, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ Π±ΡΠ΄ΡΡ Ρ
ΡΠ°Π½ΠΈΡΡΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
mkdir -p logs
ΠΠ°Π»Π΅Π΅, ΠΌΡ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ TensorBoard Π² Google Colab:
%load_ext tensorboard
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΡΡΡΠΈΡΡ TensorBoard ΠΈ ΡΠΊΠ°Π·Π°ΡΡ ΠΏΠ°ΠΏΠΊΡ ./logs
Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΠΏΠΊΠΈ Ρ Π»ΠΎΠ³Π°ΠΌΠΈ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ,
%tensorboard --logdir ./logs
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΠΏΡΡΡΡΡ ΠΏΠ°Π½Π΅Π»Ρ TensorBoard:
ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΌΡ Π½Π°ΡΠ½Π΅ΠΌ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΡ, ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ Π²Π΅ΡΠ½ΡΡΡΡΡ ΠΊ ΡΡΠΎΠΉ ΠΏΠ°Π½Π΅Π»ΠΈ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ Ρ ΠΎΡΠΎΡΠΎ ΠΎΠ½Π° ΠΎΠ±ΡΡΠ°Π΅ΡΡΡ.
ππ»βοΈ Π’ΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ
ΠΠ°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²Π΅ΡΠ½ΡΡΡΡΡ ΠΊ ΡΠ°Π½Π΅Π΅ ΡΠΏΠΎΠΌΡΠ½ΡΡΠΎΠΌΡ ΡΠ°ΠΉΠ»Ρ cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/pipeline.config
. Π ΡΡΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ ΡΠΎΠ±ΡΠ°Π½Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
.
ΠΠ°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΉΠ» pipeline.config
Π² ΠΊΠΎΡΠ΅Π½Ρ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ:
- ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠ»Π°ΡΡΠΎΠ² Ρ
90
(ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠ»Π°ΡΡΠΎΠ² Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ COCO) Π½Π°1
(Π½Π°Ρ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡhttp
) - ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΌΠ΅Π½ΡΡΠΈΡΡ ΡΠ°Π·ΠΌΠ΅Ρ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅ΡΠ° (batch size) Π΄ΠΎ
8
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π½Π° ΠΎΠ΄ΠΈΠ½ ΠΏΠ°ΠΊΠ΅Ρ, ΡΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠΌ ΠΏΠ°ΠΌΡΡΠΈ. - ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π½Π°ΡΠ΅ΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π³Π΄Π΅ Ρ ΡΠ°Π½ΡΡΡΡ ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΡΠ΅ ΡΠ»Π΅ΠΏΠΊΠΈ ΡΠ°Π½Π΅Π΅ Π½Π°ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π½Π΅ Ρ ΠΎΡΠΈΠΌ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°ΡΡ Π΅Π΅ Ρ Π½ΡΠ»Ρ.
- ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ
fine_tune_checkpoint_type
Π²detection
. - ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π³Π΄Π΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΠΊΠ°ΡΡΠ° Π½ΠΎΠ²ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
- ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π³Π΄Π΅ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΡΠΉ ΠΈ ΡΠ΅ΡΡΠΎΠ²ΡΠΉ Π½Π°Π±ΠΎΡΡ Π΄Π°Π½Π½ΡΡ .
ΠΡΠ΅ ΡΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ Π²ΡΡΡΠ½ΡΡ Π² ΡΠ°ΠΉΠ»Π΅ pipeline.config
, Π½ΠΎ ΡΡΠΎ ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎ:
import tensorflow as tf
from shutil import copyfile
from google.protobuf import text_format
from object_detection.protos import pipeline_pb2
# Adjust pipeline config modification here if needed.
def modify_config(pipeline):
# Model config.
pipeline.model.ssd.num_classes = 1
# Train config.
pipeline.train_config.batch_size = 8
pipeline.train_config.fine_tune_checkpoint = 'cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0'
pipeline.train_config.fine_tune_checkpoint_type = 'detection'
# Train input reader config.
pipeline.train_input_reader.label_map_path = 'dataset/printed_links/labels/label_map.pbtxt'
pipeline.train_input_reader.tf_record_input_reader.input_path[0] = 'dataset/printed_links/tfrecords/train.record'
# Eval input reader config.
pipeline.eval_input_reader[0].label_map_path = 'dataset/printed_links/labels/label_map.pbtxt'
pipeline.eval_input_reader[0].tf_record_input_reader.input_path[0] = 'dataset/printed_links/tfrecords/test.record'
return pipeline
def clone_pipeline_config():
copyfile(
'cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/pipeline.config',
'pipeline.config'
)
def setup_pipeline(pipeline_config_path):
clone_pipeline_config()
pipeline = read_pipeline_config(pipeline_config_path)
pipeline = modify_config(pipeline)
write_pipeline_config(pipeline_config_path, pipeline)
return pipeline
def read_pipeline_config(pipeline_config_path):
pipeline = pipeline_pb2.TrainEvalPipelineConfig()
with tf.io.gfile.GFile(pipeline_config_path, "r") as f:
proto_str = f.read()
text_format.Merge(proto_str, pipeline)
return pipeline
def write_pipeline_config(pipeline_config_path, pipeline):
config_text = text_format.MessageToString(pipeline)
with tf.io.gfile.GFile(pipeline_config_path, "wb") as f:
f.write(config_text)
# Adjusting the pipeline configuration.
pipeline = setup_pipeline('pipeline.config')
print(pipeline)
ΠΠΎΡ ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½Π°Ρ Π²Π΅ΡΡΠΈΡ ΡΠ°ΠΉΠ»Π° pipeline.config
ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ:
model {
ssd {
num_classes: 1
image_resizer {
fixed_shape_resizer {
height: 640
width: 640
}
}
feature_extractor {
type: "ssd_mobilenet_v2_fpn_keras"
depth_multiplier: 1.0
min_depth: 16
conv_hyperparams {
regularizer {
l2_regularizer {
weight: 3.9999998989515007e-05
}
}
initializer {
random_normal_initializer {
mean: 0.0
stddev: 0.009999999776482582
}
}
activation: RELU_6
batch_norm {
decay: 0.996999979019165
scale: true
epsilon: 0.0010000000474974513
}
}
use_depthwise: true
override_base_feature_extractor_hyperparams: true
fpn {
min_level: 3
max_level: 7
additional_layer_depth: 128
}
}
box_coder {
faster_rcnn_box_coder {
y_scale: 10.0
x_scale: 10.0
height_scale: 5.0
width_scale: 5.0
}
}
matcher {
argmax_matcher {
matched_threshold: 0.5
unmatched_threshold: 0.5
ignore_thresholds: false
negatives_lower_than_unmatched: true
force_match_for_each_row: true
use_matmul_gather: true
}
}
similarity_calculator {
iou_similarity {
}
}
box_predictor {
weight_shared_convolutional_box_predictor {
conv_hyperparams {
regularizer {
l2_regularizer {
weight: 3.9999998989515007e-05
}
}
initializer {
random_normal_initializer {
mean: 0.0
stddev: 0.009999999776482582
}
}
activation: RELU_6
batch_norm {
decay: 0.996999979019165
scale: true
epsilon: 0.0010000000474974513
}
}
depth: 128
num_layers_before_predictor: 4
kernel_size: 3
class_prediction_bias_init: -4.599999904632568
share_prediction_tower: true
use_depthwise: true
}
}
anchor_generator {
multiscale_anchor_generator {
min_level: 3
max_level: 7
anchor_scale: 4.0
aspect_ratios: 1.0
aspect_ratios: 2.0
aspect_ratios: 0.5
scales_per_octave: 2
}
}
post_processing {
batch_non_max_suppression {
score_threshold: 9.99999993922529e-09
iou_threshold: 0.6000000238418579
max_detections_per_class: 100
max_total_detections: 100
use_static_shapes: false
}
score_converter: SIGMOID
}
normalize_loss_by_num_matches: true
loss {
localization_loss {
weighted_smooth_l1 {
}
}
classification_loss {
weighted_sigmoid_focal {
gamma: 2.0
alpha: 0.25
}
}
classification_weight: 1.0
localization_weight: 1.0
}
encode_background_as_zeros: true
normalize_loc_loss_by_codesize: true
inplace_batchnorm_update: true
freeze_batchnorm: false
}
}
train_config {
batch_size: 8
data_augmentation_options {
random_horizontal_flip {
}
}
data_augmentation_options {
random_crop_image {
min_object_covered: 0.0
min_aspect_ratio: 0.75
max_aspect_ratio: 3.0
min_area: 0.75
max_area: 1.0
overlap_thresh: 0.0
}
}
sync_replicas: true
optimizer {
momentum_optimizer {
learning_rate {
cosine_decay_learning_rate {
learning_rate_base: 0.07999999821186066
total_steps: 50000
warmup_learning_rate: 0.026666000485420227
warmup_steps: 1000
}
}
momentum_optimizer_value: 0.8999999761581421
}
use_moving_average: false
}
fine_tune_checkpoint: "cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/checkpoint/ckpt-0"
num_steps: 50000
startup_delay_steps: 0.0
replicas_to_aggregate: 8
max_number_of_boxes: 100
unpad_groundtruth_tensors: false
fine_tune_checkpoint_type: "detection"
fine_tune_checkpoint_version: V2
}
train_input_reader {
label_map_path: "dataset/printed_links/labels/label_map.pbtxt"
tf_record_input_reader {
input_path: "dataset/printed_links/tfrecords/train.record"
}
}
eval_config {
metrics_set: "coco_detection_metrics"
use_moving_averages: false
}
eval_input_reader {
label_map_path: "dataset/printed_links/labels/label_map.pbtxt"
shuffle: false
num_epochs: 1
tf_record_input_reader {
input_path: "dataset/printed_links/tfrecords/test.record"
}
}
ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΏΡΠΎΡΠ΅ΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ
ΠΡ Π³ΠΎΡΠΎΠ²Ρ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΡΠ΅ΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ TensorFlow 2 Object Detection API. API ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΠ°ΠΉΠ» model_main_tf2.py, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π²ΡΡ Π»ΠΎΠ³ΠΈΠΊΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π΅ΡΠ°Π»ΡΠ½Π΅Π΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Ρ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΌ Python ΠΊΠΎΠ΄ΠΎΠΌ ΡΠ°ΠΉΠ»Π°, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΎΠΏΠΈΡΠ°Π½Ρ Π²Ρ
ΠΎΠ΄Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΠΊΡΠΈΠΏΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, num_train_steps
, model_dir
ΠΈ ΠΏΡ.).
ΠΡ Π±ΡΠ΄Π΅ΠΌ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ 1000
ΠΈΡΠ΅ΡΠ°ΡΠΈΠΉ (ΡΠΏΠΎΡ
).
%%bash
NUM_TRAIN_STEPS=1000
CHECKPOINT_EVERY_N=1000
PIPELINE_CONFIG_PATH=pipeline.config
MODEL_DIR=./logs
SAMPLE_1_OF_N_EVAL_EXAMPLES=1
python ./models/research/object_detection/model_main_tf2.py \
--model_dir=$MODEL_DIR \
--num_train_steps=$NUM_TRAIN_STEPS \
--sample_1_of_n_eval_examples=$SAMPLE_1_OF_N_EVAL_EXAMPLES \
--pipeline_config_path=$PIPELINE_CONFIG_PATH \
--checkpoint_every_n=$CHECKPOINT_EVERY_N \
--alsologtostderr
ΠΠΎ Π²ΡΠ΅ΠΌΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ (ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π½ΡΡΡ ~10
ΠΌΠΈΠ½ΡΡ Π΄Π»Ρ 1000
ΠΈΡΠ΅ΡΠ°ΡΠΈΠΉ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ GPU runtime Π² GoogleColab) Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΠΊΠ°ΠΊ ΠΏΡΠΎΡΠ΅ΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ Π² TensorBoard. ΠΡΠΈΠ±ΠΊΠΈ localization
ΠΈ classification
Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠΌΠ΅Π½ΡΡΠ°ΡΡΡΡ, ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ Π²ΡΠ΅ Π»ΡΡΡΠ΅ ΠΈ Π»ΡΡΡΠ΅ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΡΠ΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΈΡ
ΠΊΠ»Π°ΡΡ.
Π’Π°ΠΊΠΆΠ΅ ΠΏΠΎ ΠΌΠ΅ΡΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π² ΠΏΠ°ΠΏΠΊΠ΅ logs
Π±ΡΠ΄ΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡΡΡ Π½ΠΎΠ²ΡΠ΅ ΡΠ΅ΠΊΠΏΠΎΠΈΠ½ΡΡ (ΡΠ»Π΅ΠΏΠΊΠΈ) ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΌΠΎΠ΄Π΅Π»ΠΈ.
ΠΠ°ΠΏΠΊΠ° logs
ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
logs
βββ checkpoint
βββ ckpt-1.data-00000-of-00001
βββ ckpt-1.index
βββ train
βββ events.out.tfevents.1606560330.b314c371fa10.1747.1628.v2
ΠΡΠ΅Π½ΠΈΠ²Π°Π΅ΠΌ ΠΌΠΎΠ΄Π΅Π»Ρ (ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎ)
Π§ΡΠΎΠ±Ρ ΠΎΡΠ΅Π½ΠΈΡΡ ΡΠΎΡΠ½ΠΎΡΡΡ ΡΠ°Π±ΠΎΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΌΡ ΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈΠ· ΡΠ΅ΡΡΠΎΠ²ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ . Π Π΅Π·ΡΠ»ΡΡΠ°Ρ ΡΠ°ΠΊΠΎΠΉ ΠΎΡΠ΅Π½ΠΊΠΈ ΠΎΠ±ΠΎΠ±ΡΠ°Π΅ΡΡΡ Π² Π²ΠΈΠ΄Π΅ ΠΌΠ΅ΡΡΠΈΠΊ, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°Π±Π»ΡΠ΄Π°ΡΡ Ρ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Ρ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π·Π΄Π΅ΡΡ.
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΠΏΡΠΎΠΏΡΡΡΠΈΠΌ ΡΡΠΎΡ ΡΠ°Π³ Ρ ΠΌΠ΅ΡΡΠΈΠΊΠ°ΠΌΠΈ, Π½ΠΎ ΠΌΡ Π²ΡΠ΅-ΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΏΠ°Π½Π΅Π»ΡΡ TensorBoard, ΡΡΠΎΠ±Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°Π΅Ρ Π½Π° ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ :
%%bash
PIPELINE_CONFIG_PATH=pipeline.config
MODEL_DIR=logs
python ./models/research/object_detection/model_main_tf2.py \
--model_dir=$MODEL_DIR \
--pipeline_config_path=$PIPELINE_CONFIG_PATH \
--checkpoint_dir=$MODEL_DIR \
ΠΠΎΡΠ»Π΅ Π·Π°ΠΏΡΡΠΊΠ° ΡΠΊΡΠΈΠΏΡΠ° Π²Ρ ΡΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π½ΡΠΌΠΈ Π² Π½ΠΈΡ ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠ°ΠΌΠΈ:
π ΠΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌ ΠΌΠΎΠ΄Π΅Π»Ρ
ΠΠΎΡΠ»Π΅ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ. ΠΠ»Ρ ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΌΡ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΡΠΊΡΠΈΠΏΡΠΎΠΌ exporter_main_v2.py ΠΈΠ· Object Detection API. ΠΡΠΎΡ ΡΠΊΡΠΈΠΏΡ ΠΏΠΎΠ΄Π³ΠΎΡΠ°Π²Π»ΠΈΠ²Π°Π΅Ρ TensorFlow Π³ΡΠ°Ρ Π½Π° ΠΎΡΠ½ΠΎΠ²Π°Π½ΠΈΠΈ ΡΠ΅ΠΊΠΏΠΎΠΈΠ½ΡΠΎΠ² ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΈ Π΅Π΅ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ. ΠΠΎΡΠ»Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠΊΡΠΈΠΏΡΠ° ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΏΠ°ΠΏΠΊΡ Ρ ΡΠ΅ΠΊΠΏΠΎΠΈΠ½ΡΠ°ΠΌΠΈ, ΠΌΠΎΠ΄Π΅Π»ΡΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ SavedModel ΠΈ ΠΊΠΎΠΏΠΈΠ΅ΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΌΠΎΠ΄Π΅Π»ΠΈ.
%%bash
python ./models/research/object_detection/exporter_main_v2.py \
--input_type=image_tensor \
--pipeline_config_path=pipeline.config \
--trained_checkpoint_dir=logs \
--output_directory=exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
ΠΠΎΡ ΡΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΏΠ°ΠΏΠΊΠΈ exported
:
exported
βββ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
βββ checkpoint
β βββ checkpoint
β βββ ckpt-0.data-00000-of-00001
β βββ ckpt-0.index
βββ pipeline.config
βββ saved_model
βββ assets
βββ saved_model.pb
βββ variables
βββ variables.data-00000-of-00001
βββ variables.index
ΠΠ° ΡΡΠΎΠΌ ΡΡΠ°ΠΏΠ΅ Ρ Π½Π°Ρ Π΅ΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π² ΠΏΠ°ΠΏΠΊΠ΅ saved_model
, ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ ΡΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
π ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ, ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ Π½Π° ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΌ ΡΡΠ°ΠΏΠ΅.
Π Π½Π°ΡΠ°Π»Π΅ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ-ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΠ΅Π»Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ. ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Π²Ρ ΠΎΠ΄ ΠΈ Π²ΡΠ΄Π°Π²Π°ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ± ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π½ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°Ρ :
import time
import math
PATH_TO_SAVED_MODEL = 'exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/saved_model'
def detection_function_from_saved_model(saved_model_path):
print('Loading saved model...', end='')
start_time = time.time()
# Load saved model and build the detection function
detect_fn = tf.saved_model.load(saved_model_path)
end_time = time.time()
elapsed_time = end_time - start_time
print('Done! Took {} seconds'.format(math.ceil(elapsed_time)))
return detect_fn
exported_detect_fn = detection_function_from_saved_model(
PATH_TO_SAVED_MODEL
)
output β
Loading saved model...Done! Took 9 seconds
ΠΠ»Ρ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ² ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π½ΡΡ ΠΊΠ»Π°ΡΡΠΎΠ² Ρ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ ΠΊΠ»Π°ΡΡΠΎΠ² Π½Π°ΠΌ ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ ΠΊΠ°ΡΡΡ ΠΊΠ»Π°ΡΡΠΎΠ²:
from object_detection.utils import label_map_util
category_index = label_map_util.create_category_index_from_labelmap(
'dataset/printed_links/labels/label_map.pbtxt',
use_display_name=True
)
print(category_index)
output β
{1: {'id': 1, 'name': 'http'}}
Π’Π΅ΡΡΠΈΡΡΠ΅ΠΌ Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π° ΡΠ΅ΡΡΠΎΠ²ΠΎΠΌ Π½Π°Π±ΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ .
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
from object_detection.utils import visualization_utils
from object_detection.data_decoders.tf_example_decoder import TfExampleDecoder
%matplotlib inline
def tensors_from_tfrecord(
tfrecords_filename,
tfrecords_num,
dtype=tf.float32
):
decoder = TfExampleDecoder()
raw_dataset = tf.data.TFRecordDataset(tfrecords_filename)
images = []
for raw_record in raw_dataset.take(tfrecords_num):
example = decoder.decode(raw_record)
image = example['image']
image = tf.cast(image, dtype=dtype)
images.append(image)
return images
def test_detection(tfrecords_filename, tfrecords_num, detect_fn):
image_tensors = tensors_from_tfrecord(
tfrecords_filename,
tfrecords_num,
dtype=tf.uint8
)
for image_tensor in image_tensors:
image_np = image_tensor.numpy()
# The model expects a batch of images, so add an axis with `tf.newaxis`.
input_tensor = tf.expand_dims(image_tensor, 0)
detections = detect_fn(input_tensor)
# All outputs are batches tensors.
# Convert to numpy arrays, and take index [0] to remove the batch dimension.
# We're only interested in the first num_detections.
num_detections = int(detections.pop('num_detections'))
detections = {key: value[0, :num_detections].numpy() for key, value in detections.items()}
detections['num_detections'] = num_detections
# detection_classes should be ints.
detections['detection_classes'] = detections['detection_classes'].astype(np.int64)
image_np_with_detections = image_np.astype(int).copy()
visualization_utils.visualize_boxes_and_labels_on_image_array(
image_np_with_detections,
detections['detection_boxes'],
detections['detection_classes'],
detections['detection_scores'],
category_index,
use_normalized_coordinates=True,
max_boxes_to_draw=100,
min_score_thresh=.3,
agnostic_mode=False
)
plt.figure(figsize=(8, 8))
plt.imshow(image_np_with_detections)
plt.show()
test_detection(
tfrecords_filename='dataset/printed_links/tfrecords/test.record',
tfrecords_num=10,
detect_fn=exported_detect_fn
)
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ 10
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΈΠ· ΡΠ΅ΡΡΠΎΠ²ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ
Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π½ΡΠΌΠΈ ΠΈ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠ΅Π½Π½ΡΠΌΠΈ https:
ΠΏΡΠ΅ΡΠΈΠΊΡΠ°ΠΌΠΈ:
Π’ΠΎΡ ΡΠ°ΠΊΡ, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠΌΠΎΠ³Π»Π° ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ (Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠ΅ΡΠΈΠΊΡΡ https://
) Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠ½Π° ΡΠ°Π½ΡΡΠ΅ Π½Π΅ "Π²ΠΈΠ΄Π΅Π»Π°" ΡΠ²Π»ΡΠ΅ΡΡΡ Ρ
ΠΎΡΠΎΡΠΈΠΌ Π·Π½Π°ΠΊΠΎΠΌ ΠΈ, ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎ, ΡΠ΅ΠΌ, ΡΡΠΎ ΠΌΡ Ρ
ΠΎΡΠ΅Π»ΠΈ Π΄ΠΎΡΡΠΈΠ³Π½ΡΡΡ ΡΡΠΎΠΉ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΎΠΉ.
π ΠΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅ΠΌ ΠΌΠΎΠ΄Π΅Π»Ρ Π² Π²Π΅Π±-ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠΉ ΡΠΎΡΠΌΠ°Ρ
ΠΠ°ΠΊ Π²Ρ ΠΏΠΎΠΌΠ½ΠΈΡΠ΅ ΠΈΠ· Π½Π°ΡΠ°Π»Π° Π΄Π°Π½Π½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ Π½Π°ΡΠ΅ΠΉ ΡΠ΅Π»ΡΡ Π±ΡΠ»Π° ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅. Π ΡΡΠ°ΡΡΡΡ, ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ JavaScript Π²Π΅ΡΡΠΈΡ TensorFlow - TensorFlow.js. Π JavaScript ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΠΎΠΉ ΡΠ°Π½Π΅Π΅ ΠΌΠΎΠ΄Π΅Π»ΡΡ Π½Π°ΠΏΡΡΠΌΡΡ. ΠΠ°ΠΌ Π½ΡΠΆΠ½Π° Π΅ΡΠ΅ ΠΎΠ΄Π½Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π² ΡΠΎΡΠΌΠ°Ρ tfjs_graph_model.
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΡΡΡΠ΅ΡΡΠ²ΠΈΡΡ ΡΡΡ ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ, Π½Π°ΠΌ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Python ΠΏΠ°ΠΊΠ΅Ρ tensorflowjs:
pip install tensorflowjs --quiet
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π² Π½ΡΠΆΠ½ΡΠΉ Π½Π°ΠΌ ΡΠΎΡΠΌΠ°Ρ:
%%bash
tensorflowjs_converter \
--input_format=tf_saved_model \
--output_format=tfjs_graph_model \
exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8/saved_model \
exported_web/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
ΠΠ°ΠΏΠΊΠ° exported_web
ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ .json
ΡΠ°ΠΉΠ» Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ΅ΠΉ ΠΎΠ± Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΉΠ»ΠΎΠ² Π² ΡΠΎΡΠΌΠ°ΡΠ΅ .bin
ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π΅Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ.
exported_web
βββ ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8
βββ group1-shard1of4.bin
βββ group1-shard2of4.bin
βββ group1-shard3of4.bin
βββ group1-shard4of4.bin
βββ model.json
ΠΠ°ΠΊΠΎΠ½Π΅Ρ-ΡΠΎ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ ΠΌΠΎΠ΄Π΅Π»Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΏΠΎΡΠΎΠ±Π½Π° ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡ https://
ΠΏΡΠ΅ΡΠΈΠΊΡΡ Π² ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
ΠΈ ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΎΡ
ΡΠ°Π½Π΅Π½Π° Π² ΡΠΎΡΠΌΠ°ΡΠ΅, ΠΏΠΎΠ½ΡΡΠ½ΠΎΠΌ JavaScript ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌ.
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ ΡΠ°Π·ΠΌΠ΅ΡΡ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΡΠΎΠ·Π΄Π°Π»ΠΈ:
import pathlib
def get_folder_size(folder_path):
mB = 1000000
root_dir = pathlib.Path(folder_path)
sizeBytes = sum(f.stat().st_size for f in root_dir.glob('**/*') if f.is_file())
return f'{sizeBytes//mB} MB'
print(f'Original model size: {get_folder_size("cache/datasets/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8")}')
print(f'Exported model size: {get_folder_size("exported/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8")}')
print(f'Exported WEB model size: {get_folder_size("exported_web/ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8")}')
output β
Original model size: 31 MB
Exported model size: 28 MB
Exported WEB model size: 13 MB
ΠΠ°ΠΊ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, ΠΌΠΎΠ΄Π΅Π»Ρ, ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π²Π΅ΡΠΈΡ 13MB
, ΡΡΠΎ Π²ΠΏΠΎΠ»Π½Π΅ Π΄ΠΎΠΏΡΡΡΠΈΠΌΠΎ ΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡΠΌ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² Π½Π°ΡΠ°Π»Π΅ ΡΡΠ°ΡΡΠΈ.
ΠΠΎΠ·ΠΆΠ΅ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import * as tf from '@tensorflow/tfjs';
const model = await tf.loadGraphModel(modelURL);
π§ Π‘Π»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠ°Π³ΠΎΠΌ Π±ΡΠ΄Π΅Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π΄Π»Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΡΡΠΎ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΠΌΠΎΠΉ Π΄Π»Ρ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠ°ΡΡΠΈ. ΠΠΎ ΡΠΆΠ΅ ΡΠ΅ΠΉΡΠ°Ρ, ΠΏΡΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Ρ ΡΠΈΠ½Π°Π»ΡΠ½ΡΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠΌ ΠΊΠΎΠ΄Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π° TypeScript Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ links-detector Π½Π° GitHub.
π€ ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ Π½Π°ΡΠ°Π»ΠΈ ΡΠ΅ΡΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΏΠ΅ΡΠ°ΡΠ½ΡΡ
ΡΡΡΠ»ΠΎΠΊ. Π ΠΈΡΠΎΠ³Π΅ ΠΌΡ ΠΎΠ±ΡΡΠΈΠ»ΠΈ ΠΌΠΎΠ΄Π΅Π»Ρ, ΡΠΏΠΎΡΠΎΠ±Π½ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΡ ΠΏΡΠ΅ΡΠΈΠΊΡΡ https://
Π² ΡΠ΅ΠΊΡΡΠΎΠ²ΡΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
(Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π² ΠΊΠ°Π΄ΡΠ°Ρ
Π²ΠΈΠ΄Π΅ΠΎ-ΠΏΠΎΡΠΎΠΊΠ° Ρ ΠΊΠ°ΠΌΠ΅ΡΡ ΡΠΌΠ°ΡΡΡΠΎΠ½Π°). ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°Π»ΠΈ ΠΎΠ±ΡΡΠ΅Π½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π² ΡΠΎΡΠΌΠ°Ρ tfjs_graph_model
Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π΅Π΅ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π² JavaScript/TypeScript ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ π <strong>Π·Π°ΠΏΡΡΡΠΈΡΡ Links Detector</strong> ΡΠΎ ΡΠ²ΠΎΠ΅Π³ΠΎ ΡΠΌΠ°ΡΡΡΠΎΠ½Π° ΠΈ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ, ΠΊΠ°ΠΊ ΠΎΠ½ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°Π΅Ρ ΡΡΡΠ»ΠΊΠΈ Π² Π²Π°ΡΠ΅ΠΉ ΠΊΠ½ΠΈΠ³Π΅ ΠΈΠ»ΠΈ ΠΆΡΡΠ½Π°Π»Π΅.
Π€ΠΈΠ½Π°Π»ΡΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ π <strong>ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Ρ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠ΅ΠΌ links-detector</strong> Π½Π° GitHub, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΉΡΠΈ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠΉ ΡΠ°ΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
β οΈ ΠΠ° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΡΠ°Π΄ΠΈΠΈ ΠΈ ΠΈΠΌΠ΅Π΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π½Π΅Π΄ΠΎΡΠ°Π±ΠΎΡΠΎΠΊ ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠΉ. ΠΠΎΡΡΠΎΠΌΡ, Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π²ΡΡΠ΅ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π½Π΅Π΄ΠΎΡΠ°Π±ΠΎΡΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π»ΠΈΠΊΠ²ΠΈΠ΄ΠΈΡΠΎΠ²Π°Π½Ρ, Π½Π΅ ΠΎΠΆΠΈΠ΄Π°ΠΉΡΠ΅ ΠΎΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΎΠ³ΠΎ π€·π»β.
Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ»Π΅Π΄ΡΡΡΠΈΡ ΡΠ°Π³ΠΎΠ² ΠΏΠΎ ΡΠ»ΡΡΡΠ΅Π½ΠΈΡ ΡΠΎΡΠ½ΠΎΡΡΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΡΠΉ ΠΈ ΡΠ΅ΡΡΠΎΠ²ΡΠΉ Π½Π°Π±ΠΎΡΡ Π΄Π°Π½Π½ΡΡ
ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ ΡΠ°Π·Π½ΡΡ
ΡΠΎΡΠΌΠ°ΡΠΎΠ² (
http://
,tcp://
,ftp://
ΠΈ ΠΏΡ.) - ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ ΠΏΡΠΈΠΌΠ΅ΡΠ°ΠΌΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ ΡΠ΅ΠΌΠ½ΡΠΌ ΡΠΎΠ½ΠΎΠΌ ΠΈ ΡΠ²Π΅ΡΠ»ΡΠΌ ΡΠ΅ΠΊΡΡΠΎΠΌ.
- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ ΠΏΠΎΠ΄ΡΠ΅ΡΠΊΠ½ΡΡΡΠΌΠΈ ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ.
- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΡ Π½Π°Π±ΠΎΡ Π΄Π°Π½Π½ΡΡ ΡΠ΅ΠΊΡΡΠ°ΠΌΠΈ ΠΈ ΡΡΡΠ»ΠΊΠ°ΠΌΠΈ Ρ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΡΡΠΈΡΡΠ°ΠΌΠΈ
- ΠΈ ΠΏΡ.
ΠΠ΅ΡΠΌΠΎΡΡΡ Π½Π° ΡΠΎ, ΡΡΠΎ ΡΠΎΡΠ½ΠΎΡΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½Π° Π΄Π»Ρ ΡΠ΅Π»ΠΈΠ·Π° ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Ρ Π²ΡΠ΅-ΠΆΠ΅ Π½Π°Π΄Π΅ΡΡΡ, ΡΡΠΎ ΡΡΠ° ΡΡΠ°ΡΡΡ Π±ΡΠ»Π° Π΄Π»Ρ Π²Π°Ρ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ ΠΈ Π²Π΄ΠΎΡ Π½ΠΎΠ²ΠΈΠ»Π° Π²Π°Ρ Π½Π° Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠΈΠ΅ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΡ Ρ ΠΌΠΎΠ΄Π΅Π»ΡΠΌΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
Π£ΡΠΏΠ΅ΡΠ½ΠΎΠΉ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ!
ΠΠ»Π°ΡΡΠ½Π°Ρ ΠΈ ΠΏΠΎΠ»Π΅Π·Π½Π°Ρ ΡΡΠ°ΡΡΡ, ΠΎΠ³ΡΠΎΠΌΠ½ΠΎΠ΅ ΡΠΏΠ°ΡΠΈΠ±ΠΎ! ΠΠ½Π΅ Π½ΡΠ°Π²ΠΈΡΡΡ, ΡΡΠΎ Π²ΡΠ΅ ΡΠ°ΡΡΠΊΠ°Π·Π°Π½ΠΎ ΠΎΡΠ΅Π½Ρ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ, Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΌΠ°Π³ΠΈΠΈ Π·Π° ΡΠΊΠΎΠ±ΠΊΠ°ΠΌΠΈ Π½Π΅ ΠΎΡΡΠ°Π΅ΡΡΡ. ΠΡΠ΅Π³Π΄Π° Π±Ρ ΡΠ°ΠΊ :)
ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΠΉ ΠΈ Π³Π»Π°Π²Π½ΠΎΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΏΡΠΎΠ΅ΠΊΡ (ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΏΠΎΡ ΠΎΠΆΠΈΠ΅ ML ΠΌΠΈΠΊΡΠΎ-ΠΏΡΠΎΠ΅ΠΊΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π²ΡΡΡΠ΅ΡΠ°Π» Π·Π°Π±Π°Π²Π½ΡΠ΅, Π½ΠΎ real-life Π·Π°Π΄Π°Ρ Π½Π΅ ΡΠ΅ΡΠ°ΡΡ).
ΠΠΎΠΏΡΠΎΡ Π½Π΅ ΡΠΎΠ²ΡΠ΅ΠΌ ΠΏΠΎ ΡΠ΅ΠΌΠ΅. ΠΠ½ΠΈΠ³Π° Π½Π΅ ΡΡΠ° ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎ? https://www.amazon.com/Hands-Machine-Learning-Scikit-Learn-TensorFlow-ebook-dp-B07XGF2G87/dp/B07XGF2G87/ref=mt_other?_encoding=UTF8&me=&qid=
ΠΡΠ»ΠΈ ΠΎΠ½Π°, ΡΠΎ Π±ΡΠ»ΠΎ Π±Ρ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ, Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠ½Π° ΠΏΠΎΠ»Π΅Π·Π½Π° Π΄Π»Ρ Π½Π°ΡΠΈΠ½Π°ΡΡΠ΅Π³ΠΎ Π² ML ΠΈ ΠΊΠ°ΠΊΠΎΠΉ Π² Π½Π΅ΠΉ Π±Π°Π»Π°Π½Ρ ΡΠ΅ΠΎΡΠΈΠΈ ΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ? ΠΠ° Π³ΡΠ΄ΡΠΈΠ΄ΡΠ΅ ΠΏΠΈΡΡΡ, ΡΡΠΎ ΠΊΠΎΠ΄Π° ΠΌΠ½ΠΎΠ³ΠΎ, Π½ΠΎ ΡΠΎΠ²ΡΠ΅ΠΌ Π½Π΅Ρ ΠΎΠ±ΡΡΡΠ½Π΅Π½ΠΈΡ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡ Π² ΡΠ°ΡΡΠΈ ΠΏΡΠΎ Π½Π΅ΠΉΡΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΠΈ.
Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ, Ρ ΠΏΡΡΠΌΠΎ Π·Π°ΡΠΈΡΠ°Π»ΡΡ, Π±ΡΠ΄ΡΠΎ Π±Ρ ΡΡΠΎ ΠΈ Π½Π΅ ΠΠ ΡΠΎΠ²ΡΠ΅ΠΌ :)
ΠΠ΅ ΡΠΈΡΠ°Π», Π½ΠΎ ΠΏΠ»ΡΡΠ°Π½Ρ. Π Π² Π·Π°ΠΊΠ»Π°Π΄ΠΊΠΈ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ ΠΆΠ΅ :D