Π Π°Π±ΠΎΡΠ° ΠΌΠ΅ΡΡΡ Π² ΠΎΠ΄ΠΈΠ½ ΠΊΠ»ΠΈΠΊ πΌ

πΠΠ΅ΡΡΠ°Π΅ΡΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² Π‘Π±Π΅ΡΠ΅, Π½ΠΎ Π½Π΅ Ρ ΠΎΡΠ΅ΡΡ ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡΡ Π΄Π΅ΡΡΡΡ ΠΊΡΡΠ³ΠΎΠ² HR-ΡΠΎΠ±Π΅ΡΠ΅Π΄ΠΎΠ²Π°Π½ΠΈΠΉ? Π’Π΅ΠΏΠ΅ΡΡ ΡΡΠΎ ΠΏΡΠΎΡΠ΅, ΡΠ΅ΠΌ ΠΊΠΎΠ³Π΄Π°-Π»ΠΈΠ±ΠΎ!
π‘AI-ΠΈΠ½ΡΠ΅ΡΠ²ΡΡ Π·Π° 15 ΠΌΠΈΠ½ΡΡ β ΠΈ ΡΡ ΡΠΆΠ΅ Π½Π° ΡΠ°Π³ Π±Π»ΠΈΠΆΠ΅ ΠΊ ΡΠ²ΠΎΠ΅ΠΉ Π½ΠΎΠ²ΠΎΠΉ ΡΠ°Π±ΠΎΡΠ΅.
ΠΠ°ΠΊ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΎΡΡΠ΅Ρ?
π ΠΠ°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠΉΡΡ
π ΠΡΠΎΠΉΠ΄ΠΈ AI-ΠΈΠ½ΡΠ΅ΡΠ²ΡΡ
π ΠΠΎΠ»ΡΡΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΡΡ ΡΠ²ΡΠ·Ρ ΡΡΠ°Π·Ρ ΠΆΠ΅!
HR Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ ΡΡΠ½ΡΡ Π²ΡΠ΅ΠΌΡ β ΡΠ΅ΠΊΡΡΡΠ΅ΡΡ ΡΠ²ΡΠΆΡΡΡΡ Ρ ΡΠΎΠ±ΠΎΠΉ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΄Π²ΡΡ Π΄Π½Π΅ΠΉ! π
Π Π΅ΠΊΠ»Π°ΠΌΠ°. ΠΠΠ Π‘ΠΠΠ ΠΠΠΠ, ΠΠΠ 7707083893. Erid 2VtzquscAwp
Π Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ YOLO v3 Π½Π° Tensorflow 2.0
ΠΠΎ Yolo Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ² ΠΊ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π·Π°ΠΊΠ»ΡΡΠ°Π»ΠΎΡΡ Π² ΠΏΠΎΠΏΡΡΠΊΠ°Ρ Π°Π΄Π°ΠΏΡΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠ»Π°ΡΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ ΠΊ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ. Π YOLO, ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π±ΡΠ»ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ ΠΊΠ°ΠΊ Π·Π°Π΄Π°ΡΠ° ΡΠ΅Π³ΡΠ΅ΡΡΠΈΠΈ ΠΊ ΡΠ°Π·Π΄Π΅Π»ΡΠ½ΡΠΌ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°ΡΡΠΈΠΌ ΡΠ°ΠΌΠΊΠ°ΠΌ, Ρ ΠΊΠΎΡΠΎΡΡΠΌΠΈ ΡΠ²ΡΠ·Π°Π½Ρ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ½ΠΎΡΡΠΈ ΠΊ ΡΠ°Π·Π½ΡΠΌ ΠΊΠ»Π°ΡΡΠ°ΠΌ. ΠΠΈΠΆΠ΅ ΠΌΡ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΠΌΡΡ Ρ ΠΌΠΎΠ΄Π΅Π»ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² YOLO ΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ Π΅Π΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π² Tensorflow 2.0.

Π YOLO: ΠΠ°ΡΠ° ΠΎΠ±ΠΎΠ±ΡΠ΅Π½Π½Π°Ρ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° ΡΡΠ΅Π·Π²ΡΡΠ°ΠΉΠ½ΠΎ Π±ΡΡΡΡΠ°. ΠΠ°Π·ΠΎΠ²Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ YOLO ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΡΠΎ ΡΠΊΠΎΡΠΎΡΡΡΡ 45 ΡΡΠ΅ΠΉΠΌΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ. ΠΠ΅Π½ΡΡΠ°Ρ Π²Π΅ΡΡΠΈΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Fast YOLO, ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΡΠ΅Π»ΡΡ 155 ΡΡΠ΅ΠΉΠΌΠΎΠ² Π² ΡΠ΅ΠΊΡΠ½Π΄Ρβ¦
Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ YOLO?
YOLO β ΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄ΠΎΠ²Π°Ρ ΡΠ΅ΡΡ Π΄Π»Ρ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² (object detection), ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Π½Π°Ρ ΠΠΆΠΎΠ·Π΅ΡΠΎΠΌ Π Π΅Π΄ΠΌΠΎΠ½ΠΎΠΌ (Joseph Redmon). ΠΠ»Π°Π²Π½ΠΎΠ΅, ΡΡΠΎ ΠΎΡΠ»ΠΈΡΠ°Π΅Ρ Π΅Π΅ ΠΎΡ Π΄ΡΡΠ³ΠΈΡ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΡΡ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡ β ΡΡΠΎ ΡΠΊΠΎΡΠΎΡΡΡ. ΠΠΎΠ΄Π΅Π»ΠΈ ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²Π° YOLO Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π±ΡΡΡΡΡΠ΅, Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ Π±ΡΡΡΡΠ΅Π΅ R-CNN ΠΈ Π΄ΡΡΠ³ΠΈΡ . ΠΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ.
ΠΠΎ Π²ΡΠ΅ΠΌΡ ΠΏΠ΅ΡΠ²ΠΎΠΉ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ (Π² 2016 Π³ΠΎΠ΄Ρ) YOLO ΠΈΠΌΠ΅Π»Π° ΠΏΠ΅ΡΠ΅Π΄ΠΎΠ²ΡΡ mAP (mean Average Precision), ΠΏΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Ρ ΡΠ°ΠΊΠΈΠΌΠΈ ΡΠΈΡΡΠ΅ΠΌΠ°ΠΌΠΈ, ΠΊΠ°ΠΊ R-CNN ΠΈ DPM. Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, YOLO Ρ ΡΡΡΠ΄ΠΎΠΌ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΡΠ΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠΎΡΠ½ΠΎ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΎΠ½Π° ΠΎΠ±ΡΡΠ°Π΅ΡΡΡ ΠΎΠ±ΡΠ΅ΠΌΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². Π Π½ΠΎΠ²ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ ΠΊΠ°ΠΊ ΡΠΊΠΎΡΠΎΡΡΡ, ΡΠ°ΠΊ ΠΈ ΡΠΎΡΠ½ΠΎΡΡΡ ΡΠΈΡΡΠ΅ΠΌΡ Π±ΡΠ»ΠΈ ΡΠ»ΡΡΡΠ΅Π½Ρ.
YOLO ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π»Π° Π·Π°Π΄Π°ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΊ Π΅Π΄ΠΈΠ½ΠΎΠΉ Π·Π°Π΄Π°ΡΠ΅ ΡΠ΅Π³ΡΠ΅ΡΡΠΈΠΈ. ΠΠ½Π° ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡ ΠΏΡΡΠΌΠΎ ΠΎΡ ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π΄ΠΎ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ ΠΈ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΊΠ»Π°ΡΡΠΎΠ². Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π΅Π΄ΠΈΠ½Π°Ρ CNN ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ ΠΈ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ ΠΊΠ»Π°ΡΡΠΎΠ² Π΄Π»Ρ ΡΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ.
Π’Π΅ΠΎΡΠΈΡ
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ YOLO ΡΠΌΠΎΡΡΠΈΡ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π·, ΠΏΠ»Π°Π²Π°ΡΡΠ΅Π΅ ΠΎΠΊΠ½ΠΎ β ΡΡΠΎ Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ, Π²ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π·Π±ΠΈΠ²Π°Π΅ΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ΅ΡΠΊΠΈ Π½Π° ΡΡΠ΅ΠΉΠΊΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ πβπ. ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΊΠ°ΠΆΠ΄Π°Ρ ΡΡΠ΅ΠΉΠΊΠ° ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π²Π΅ΡΠ΅ΠΉ
ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , ΠΊΠ°ΠΆΠ΄Π°Ρ ΡΡΠ΅ΠΉΠΊΠ° ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ ΠΈ ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΠ²Π΅ΡΠ΅Π½Π½ΠΎΡΡΠΈ (confidence) Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· Π½ΠΈΡ β Π΄ΡΡΠ³ΠΈΠΌΠΈ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ, ΡΡΠΎ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡ ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π΄Π°Π½Π½Π°Ρ ΡΠ°ΠΌΠΊΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡ. ΠΡΠ»ΠΈ Π² ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΡΡΠ΅ΠΉΠΊΠ΅ ΡΠ΅ΡΠΊΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π½Π΅Ρ, ΡΠΎ ΠΎΡΠ΅Π½Ρ Π²Π°ΠΆΠ½ΠΎ, ΡΡΠΎΠ±Ρ confidence Π΄Π»Ρ ΡΡΠΎΠΉ ΡΡΠ΅ΠΉΠΊΠΈ Π±ΡΠ» ΠΎΡΠ΅Π½Ρ ΠΌΠ°Π»ΡΠΌ.
ΠΠΎΠ³Π΄Π° ΠΌΡ Π²ΠΈΠ·ΡΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ Π²ΡΠ΅ ΡΡΠΈ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ, ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΊΠ°ΡΡΡ Π²ΡΠ΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΈ Π½Π°Π±ΠΎΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ, ΡΠ°Π½ΠΆΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΏΠΎ ΠΈΡ confidence.

ΠΠΎ-Π²ΡΠΎΡΡΡ , ΠΊΠ°ΠΆΠ΄Π°Ρ ΡΡΠ΅ΠΉΠΊΠ° ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΊΠ»Π°ΡΡΠΎΠ². ΠΡΠΎ Π½Π΅ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ ΠΊΠ°ΠΊΠ°Ρ-ΡΠΎ ΡΡΠ΅ΠΉΠΊΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ, ΡΡΠΎ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π΅ΡΠ»ΠΈ ΡΡΠ΅ΠΉΠΊΠ° ΡΠ΅ΡΠΈ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π°Π²ΡΠΎΠΌΠΎΠ±ΠΈΠ»Ρ, ΡΡΠΎ Π½Π΅ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ ΠΎΠ½ ΡΠ°ΠΌ Π΅ΡΡΡ, Π½ΠΎ ΡΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ Π΅ΡΠ»ΠΈ ΡΠ°ΠΌ Π΅ΡΡΡ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ, ΡΠΎ ΡΡΠΎ Π°Π²ΡΠΎΠΌΠΎΠ±ΠΈΠ»Ρ.
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΎΠΏΠΈΡΠ΅ΠΌ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ Π²ΡΠ΄Π°Π²Π°Π΅ΠΌΡΠΉ ΠΌΠΎΠ΄Π΅Π»ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ.
Π YOLO Π΄Π»Ρ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ ΡΠΊΠΎΡΠ½ΡΠ΅ ΡΠ°ΠΌΠΊΠΈ (anchor boxes). ΠΡ ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ ΠΈΠ΄Π΅Ρ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΠΏΡΠ΅Π΄ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π΄Π²ΡΡ ΡΠ°Π·Π½ΡΡ ΡΠ°ΠΌΠΎΠΊ, Π½Π°Π·ΡΠ²Π°Π΅ΠΌΡΡ ΡΠΊΠΎΡΠ½ΡΠΌΠΈ ΡΠ°ΠΌΠΊΠ°ΠΌΠΈ ΠΈΠ»ΠΈ ΡΠΎΡΠΌΠΎΠΉ ΡΠΊΠΎΡΠ½ΡΡ ΡΠ°ΠΌΠΎΠΊ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ Π°ΡΡΠΎΡΠΈΠΈΡΠΎΠ²Π°ΡΡ Π΄Π²Π° ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ Ρ ΡΡΠΈΠΌΠΈ ΡΠΊΠΎΡΠ½ΡΠΌΠΈ ΡΠ°ΠΌΠΊΠ°ΠΌΠΈ. Π ΠΎΠ±ΡΠ΅ΠΌ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈ Π±ΠΎΠ»ΡΡΠ΅Π΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΊΠΎΡΠ½ΡΡ ΡΠ°ΠΌΠΎΠΊ (ΠΏΡΡΡ ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ Π±ΠΎΠ»ΡΡΠ΅). Π―ΠΊΠΎΡΡ Π±ΡΠ»ΠΈ ΡΠ°ΡΡΡΠΈΡΠ°Π½Ρ Π½Π° Π΄Π°ΡΠ°ΡΠ΅ΡΠ΅ COCO Ρ ΠΏΠΎΠΌΠΎΡΡΡ k-means ΠΊΠ»Π°ΡΡΠ΅ΡΠΈΠ·Π°ΡΠΈΠΈ.

Π£ Π½Π°Ρ Π΅ΡΡΡ ΡΠ΅ΡΠΊΠ°, ΠΊΠ°ΠΆΠ΄Π°Ρ ΡΡΠ΅ΠΉΠΊΠ° ΠΊΠΎΡΠΎΡΠΎΠΉ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°ΡΡ:
- Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ΅ΠΉ ΡΠ°ΠΌΠΊΠΈ: 4 ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ (π‘π₯,π‘π¦,π‘π€,π‘β) ΠΈ ΠΎΠ΄Π½Ρ "ΠΎΡΠΈΠ±ΠΊΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎΡΡΠΈ" β ΡΠΎ Π΅ΡΡΡ, ΠΌΠ΅ΡΡΠΈΠΊΡ confidence, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡΡΡ, Π΅ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΈΠ»ΠΈ Π½Π΅Ρ.
- Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠ΅ΠΉ ΠΊΠ»Π°ΡΡΠΎΠ².
ΠΡΠ»ΠΈ Π΅ΡΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π²Π΅ΡΡ Π½Π΅Π³ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ ΡΠ³Π»Π° ππ₯,ππ¦, ΡΠΎ ΡΡΠΈ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠΎΡΠΌΡΠ»Π°ΠΌ:
Π³Π΄Π΅ ππ€ ΠΈ πβ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ ΡΠΈΡΠΈΠ½Π΅ ΠΈ Π²ΡΡΠΎΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ΅ΠΉ ΡΠ°ΠΌΠΊΠΈ. ΠΠΌΠ΅ΡΡΠΎ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ ΡΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ, ΠΊΠ°ΠΊ Π±ΡΠ»ΠΎ Π²ΠΎ Π²ΡΠΎΡΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ YOLO, Π°Π²ΡΠΎΡΡ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ Π»ΠΎΠΊΠ°ΡΠΈΠΈ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΡΠ΅ΠΉΠΊΠΈ ΡΠ΅ΡΠΈ.
ΠΡΠΎΡ Π²ΡΠ²ΠΎΠ΄ β ΡΡΠΎ Π²ΡΠ²ΠΎΠ΄ Π½Π°ΡΠ΅ΠΉ Π½Π΅ΠΉΡΠΎΠ½Π½ΠΎΠΉ ΡΠ΅ΡΠΈ. ΠΡΠ΅Π³ΠΎ ΡΠ°ΠΌ πβπβ[π΅β(4+1+πΆ)] Π²ΡΠ²ΠΎΠ΄ΠΎΠ², Π³Π΄Π΅ π΅ β ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ, ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ΅ΠΉΠΊΠΎΠΉ (Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ ΡΠΎΠ³ΠΎ, Π² ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΌΠ°ΡΡΡΠ°Π±Π°Ρ ΠΌΡ Ρ ΠΎΡΠΈΠΌ Π΄Π΅Π»Π°ΡΡ Π½Π°ΡΠΈ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ), πΆ β ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠ»Π°ΡΡΠΎΠ², 4 β ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ ΡΠ°ΠΌΠΎΠΊ, Π° 1 β ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎΡΡΠΈ. ΠΠ° ΠΎΠ΄ΠΈΠ½ ΠΏΡΠΎΡ ΠΎΠ΄ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΎΠΉΡΠΈ ΠΎΡ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π΄ΠΎ Π²ΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ΅Π½Π·ΠΎΡΠ°, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ. Π‘ΡΠΎΠΈΡ ΡΠ°ΠΊΠΆΠ΅ ΡΠΏΠΎΠΌΡΠ½ΡΡΡ, ΡΡΠΎ YOLO v3 ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΠ°ΠΌΠΊΠΈ Π² ΡΡΠ΅Ρ ΡΠ°Π·Π½ΡΡ ΠΌΠ°ΡΡΡΠ°Π±Π°Ρ .
Π’Π΅ΠΏΠ΅ΡΡ, Π΅ΡΠ»ΠΈ ΠΌΡ Π²ΠΎΠ·ΡΠΌΠ΅ΠΌ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ ΠΈ ΡΠΌΠ½ΠΎΠΆΠΈΠΌ ΠΈΡ Π½Π° Π·Π½Π°ΡΠ΅Π½ΠΈΡ confidence, ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ Π²ΡΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ ΡΠ°ΠΌΠΊΠΈ, Π²Π·Π²Π΅ΡΠ΅Π½Π½ΡΠ΅ ΠΏΠΎ ΠΈΡ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠ°Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°.
ΠΡΠΎΡΡΠΎΠ΅ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Ρ ΠΏΠΎΡΠΎΠ³ΠΎΠΌ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ Π½Π°ΠΌ ΠΈΠ·Π±Π°Π²ΠΈΡΡΡΡ ΠΎΡ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΠΉ Ρ Π½ΠΈΠ·ΠΊΠΎΠΉ confidence. ΠΠ»Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΠ°Π³Π° Π²Π°ΠΆΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, ΡΡΠΎ ΡΠ°ΠΊΠΎΠ΅ ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ (intersection over union). ΠΡΠΎ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ ΠΏΠ»ΠΎΡΠ°Π΄ΠΈ ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΏΡΡΠΌΠΎΡΠ³ΠΎΠ»ΡΠ½ΠΈΠΊΠΎΠ² ΠΊ ΠΏΠ»ΠΎΡΠ°Π΄ΠΈ ΠΈΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ:

ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Ρ Π½Π°Ρ Π΅ΡΠ΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π΄ΡΠ±Π»ΠΈΠΊΠ°ΡΡ, ΠΈ ΡΡΠΎΠ±Ρ ΠΎΡ Π½ΠΈΡ ΠΈΠ·Π±Π°Π²ΠΈΡΡΡΡ, ΠΌΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΠΏΠΎΠ΄Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π΅-ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌΠΎΠ². ΠΠΎΠ΄Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π΅-ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌΠΎΠ² Π±Π΅ΡΠ΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡ ΡΠ°ΠΌΠΊΡ Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡΡ ΠΈ ΡΠΌΠΎΡΡΠΈΡ Π½Π° Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ ΡΠ°ΠΌΠΊΠΈ, ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½Π½ΡΠ΅ Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ ΠΏΠ΅ΡΠ²ΠΎΠΉ. ΠΠ»ΠΈΠΆΠ°ΠΉΡΠΈΠ΅ ΡΠ°ΠΌΠΊΠΈ Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΌ ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ Ρ ΠΏΠ΅ΡΠ²ΠΎΠΉ ΡΠ°ΠΌΠΊΠΎΠΉ Π±ΡΠ΄ΡΡ ΠΏΠΎΠ΄Π°Π²Π»Π΅Π½Ρ.
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π²ΡΠ΅ Π΄Π΅Π»Π°Π΅ΡΡΡ Π·Π° ΠΎΠ΄ΠΈΠ½ ΠΏΡΠΎΡ ΠΎΠ΄, ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΏΠΎΡΡΠΈ Ρ ΡΠ°ΠΊΠΎΠΉ ΠΆΠ΅ ΡΠΊΠΎΡΠΎΡΡΡΡ, ΠΊΠ°ΠΊ ΠΊΠ»Π°ΡΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, Π²ΡΠ΅ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°Π½ΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΡΡΡΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ, Π° ΡΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π΅ΡΠ²Π½ΠΎ Π²ΡΡΡΠ°ΠΈΠ²Π°Π΅Ρ Π² ΡΠ΅Π±Ρ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ. ΠΡΠΎΡΠ΅ Π³ΠΎΠ²ΠΎΡΡ, ΠΌΠΎΠ΄Π΅Π»Ρ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ²ΠΎΠΈΡΡ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΎΠ±ΡΡΠ½ΠΎ Π²ΡΡΡΠ΅ΡΠ°ΡΡΡΡ Π²ΠΌΠ΅ΡΡΠ΅, ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΡ ΠΈ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΈ ΡΠ°ΠΊ Π΄Π°Π»Π΅Π΅.
ΠΡ Π½Π°ΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌ ΠΈΠ·ΡΡΠΈΡΡ Π²ΡΠ΅ ΡΡΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ° YOLO:
- You Only Look Once: ΡΠ½ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ
- YOLO 9000: Π±ΡΡΡΡΠ΅Π΅, Π»ΡΡΡΠ΅, ΡΠΈΠ»ΡΠ½Π΅Π΅
- YOLOv3: ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎΠ΅ ΡΠ»ΡΡΡΠ΅Π½ΠΈΠ΅
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ YOLO Π² Tensorflow
ΠΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠΎΠ»Π½ΡΡ ΡΠ²Π΅ΡΡΠΎΡΠ½ΡΡ Π½Π΅ΠΉΡΠΎΠ½Π½ΡΡ ΡΠ΅ΡΡ (Fully Convolutional Network, FCN) Π±Π΅Π· ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ. Π§ΡΠΎΠ±Ρ ΡΡΠΎ-ΡΠΎ ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·Π°ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠΎΠΉ ΡΠ΅ΡΠΈ, Π½ΡΠΆΠ½ΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ Π²Π΅ΡΠ° ΠΎΡ Π·Π°ΡΠ°Π½Π΅Π΅ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ. ΠΡΠΈ Π²Π΅ΡΠ° ΠΏΠΎΠ»ΡΡΠ΅Π½Ρ ΠΏΠΎΡΠ»Π΅ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ YOLOv3 Π½Π° Π΄Π°ΡΠ°ΡΠ΅ΡΠ΅ COCO (Common Objects in Context), ΠΈ ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ Ρ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΠΉΡΠ°.
!wget https://pjreddie.com/media/files/yolov3.weights
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡ Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ Π²Π΅ΡΠΎΠ²
#!rm -rf checkpoints
!mkdir checkpoints
ΠΠΌΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ
import cv2
import numpy as np
import tensorflow as tf
from absl import logging
from itertools import repeat
from tensorflow.keras import Model
from tensorflow.keras.layers import Add, Concatenate, Lambda
from tensorflow.keras.layers import Conv2D, Input, LeakyReLU
from tensorflow.keras.layers import MaxPool2D, UpSampling2D, ZeroPadding2D
from tensorflow.keras.regularizers import l2
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras.losses import sparse_categorical_crossentropy
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π²Π΅ΡΡΠΈΡ Tensorflow. ΠΠ½Π° Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ Π½Π΅ Π½ΠΈΠΆΠ΅ 2.0:
print(tf.__version__)
# 2.1.0
ΠΠΏΡΠ΅Π΄Π΅Π»ΠΈΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π°ΠΆΠ½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½ΠΈΠΆΠ΅.
yolo_iou_threshold = 0.6 # ΠΏΠΎΡΠΎΠ³ ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ (iou)
yolo_score_threshold = 0.6
weightsyolov3 = 'yolov3.weights' # ΠΏΡΡΡ ΠΊ ΡΠ°ΠΉΠ»Ρ Π²Π΅ΡΠΎΠ²
weights= 'checkpoints/yolov3.tf' # ΠΏΡΡΡ ΠΊ ΡΠ°ΠΉΠ»Ρ checkpoint'ΠΎΠ²
size= 416 # ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΊ ΡΡΠΎΠΌΡ ΡΠ°Π·ΠΌΠ΅ΡΡ
checkpoints = 'checkpoints/yolov3.tf'
num_classes = 80 # ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠ»Π°ΡΡΠΎΠ² Π² ΠΌΠΎΠ΄Π΅Π»ΠΈ
Π‘ΠΏΠΈΡΠΎΠΊ ΡΠ»ΠΎΠ΅Π² Π² YOLOv3 FCN β Fully Convolutional Network
YOLO_V3_LAYERS = [
'yolo_darknet',
'yolo_conv_0',
'yolo_output_0',
'yolo_conv_1',
'yolo_output_1',
'yolo_conv_2',
'yolo_output_2',
]
ΠΡΠ΅Π½Ρ ΡΡΡΠ΄Π½ΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ Π²Π΅ΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΈΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ API, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΠΎΡΡΠ΄ΠΎΠΊ ΡΠ»ΠΎΠ΅Π² Π² Darknet ΠΈ tf.keras ΡΠ°Π·Π»ΠΈΡΠ°ΡΡΡΡ. ΠΠ΄Π΅ΡΡ Π»ΡΡΡΠ΅Π΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ β ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΠ΄ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π² keras. ΠΠ»Ρ ΡΠΎΡ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΏΠΎΠ΄ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Checkpoint'Ρ Tensorflow, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ΠΈ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ Tensorflow.
ΠΠΎΡ ΡΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ Π²Π΅ΡΠΎΠ² ΠΈΠ· ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ ΡΡΠ΅Π½ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ YOLO Π² Darknet:
def load_darknet_weights(model, weights_file):
wf = open(weights_file, 'rb')
major, minor, revision, seen, _ = np.fromfile(wf, dtype=np.int32, count=5)
layers = YOLO_V3_LAYERS
for layer_name in layers:
sub_model = model.get_layer(layer_name)
for i, layer in enumerate(sub_model.layers):
if not layer.name.startswith('conv2d'):
continue
batch_norm = None
if i + 1 < len(sub_model.layers) and \
sub_model.layers[i + 1].name.startswith('batch_norm'):
batch_norm = sub_model.layers[i + 1]
logging.info("{}/{} {}".format(
sub_model.name, layer.name, 'bn' if batch_norm else 'bias'))
filters = layer.filters
size = layer.kernel_size[0]
in_dim = layer.input_shape[-1]
if batch_norm is None:
conv_bias = np.fromfile(wf, dtype=np.float32, count=filters)
else:
bn_weights = np.fromfile(
wf, dtype=np.float32, count=4 * filters)
bn_weights = bn_weights.reshape((4, filters))[[1, 0, 2, 3]]
conv_shape = (filters, in_dim, size, size)
conv_weights = np.fromfile(
wf, dtype=np.float32, count=np.product(conv_shape))
conv_weights = conv_weights.reshape(
conv_shape).transpose([2, 3, 1, 0])
if batch_norm is None:
layer.set_weights([conv_weights, conv_bias])
else:
layer.set_weights([conv_weights])
batch_norm.set_weights(bn_weights)
assert len(wf.read()) == 0, 'Π½Π΅ ΡΠ΄Π°Π»ΠΎΡΡ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ Π²ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅'
wf.close()
Π€ΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΡΠ°ΡΡΠ΅ΡΠ° ΠΏΠ΅ΡΠ΅ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ
def interval_overlap(interval_1, interval_2):
x1, x2 = interval_1
x3, x4 = interval_2
if x3 < x1:
return 0 if x4 < x1 else (min(x2,x4) - x1)
else:
return 0 if x2 < x3 else (min(x2,x4) - x3)
def intersectionOverUnion(box1, box2):
intersect_w = interval_overlap([box1.xmin, box1.xmax], [box2.xmin, box2.xmax])
intersect_h = interval_overlap([box1.ymin, box1.ymax], [box2.ymin, box2.ymax])
intersect_area = intersect_w * intersect_h
w1, h1 = box1.xmax-box1.xmin, box1.ymax-box1.ymin
w2, h2 = box2.xmax-box2.xmin, box2.ymax-box2.ymin
union_area = w1*h1 + w2*h2 - intersect_area
return float(intersect_area) / union_area
Π€ΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ΅ΠΉ ΡΠ°ΠΌΠΊΠΈ, ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠ»Π°ΡΡΠ° ΠΈ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΠΈ:
def draw_outputs(img, outputs, class_names):
boxes, score, classes, nums = outputs
boxes, score, classes, nums = boxes[0], score[0], classes[0], nums[0]
wh = np.flip(img.shape[0:2])
for i in range(nums):
x1y1 = tuple((np.array(boxes[i][0:2]) * wh).astype(np.int32))
x2y2 = tuple((np.array(boxes[i][2:4]) * wh).astype(np.int32))
img = cv2.rectangle(img, x1y1, x2y2, (255, 0, 0), 2)
img = cv2.putText(img, '{} {:.4f}'.format(
class_names[int(classes[i])], score[i]),
x1y1, cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 2)
return img
ΠΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΏΠ°ΠΊΠ΅ΡΠ½ΡΡ Π½ΠΎΡΠΌΠ°Π»ΠΈΠ·Π°ΡΠΈΡ (batch normalization), ΡΡΠΎΠ±Ρ Π½ΠΎΡΠΌΠ°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ Π΄Π»Ρ ΡΡΠΊΠΎΡΠ΅Π½ΠΈΡ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠΈ. Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, tf.keras.layers.BatchNormalization ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π΅ ΠΎΡΠ΅Π½Ρ Ρ
ΠΎΡΠΎΡΠΎ Π΄Π»Ρ transfer learning, ΠΏΠΎΡΡΠΎΠΌΡ Π·Π΄Π΅ΡΡ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅ΡΡΡ Π΄ΡΡΠ³ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
class BatchNormalization(tf.keras.layers.BatchNormalization):
def call(self, x, training=False):
if training is None: training = tf.constant(False)
training = tf.logical_and(training, self.trainable)
return super().call(x, training)
ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΌΠ°ΡΡΡΠ°Π±Π° ΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΡΡΠΈ ΡΠΊΠΎΡΠ½ΡΠ΅ ΡΠ°ΠΌΠΊΠΈ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ΅ΠΉΠΊΠΈ. Π ΡΡΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΌΠ°ΡΠΊΠ° ΡΠ°ΠΊΠΎΠ²Π°:
- 0,1,2 β ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΈ ΠΏΠ΅ΡΠ²ΡΠ΅ ΡΠΊΠΎΡΠ½ΡΠ΅ ΡΠ°ΠΌΠΊΠΈ
- 3,4,5 β ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ΅ΡΠ²Π΅ΡΡΡΡ, ΠΏΡΡΡΡ ΠΈ ΡΠ΅ΡΡΡΡ ΡΠ°ΠΌΠΊΠΈ
- 6,7,8 β ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ΅Π΄ΡΠΌΡΡ, Π²ΠΎΡΡΠΌΡΡ ΠΈ Π΄Π΅Π²ΡΡΡΡ ΡΠ°ΠΌΠΊΠΈ
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ YOLO v3
ΠΡΠΈΡΠ»ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠ΅ΡΡ YOLOv3. ΠΠΎΡ ΠΊΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ Π΅Π΅ ΡΡΡΡΠΊΡΡΡΠ°:

ΠΠ΄Π΅ΡΡ ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ ΠΈΠ΄Π΅Ρ β ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ²Π΅ΡΡΠΎΡΠ½ΡΠ΅ ΡΠ»ΠΎΠΈ. ΠΡ ΡΠ°ΠΌ 53, ΡΠ°ΠΊ ΡΡΠΎ ΠΏΡΠΎΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, Π² ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π²Π°ΠΆΠ½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ, ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΠΈΠ΅ΡΡ ΠΎΡ ΡΠ»ΠΎΡ ΠΊ ΡΠ»ΠΎΡ.

ΠΡΡΠ°ΡΠΎΡΠ½ΡΠ΅ Π±Π»ΠΎΠΊΠΈ (Residual blocks) Π½Π° Π΄ΠΈΠ°Π³ΡΠ°ΠΌΠΌΠ΅ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ YOLOv3 ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠΈΠ·Π½Π°ΠΊΠ°ΠΌ. ΠΡΡΠ°ΡΠΎΡΠ½ΡΠΉ Π±Π»ΠΎΠΊ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠ²Π΅ΡΡΠΎΡΠ½ΡΡ ΡΠ»ΠΎΠ΅Π² ΠΈ ΠΎΠ±Ρ ΠΎΠ΄Π½ΡΡ ΠΏΡΡΠ΅ΠΉ:

ΠΡ ΡΡΡΠΎΠΈΠΌ Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ API, ΠΏΡΠΎΡΡΠΎΠ³ΠΎ Π² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ. Π‘ Π½ΠΈΠΌ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π»Π΅Π³ΠΊΠΎ Π·Π°Π΄Π°Π²Π°ΡΡ Π²Π΅ΡΠ²ΠΈ Π² Π½Π°ΡΠ΅ΠΉ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ΅ (Π±Π»ΠΎΠΊ ResNet) ΠΈ Π»Π΅Π³ΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ΄Π½ΠΈ ΠΈ ΡΠ΅ ΠΆΠ΅ ΡΠ»ΠΎΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π· Π²Π½ΡΡΡΠΈ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ.
def DarknetConv(x, filters, size, strides=1, batch_norm=True):
if strides == 1:
padding = 'same'
else:
x = ZeroPadding2D(((1, 0), (1, 0)))(x) # top left half-padding
padding = 'valid'
x = Conv2D(filters=filters, kernel_size=size,
strides=strides, padding=padding,
use_bias=not batch_norm, kernel_regularizer=l2(0.0005))(x)
if batch_norm:
x = BatchNormalization()(x)
x = LeakyReLU(alpha=0.1)(x)
return x
def DarknetResidual(x, filters):
previous = x
x = DarknetConv(x, filters // 2, 1)
x = DarknetConv(x, filters, 3)
x = Add()([previous , x])
return x
def DarknetBlock(x, filters, blocks):
x = DarknetConv(x, filters, 3, strides=2)
for _ in repeat(None, blocks):
x = DarknetResidual(x, filters)
return x
def Darknet(name=None):
x = inputs = Input([None, None, 3])
x = DarknetConv(x, 32, 3)
x = DarknetBlock(x, 64, 1)
x = DarknetBlock(x, 128, 2)
x = x_36 = DarknetBlock(x, 256, 8)
x = x_61 = DarknetBlock(x, 512, 8)
x = DarknetBlock(x, 1024, 4)
return tf.keras.Model(inputs, (x_36, x_61, x), name=name)
def YoloConv(filters, name=None):
def yolo_conv(x_in):
if isinstance(x_in, tuple):
inputs = Input(x_in[0].shape[1:]), Input(x_in[1].shape[1:])
x, x_skip = inputs
x = DarknetConv(x, filters, 1)
x = UpSampling2D(2)(x)
x = Concatenate()([x, x_skip])
else:
x = inputs = Input(x_in.shape[1:])
x = DarknetConv(x, filters, 1)
x = DarknetConv(x, filters * 2, 3)
x = DarknetConv(x, filters, 1)
x = DarknetConv(x, filters * 2, 3)
x = DarknetConv(x, filters, 1)
return Model(inputs, x, name=name)(x_in)
return yolo_conv
def YoloOutput(filters, anchors, classes, name=None):
def yolo_output(x_in):
x = inputs = Input(x_in.shape[1:])
x = DarknetConv(x, filters * 2, 3)
x = DarknetConv(x, anchors * (classes + 5), 1, batch_norm=False)
x = Lambda(lambda x: tf.reshape(x, (-1, tf.shape(x)[1], tf.shape(x)[2],
anchors, classes + 5)))(x)
return tf.keras.Model(inputs, x, name=name)(x_in)
return yolo_output
def yolo_boxes(pred, anchors, classes):
grid_size = tf.shape(pred)[1]
box_xy, box_wh, score, class_probs = tf.split(pred, (2, 2, 1, classes), axis=-1)
box_xy = tf.sigmoid(box_xy)
score = tf.sigmoid(score)
class_probs = tf.sigmoid(class_probs)
pred_box = tf.concat((box_xy, box_wh), axis=-1)
grid = tf.meshgrid(tf.range(grid_size), tf.range(grid_size))
grid = tf.expand_dims(tf.stack(grid, axis=-1), axis=2)
box_xy = (box_xy + tf.cast(grid, tf.float32)) / tf.cast(grid_size, tf.float32)
box_wh = tf.exp(box_wh) * anchors
box_x1y1 = box_xy - box_wh / 2
box_x2y2 = box_xy + box_wh / 2
bbox = tf.concat([box_x1y1, box_x2y2], axis=-1)
return bbox, score, class_probs, pred_box
ΠΠΎΠ΄Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π΅-ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌΠΎΠ²
def nonMaximumSuppression(outputs, anchors, masks, classes):
boxes, conf, out_type = [], [], []
for output in outputs:
boxes.append(tf.reshape(output[0], (tf.shape(output[0])[0], -1, tf.shape(output[0])[-1])))
conf.append(tf.reshape(output[1], (tf.shape(output[1])[0], -1, tf.shape(output[1])[-1])))
out_type.append(tf.reshape(output[2], (tf.shape(output[2])[0], -1, tf.shape(output[2])[-1])))
bbox = tf.concat(boxes, axis=1)
confidence = tf.concat(conf, axis=1)
class_probs = tf.concat(out_type, axis=1)
scores = confidence * class_probs
boxes, scores, classes, valid_detections = tf.image.combined_non_max_suppression(
boxes=tf.reshape(bbox, (tf.shape(bbox)[0], -1, 1, 4)),
scores=tf.reshape(
scores, (tf.shape(scores)[0], -1, tf.shape(scores)[-1])),
max_output_size_per_class=100,
max_total_size=100,
iou_threshold=yolo_iou_threshold,
score_threshold=yolo_score_threshold
)
return boxes, scores, classes, valid_detections
ΠΡΠ½ΠΎΠ²Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ, ΡΠΎΠ·Π΄Π°ΡΡΠ°Ρ Π²ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ:
def YoloV3(size=None, channels=3, anchors=yolo_anchors,
masks=yolo_anchor_masks, classes=80, training=False):
x = inputs = Input([size, size, channels])
x_36, x_61, x = Darknet(name='yolo_darknet')(x)
x = YoloConv(512, name='yolo_conv_0')(x)
output_0 = YoloOutput(512, len(masks[0]), classes, name='yolo_output_0')(x)
x = YoloConv(256, name='yolo_conv_1')((x, x_61))
output_1 = YoloOutput(256, len(masks[1]), classes, name='yolo_output_1')(x)
x = YoloConv(128, name='yolo_conv_2')((x, x_36))
output_2 = YoloOutput(128, len(masks[2]), classes, name='yolo_output_2')(x)
if training:
return Model(inputs, (output_0, output_1, output_2), name='yolov3')
boxes_0 = Lambda(lambda x: yolo_boxes(x, anchors[masks[0]], classes),
name='yolo_boxes_0')(output_0)
boxes_1 = Lambda(lambda x: yolo_boxes(x, anchors[masks[1]], classes),
name='yolo_boxes_1')(output_1)
boxes_2 = Lambda(lambda x: yolo_boxes(x, anchors[masks[2]], classes),
name='yolo_boxes_2')(output_2)
outputs = Lambda(lambda x: nonMaximumSuppression(x, anchors, masks, classes),
name='nonMaximumSuppression')((boxes_0[:3], boxes_1[:3], boxes_2[:3]))
return Model(inputs, outputs, name='yolov3')
Π€ΡΠ½ΠΊΡΠΈΡ ΠΏΠΎΡΠ΅ΡΡ Ρ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠΎΠΌ:
def YoloLoss(anchors, classes=80, ignore_thresh=0.5):
def yolo_loss(y_true, y_pred):
# 1. transform all pred outputs
# y_pred: (batch_size, grid, grid, anchors, (x, y, w, h, obj, ...cls))
pred_box, pred_obj, pred_class, pred_xywh = yolo_boxes(
y_pred, anchors, classes)
pred_xy = pred_xywh[..., 0:2]
pred_wh = pred_xywh[..., 2:4]
# 2. transform all true outputs
# y_true: (batch_size, grid, grid, anchors, (x1, y1, x2, y2, obj, cls))
true_box, true_obj, true_class_idx = tf.split(
y_true, (4, 1, 1), axis=-1)
true_xy = (true_box[..., 0:2] + true_box[..., 2:4]) / 2
true_wh = true_box[..., 2:4] - true_box[..., 0:2]
# give higher weights to small boxes
box_loss_scale = 2 - true_wh[..., 0] * true_wh[..., 1]
# 3. inverting the pred box equations
grid_size = tf.shape(y_true)[1]
grid = tf.meshgrid(tf.range(grid_size), tf.range(grid_size))
grid = tf.expand_dims(tf.stack(grid, axis=-1), axis=2)
true_xy = true_xy * tf.cast(grid_size, tf.float32) - \
tf.cast(grid, tf.float32)
true_wh = tf.math.log(true_wh / anchors)
true_wh = tf.where(tf.math.is_inf(true_wh),
tf.zeros_like(true_wh), true_wh)
# 4. calculate all masks
obj_mask = tf.squeeze(true_obj, -1)
# ignore false positive when iou is over threshold
true_box_flat = tf.boolean_mask(true_box, tf.cast(obj_mask, tf.bool))
best_iou = tf.reduce_max(broadcast_iou(
pred_box, true_box_flat), axis=-1)
ignore_mask = tf.cast(best_iou < ignore_thresh, tf.float32)
# 5. calculate all losses
xy_loss = obj_mask * box_loss_scale * \
tf.reduce_sum(tf.square(true_xy - pred_xy), axis=-1)
wh_loss = obj_mask * box_loss_scale * \
tf.reduce_sum(tf.square(true_wh - pred_wh), axis=-1)
obj_loss = binary_crossentropy(true_obj, pred_obj)
obj_loss = obj_mask * obj_loss + \
(1 - obj_mask) * ignore_mask * obj_loss
# TODO: use binary_crossentropy instead
class_loss = obj_mask * sparse_categorical_crossentropy(
true_class_idx, pred_class)
# 6. sum over (batch, gridx, gridy, anchors) => (batch, 1)
xy_loss = tf.reduce_sum(xy_loss, axis=(1, 2, 3))
wh_loss = tf.reduce_sum(wh_loss, axis=(1, 2, 3))
obj_loss = tf.reduce_sum(obj_loss, axis=(1, 2, 3))
class_loss = tf.reduce_sum(class_loss, axis=(1, 2, 3))
return xy_loss + wh_loss + obj_loss + class_loss
return yolo_loss
Π‘Π»Π΅Π΄ΡΡΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠΈΡΡΠ΅Ρ ΡΠ΅Π»Π΅Π²ΡΠ΅ Π²ΡΠ²ΠΎΠ΄Ρ ΠΊ ΠΊΠΎΡΡΠ΅ΠΆΡ (tuple) ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΡΠΎΡΠΌΡ:
ΠΠ΄Π΅ΡΡ N β ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΌΠ΅ΡΠΎΠΊ Π² ΠΏΠ°ΠΊΠ΅ΡΠ΅ (batch), Π° 6 ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ [x, y, w, h, obj, class] ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΡ
ΡΠ°ΠΌΠΎΠΊ.
@tf.function
def transform_targets_for_output(y_true, grid_size, anchor_idxs, classes):
N = tf.shape(y_true)[0]
y_true_out = tf.zeros(
(N, grid_size, grid_size, tf.shape(anchor_idxs)[0], 6))
anchor_idxs = tf.cast(anchor_idxs, tf.int32)
indexes = tf.TensorArray(tf.int32, 1, dynamic_size=True)
updates = tf.TensorArray(tf.float32, 1, dynamic_size=True)
idx = 0
for i in tf.range(N):
for j in tf.range(tf.shape(y_true)[1]):
if tf.equal(y_true[i][j][2], 0):
continue
anchor_eq = tf.equal(
anchor_idxs, tf.cast(y_true[i][j][5], tf.int32))
if tf.reduce_any(anchor_eq):
box = y_true[i][j][0:4]
box_xy = (y_true[i][j][0:2] + y_true[i][j][2:4]) / 2
anchor_idx = tf.cast(tf.where(anchor_eq), tf.int32)
grid_xy = tf.cast(box_xy // (1/grid_size), tf.int32)
indexes = indexes.write(
idx, [i, grid_xy[1], grid_xy[0], anchor_idx[0][0]])
updates = updates.write(
idx, [box[0], box[1], box[2], box[3], 1, y_true[i][j][4]])
idx += 1
return tf.tensor_scatter_nd_update(
y_true_out, indexes.stack(), updates.stack())
def transform_targets(y_train, anchors, anchor_masks, classes):
outputs = []
grid_size = 13
anchors = tf.cast(anchors, tf.float32)
anchor_area = anchors[..., 0] * anchors[..., 1]
box_wh = y_train[..., 2:4] - y_train[..., 0:2]
box_wh = tf.tile(tf.expand_dims(box_wh, -2),
(1, 1, tf.shape(anchors)[0], 1))
box_area = box_wh[..., 0] * box_wh[..., 1]
intersection = tf.minimum(box_wh[..., 0], anchors[..., 0]) * \
tf.minimum(box_wh[..., 1], anchors[..., 1])
iou = intersection / (box_area + anchor_area - intersection)
anchor_idx = tf.cast(tf.argmax(iou, axis=-1), tf.float32)
anchor_idx = tf.expand_dims(anchor_idx, axis=-1)
y_train = tf.concat([y_train, anchor_idx], axis=-1)
for anchor_idxs in anchor_masks:
outputs.append(transform_targets_for_output(
y_train, grid_size, anchor_idxs, classes))
grid_size *= 2
return tuple(outputs) # [x, y, w, h, obj, class]
def preprocess_image(x_train, size):
return (tf.image.resize(x_train, (size, size))) / 255
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Π½Π°ΡΠ΅ΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ Π²Π΅ΡΠ° ΠΈ ΠΈΠΌΠ΅Π½Π° ΠΊΠ»Π°ΡΡΠΎΠ². Π Π΄Π°ΡΠ°ΡΠ΅ΡΠ΅ COCO ΠΈΡ 80.
yolo = YoloV3(classes=num_classes)
load_darknet_weights(yolo, weightsyolov3)
yolo.save_weights(checkpoints)
class_names = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck",
"boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench",
"bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe",
"backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard",
"sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
"tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl",
"banana","apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut",
"cake","chair", "sofa", "pottedplant", "bed", "diningtable", "toilet", "tvmonitor", "laptop",
"mouse","remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink",
"refrigerator","book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"]
ΠΠΎΡ ΠΈ Π²ΡΠ΅! ΠΡΡΠΌΠΎ ΡΠ΅ΠΉΡΠ°Ρ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ Π½Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π° ΠΊΠ°ΠΊΠΎΠΌ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ.

name = 'detect.jpg'
img = tf.image.decode_image(open(name, 'rb').read(), channels=3)
img = tf.expand_dims(img, 0)
img = preprocess_image(img, size)
boxes, scores, classes, nums = yolo(img) #eager mode
img = cv2.imread(name)
img = draw_outputs(img, (boxes, scores, classes, nums), class_names)
cv2.imwrite('output.jpg', img)
ΠΠΎΡΠ»Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π² ΡΠ°ΠΉΠ»Π΅ output.jpg ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ ΡΠΎ ΠΆΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Ρ ΡΠ°ΠΌΠΊΠ°ΠΌΠΈ, ΠΎΡΠΌΠ΅ΡΠ°ΡΡΠΈΠΌΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ, ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡΠ΅ Π½Π°ΡΠ΅ΠΉ Π½Π΅ΠΉΡΠΎΠ½Π½ΠΎΠΉ ΡΠ΅ΡΡΡ:

Π Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ Π²ΠΈΠ΄Π΅ΠΎ Ρ ΠΊΠ°ΠΌΠ΅ΡΡ
ΠΡ ΡΠΆΠ΅ Π΄ΠΎΠ±ΠΈΠ»ΠΈΡΡ Π²ΠΏΠ΅ΡΠ°ΡΠ»ΡΡΡΠ΅Π³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°, Π½ΠΎ Π³Π»Π°Π²Π½ΠΎΠ΅ Π΅ΡΠ΅ Π²ΠΏΠ΅ΡΠ΅Π΄ΠΈ! Π‘Π°ΠΌΠΎΠ΅ Π²Π°ΠΆΠ½ΠΎΠ΅ Π² Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ΅ YOLO Π½Π΅ ΡΠΎ, ΡΡΠΎ ΠΎΠ½Π° Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ Π½Π΅ΠΏΠ»ΠΎΡ
ΠΎ ΡΠΌΠ΅Π΅Ρ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ, Π° ΡΠΎ, ΡΡΠΎ ΠΎΠ½Π° Π΄Π΅Π»Π°Π΅Ρ ΡΡΠΎ Π±ΡΡΡΡΠΎ. ΠΠ°ΡΡΠΎΠ»ΡΠΊΠΎ Π±ΡΡΡΡΠΎ, ΡΡΠΎ ΡΡΠΏΠ΅Π²Π°Π΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ Π²ΡΠ΅ ΠΊΠ°Π΄ΡΡ, ΠΏΠΎΡΡΡΠΏΠ°ΡΡΠΈΠ΅ ΠΎΡ Π²Π΅Π±-ΠΊΠ°ΠΌΠ΅ΡΡ. ΠΠΊΠ»ΡΡΠΈΡΠ΅ Π²Π΅Π±-ΠΊΠ°ΠΌΠ΅ΡΡ ΠΈ Π·Π°ΠΏΡΡΡΠΈΡΠ΅ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄:
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
#img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = tf.expand_dims(frame, 0)
img = preprocess_image(img, size)
boxes, scores, classes, nums = yolo(img) #eager mode
img = draw_outputs(frame, (boxes, scores, classes, nums), class_names)
# Display the resulting frame
cv2.imshow('frame',img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
ΠΡ ΡΠ²ΠΈΠ΄ΠΈΡΠ΅ Π½Π° ΡΠΊΡΠ°Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΡΡΡΡ ΠΊΠ°ΡΡΠΈΠ½ΠΊΡ Ρ ΠΊΠ°ΠΌΠ΅ΡΡ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ΄ΡΡ ΠΎΡΠΌΠ΅ΡΠ΅Π½Ρ Π²ΡΠ΅ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π½Π½ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ. Π’Π΅ΠΏΠ΅ΡΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ°ΡΡ ΡΠ²ΠΎΡ ΠΊΠ°ΠΌΠ΅ΡΡ ΠΈΠ»ΠΈ Π΄Π²ΠΈΠ³Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π² ΠΊΠ°Π΄ΡΠ΅, ΠΈ Π½Π΅ΠΉΡΠΎΠ½Π½Π°Ρ ΡΠ΅ΡΡ Π±ΡΠ΄Π΅Ρ ΡΡΠΏΠ΅Π²Π°ΡΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΌΠ΅Π½ΡΡΡΠΈΠ΅ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ.
ΠΠ΅Π»Π°Ρ ΡΠ΄Π°ΡΠ½ΡΡ
ΠΈ Π·Π°Π±Π°Π²Π½ΡΡ
ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΎΠ² Ρ YOLO!
Π‘ΡΡΠ»ΠΊΠΈ:
ΠΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ
Π Π΅Π±ΡΡ, ΡΡΠΎ ΡΠΊΠ°ΠΆΠ΅ΡΠ΅ ΡΡΡΠ°ΡΠ΅Π»Π° Π»ΠΈ ΡΡΠ°ΡΡΡ, ΡΡΠΎΠΈΡ ΡΠΈΡΠ°ΡΡ ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΡ ΡΠ΅ΡΠ°ΡΡ?
ΠΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π²ΡΠ΄Π°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΡ: NameError: name 'yolo_anchors' is not defined
Π’ΡΡΠ΄Π½ΠΎ Π±ΡΠ»ΠΎ ΠΎΡΡΠ°Π²ΠΈΡΡ ΡΠΆΠ΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π³ΠΎΡΠΎΠ²ΡΠΉ ΠΈ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΉ ΠΊΠΎΠ΄ Π² ΠΊΠΎΠ½ΡΠ΅...
Π€Π°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΡΠ»ΠΊΠ° Π½Π° GitHub-ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ Yolo v3 Π½Π° TensorFlow ΡΠΆΠ΅ Π΅ΡΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ ΡΡΠ°ΡΡΠΈ Π² ΡΠ°Π·Π΄Π΅Π»Π΅ "ΡΡΡΠ»ΠΊΠΈ" -- https://github.com/zzh8829/yolov3-tf2. Π’Π°ΠΊ ΠΏΡΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΡΡΡΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ, ΠΊΠ°ΠΊ Π²ΡΡ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ.
Π ΠΊΠΎΠ΄ Π² ΡΡΠ°ΡΡΠ΅ ΡΠ°Π·Π΄Π΅Π»Π΅Π½, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π΅Π³ΠΎ ΠΏΠΈΡΠ°Π»ΠΈ ΡΠ°Π·Π½ΡΠ΅ Π»ΡΠ΄ΠΈ -- Π±ΡΠ»ΠΎ Π±Ρ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡ Π΅Π³ΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅, ΠΊΠ°ΠΊ ΠΎΠ±ΡΠΈΠΉ.