Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ
Π’ΠΎ ΠΎΠ²Π°Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π°, ќС Π²ΠΈ ΠΊΠ°ΠΆΠ°ΠΌ ΠΊΠ°ΠΊΠΎ Π΄Π° поставитС срСдина Π·Π° машинско ΡƒΡ‡Π΅ΡšΠ΅ Π·Π° 30 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ, Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ нСвронска ΠΌΡ€Π΅ΠΆΠ° Π·Π° ΠΏΡ€Π΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡšΠ΅ слики ΠΈ ΠΏΠΎΡ‚ΠΎΠ° Π΄Π° ја стартуватС истата ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсор (GPU).

ΠŸΡ€Π²ΠΎ, Π΄Π° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ ΡˆΡ‚ΠΎ Π΅ нСвронска ΠΌΡ€Π΅ΠΆΠ°.

Π’ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΡΠ»ΡƒΡ‡Π°Ρ˜, ΠΎΠ²Π° Π΅ ΠΌΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΡ‡ΠΊΠΈ ΠΌΠΎΠ΄Π΅Π», ΠΊΠ°ΠΊΠΎ ΠΈ Π½Π΅Π³ΠΎΠ²ΠΎ софтвСрско ΠΈΠ»ΠΈ хардвСрско ΠΎΡ‚Π΅Π»ΠΎΡ‚Π²ΠΎΡ€ΡƒΠ²Π°ΡšΠ΅, ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½ΠΎ Π²Ρ€Π· ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΡ‚ Π½Π° ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π° ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π°ΡšΠ΅ Π½Π° Π±ΠΈΠΎΠ»ΠΎΡˆΠΊΠΈΡ‚Π΅ нСвронски ΠΌΡ€Π΅ΠΆΠΈ - ΠΌΡ€Π΅ΠΆΠΈ Π½Π° Π½Π΅Ρ€Π²Π½ΠΈ ΠΊΠ»Π΅Ρ‚ΠΊΠΈ Π½Π° ΠΆΠΈΠ² ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°ΠΌ. Овој ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ сС појави Π΄ΠΎΠ΄Π΅ΠΊΠ° Π³ΠΈ ΠΏΡ€ΠΎΡƒΡ‡ΡƒΠ²Π°ΡˆΠ΅ процСситС ΡˆΡ‚ΠΎ сС случуваат Π²ΠΎ ΠΌΠΎΠ·ΠΎΠΊΠΎΡ‚ ΠΈ сС ΠΎΠ±ΠΈΠ΄ΡƒΠ²Π°ΡˆΠ΅ Π΄Π° Π³ΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈΡ€Π° ΠΎΠ²ΠΈΠ΅ процСси.

НСвронскитС ΠΌΡ€Π΅ΠΆΠΈ Π½Π΅ сС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½ΠΈ Π²ΠΎ Π²ΠΎΠΎΠ±ΠΈΡ‡Π°Π΅Π½Π°Ρ‚Π° смисла Π½Π° Π·Π±ΠΎΡ€ΠΎΡ‚, Ρ‚ΠΈΠ΅ сС ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈ. Бпособноста Π·Π° ΡƒΡ‡Π΅ΡšΠ΅ Π΅ Π΅Π΄Π½Π° ΠΎΠ΄ Π³Π»Π°Π²Π½ΠΈΡ‚Π΅ прСдности Π½Π° нСвронскитС ΠΌΡ€Π΅ΠΆΠΈ Π²ΠΎ однос Π½Π° Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π°Π»Π½ΠΈΡ‚Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΈ. Π’Π΅Ρ…Π½ΠΈΡ‡ΠΊΠΈ, ΡƒΡ‡Π΅ΡšΠ΅Ρ‚ΠΎ сС состои ΠΎΠ΄ ΠΏΡ€ΠΎΠ½Π°ΠΎΡ“Π°ΡšΠ΅ Π½Π° ΠΊΠΎΠ΅Ρ„ΠΈΡ†ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° врски ΠΏΠΎΠΌΠ΅Ρ“Ρƒ Π½Π΅Π²Ρ€ΠΎΠ½ΠΈΡ‚Π΅. Π—Π° Π²Ρ€Π΅ΠΌΠ΅ Π½Π° процСсот Π½Π° ΠΎΠ±ΡƒΠΊΠ°, нСвронската ΠΌΡ€Π΅ΠΆΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΡƒΠ²Π° слоТСни зависности ΠΏΠΎΠΌΠ΅Ρ“Ρƒ Π²Π»Π΅Π·Π½ΠΈΡ‚Π΅ ΠΈ ΠΈΠ·Π»Π΅Π·Π½ΠΈΡ‚Π΅ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, ΠΊΠ°ΠΊΠΎ ΠΈ Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΠΈ Π³Π΅Π½Π΅Ρ€Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡ˜Π°.

Од Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° ΠΌΠ°ΡˆΠΈΠ½ΡΠΊΠΎΡ‚ΠΎ ΡƒΡ‡Π΅ΡšΠ΅, нСвронската ΠΌΡ€Π΅ΠΆΠ° Π΅ посСбСн ΡΠ»ΡƒΡ‡Π°Ρ˜ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° ΠΏΡ€Π΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡšΠ΅ шаблони, дискриминантна Π°Π½Π°Π»ΠΈΠ·Π°, ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π½Π° ΠΊΠ»Π°ΡΡ‚Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ.

ΠžΠ±ΠΎΡ€ΡƒΠ΄ΠΎΠ²Π°Π½ΠΈΠ΅

ΠŸΡ€Π²ΠΎ, Π΄Π° ја Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΎΠΏΡ€Π΅ΠΌΠ°Ρ‚Π°. ΠŸΠΎΡ‚Ρ€Π΅Π±Π΅Π½ Π½ΠΈ Π΅ сСрвСр со инсталиран ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π΅Π½ систСм Linux Π½Π° Π½Π΅Π³ΠΎ. ΠžΠΏΡ€Π΅ΠΌΠ°Ρ‚Π° ΠΏΠΎΡ‚Ρ€Π΅Π±Π½Π° Π·Π° ΡƒΠΏΡ€Π°Π²ΡƒΠ²Π°ΡšΠ΅ со систСмитС Π·Π° машинско ΡƒΡ‡Π΅ΡšΠ΅ Π΅ ΠΏΡ€ΠΈΠ»ΠΈΡ‡Π½ΠΎ моќна ΠΈ, ΠΊΠ°ΠΊΠΎ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ°, скапа. Π—Π° ΠΎΠ½ΠΈΠ΅ ΠΊΠΎΠΈ Π½Π΅ΠΌΠ°Π°Ρ‚ Π΄ΠΎΠ±Ρ€Π° машина ΠΏΡ€ΠΈ Ρ€Π°ΠΊΠ°, ΠΏΡ€Π΅ΠΏΠΎΡ€Π°Ρ‡ΡƒΠ²Π°ΠΌ Π΄Π° ΠΎΠ±Ρ€Π½Π°Ρ‚ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ½ΡƒΠ΄ΠΈΡ‚Π΅ Π½Π° Π΄Π°Π²Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ Π½Π° ΠΎΠ±Π»Π°ΠΊ. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π±Ρ€Π·ΠΎ Π΄Π° Π³ΠΎ ΠΈΠ·Π½Π°Ρ˜ΠΌΠΈΡ‚Π΅ Π±Π°Ρ€Π°Π½ΠΈΠΎΡ‚ сСрвСр ΠΈ Π΄Π° ΠΏΠ»Π°ΡœΠ°Ρ‚Π΅ само Π·Π° Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅.

Π’ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ ΠΊΠ°Π΄Π΅ ΡˆΡ‚ΠΎ Π΅ Π½Π΅ΠΎΠΏΡ…ΠΎΠ΄Π½ΠΎ Π΄Π° сС создадат нСвронски ΠΌΡ€Π΅ΠΆΠΈ, Π³ΠΈ користам сСрвСритС Π½Π° Π΅Π΄Π΅Π½ ΠΎΠ΄ рускитС ΠΏΡ€ΠΎΠ²Π°Ρ˜Π΄Π΅Ρ€ΠΈ Π½Π° ΠΎΠ±Π»Π°ΠΊ. ΠšΠΎΠΌΠΏΠ°Π½ΠΈΡ˜Π°Ρ‚Π° Π½ΡƒΠ΄ΠΈ ΠΎΠ±Π»Π°ΠΊ сСрвСри Π·Π° ΠΈΠ·Π½Π°Ρ˜ΠΌΡƒΠ²Π°ΡšΠ΅ ΡΠΏΠ΅Ρ†ΠΈΡ˜Π°Π»Π½ΠΎ Π·Π° машинско ΡƒΡ‡Π΅ΡšΠ΅ со моќни Tesla V100 Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсори (GPU) ΠΎΠ΄ NVIDIA. Накратко: ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅Ρ‚ΠΎ сСрвСр со Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсор ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅ дСсСтици ΠΏΠ°Ρ‚ΠΈ поСфикасно (Π±Ρ€Π·ΠΎ) Π²ΠΎ спорСдба со сСрвСр со слична Ρ†Π΅Π½Π° ΡˆΡ‚ΠΎ користи процСсор (Π΄ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠ·Π½Π°Ρ‚Π° Ρ†Π΅Π½Ρ‚Ρ€Π°Π»Π½Π° процСсорска Π΅Π΄ΠΈΠ½ΠΈΡ†Π°) Π·Π° прСсмСтки. Ова сС постигнува ΠΏΠΎΡ€Π°Π΄ΠΈ карактСристикитС Π½Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор, која ΠΏΠΎΠ±Ρ€Π·ΠΎ сС справува со прСсмСткитС.

Π—Π° Π΄Π° Π³ΠΈ ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°ΠΌΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅ опишани ΠΏΠΎΠ΄ΠΎΠ»Ρƒ, Π³ΠΎ ΠΊΡƒΠΏΠΈΠ²ΠΌΠ΅ слСдниов сСрвСр Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ Π΄Π΅Π½Π°:

  • SSD диск 150 GB
  • RAM ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π° 32 GB
  • Tesla V100 16 Gb процСсор со 4 Ρ˜Π°Π΄Ρ€Π°

Π“ΠΎ инсталиравмС Ubuntu 18.04 Π½Π° Π½Π°ΡˆΠ°Ρ‚Π° машина.

ΠŸΠΎΡΡ‚Π°Π²ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΎΠΊΠΎΠ»ΠΈΠ½Π°Ρ‚Π°

Π‘Π΅Π³Π° ајдС Π΄Π° инсталирамС сè ΡˆΡ‚ΠΎ Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° сСрвСрот. Π‘ΠΈΠ΄Π΅Ρ˜ΡœΠΈ Π½Π°ΡˆΠ°Ρ‚Π° ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° Π΅ првСнствСно Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ, ќС Π·Π±ΠΎΡ€ΡƒΠ²Π°ΠΌ Π·Π° Π½Π΅ΠΊΠΎΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ ΡˆΡ‚ΠΎ ќС ΠΈΠΌ Π±ΠΈΠ΄Π°Ρ‚ корисни.

Π“ΠΎΠ»Π΅ΠΌ Π΄Π΅Π» ΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΡΡ‚Π°Π²ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΎΠΊΠΎΠ»ΠΈΠ½Π°Ρ‚Π° сС Π²Ρ€ΡˆΠΈ ΠΏΡ€Π΅ΠΊΡƒ ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°Ρ‚Π° линија. ΠŸΠΎΠ²Π΅ΡœΠ΅Ρ‚ΠΎ ΠΎΠ΄ корисницитС користат Windows ΠΊΠ°ΠΊΠΎ Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π΅Π½ систСм. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Π΄Π½Π°Ρ‚Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π° Π²ΠΎ овој ОБ остава ΠΌΠ½ΠΎΠ³Ρƒ Π΄Π° сС посакува. Π—Π°Ρ‚ΠΎΠ°, ќС користимС ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½Π° Π°Π»Π°Ρ‚ΠΊΠ° Cmder/. ΠŸΡ€Π΅Π·Π΅ΠΌΠ΅Ρ‚Π΅ ја ΠΌΠΈΠ½ΠΈ Π²Π΅Ρ€Π·ΠΈΡ˜Π°Ρ‚Π° ΠΈ ΡΡ‚Π°Ρ€Ρ‚ΡƒΠ²Π°Ρ˜Ρ‚Π΅ Cmder.exe. Π‘Π»Π΅Π΄Π½ΠΎ, Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС ΠΏΠΎΠ²Ρ€Π·Π΅Ρ‚Π΅ со сСрвСрот ΠΏΡ€Π΅ΠΊΡƒ SSH:

ssh root@server-ip-or-hostname

НамСсто ΠΈΠΌΠ΅ Π½Π° сСрвСр-ip-ΠΈΠ»ΠΈ-домаќин, Π½Π°Π²Π΅Π΄Π΅Ρ‚Π΅ ја IP адрСсата ΠΈΠ»ΠΈ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° DNS Π½Π° Π²Π°ΡˆΠΈΠΎΡ‚ сСрвСр. Π‘Π»Π΅Π΄Π½ΠΎ, внСсСтС ја Π»ΠΎΠ·ΠΈΠ½ΠΊΠ°Ρ‚Π° ΠΈ Π°ΠΊΠΎ врската Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½Π°, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π΄ΠΎΠ±ΠΈΠ΅ΠΌΠ΅ слична ΠΏΠΎΡ€Π°ΠΊΠ° Π½Π° ΠΎΠ²Π°Π°.

Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-74-generic x86_64)

Π“Π»Π°Π²Π½ΠΈΠΎΡ‚ јазик Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜ Π½Π° ML ΠΌΠΎΠ΄Π΅Π»ΠΈ Π΅ Python. И Π½Π°Ρ˜ΠΏΠΎΠΏΡƒΠ»Π°Ρ€Π½Π°Ρ‚Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° Π·Π° нСјзина ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π½Π° Linux Π΅ Π°Π½Π°ΠΊΠΎΠ½Π΄Π°.

АјдС Π΄Π° Π³ΠΎ инсталирамС Π½Π° Π½Π°ΡˆΠΈΠΎΡ‚ сСрвСр.

Π—Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π°ΠΌΠ΅ со Π°ΠΆΡƒΡ€ΠΈΡ€Π°ΡšΠ΅ Π½Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈΠΎΡ‚ ΠΌΠ΅Π½Π°ΡŸΠ΅Ρ€ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ:

sudo apt-get update

Π˜Π½ΡΡ‚Π°Π»ΠΈΡ€Π°Ρ˜Ρ‚Π΅ curl (услуТна Π°Π»Π°Ρ‚ΠΊΠ° Π·Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½Π° линија):

sudo apt-get install curl

ΠŸΡ€Π΅Π·Π΅ΠΌΠ΅Ρ‚Π΅ ја Π½Π°Ρ˜Π½ΠΎΠ²Π°Ρ‚Π° Π²Π΅Ρ€Π·ΠΈΡ˜Π° Π½Π° Anaconda Distribution:

cd /tmp
curl –O https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh

Π”Π° ја Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ ΠΈΠ½ΡΡ‚Π°Π»Π°Ρ†ΠΈΡ˜Π°Ρ‚Π°:

bash Anaconda3-2019.10-Linux-x86_64.sh

Π—Π° Π²Ρ€Π΅ΠΌΠ΅ Π½Π° процСсот Π½Π° ΠΈΠ½ΡΡ‚Π°Π»Π°Ρ†ΠΈΡ˜Π°, ќС Π±ΠΈΠ΄Π΅ ΠΏΠΎΠ±Π°Ρ€Π°Π½ΠΎ Π΄Π° Π³ΠΎ ΠΏΠΎΡ‚Π²Ρ€Π΄ΠΈΡ‚Π΅ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΎΡ‚ Π·Π° Π»ΠΈΡ†Π΅Π½Ρ†Π°. По ΡƒΡΠΏΠ΅ΡˆΠ½Π° ΠΈΠ½ΡΡ‚Π°Π»Π°Ρ†ΠΈΡ˜Π°, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΎΠ²Π°:

Thank you for installing Anaconda3!

Π‘Π΅Π³Π° сС создадСни ΠΌΠ½ΠΎΠ³Ρƒ Ρ€Π°ΠΌΠΊΠΈ Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜ Π½Π° ML ΠΌΠΎΠ΄Π΅Π»ΠΈ со ΠΊΠΎΠΈ Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ Π½Π°Ρ˜ΠΏΠΎΠΏΡƒΠ»Π°Ρ€Π½ΠΈΡ‚Π΅: PyTorch ΠΈ ΠŸΡ€ΠΎΡ‚ΠΎΠΊ Π½Π° Ρ‚Π΅Π½Π·ΠΎΡ€.

ΠšΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅Ρ‚ΠΎ Π½Π° Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ја Π·Π³ΠΎΠ»Π΅ΠΌΠΈΡ‚Π΅ Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° Ρ€Π°Π·Π²ΠΎΡ˜ ΠΈ Π΄Π° користитС Π³ΠΎΡ‚ΠΎΠ²ΠΈ Π°Π»Π°Ρ‚ΠΊΠΈ Π·Π° стандардни Π·Π°Π΄Π°Ρ‡ΠΈ.

Π’ΠΎ овој ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ќС Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌΠ΅ со PyTorch. АјдС Π΄Π° Π³ΠΎ инсталирамС:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Π‘Π΅Π³Π° Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π³ΠΎ лансирамС Jupyter Notebook, ΠΏΠΎΠΏΡƒΠ»Π°Ρ€Π½Π° Π°Π»Π°Ρ‚ΠΊΠ° Π·Π° Ρ€Π°Π·Π²ΠΎΡ˜ Π·Π° ΡΠΏΠ΅Ρ†ΠΈΡ˜Π°Π»ΠΈΡΡ‚ΠΈ Π·Π° ML. Π’ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΊΠΎΠ΄ ΠΈ вСднаш Π΄Π° Π³ΠΈ Π²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ ΠΎΠ΄ Π½Π΅Π³ΠΎΠ²ΠΎΡ‚ΠΎ ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅. Jupyter Notebook Π΅ Π²ΠΊΠ»ΡƒΡ‡Π΅Π½ Π²ΠΎ Anaconda ΠΈ Π΅ вСќС инсталиран Π½Π° Π½Π°ΡˆΠΈΠΎΡ‚ сСрвСр. Π’Ρ€Π΅Π±Π° Π΄Π° сС ΠΏΠΎΠ²Ρ€Π·Π΅Ρ‚Π΅ со Π½Π΅Π³ΠΎ ΠΎΠ΄ Π½Π°ΡˆΠΈΠΎΡ‚ дСсктоп систСм.

Π—Π° Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ ΠΎΠ²Π°, ΠΏΡ€Π²ΠΎ ќС Π³ΠΎ стартувамС Jupyter Π½Π° сСрвСрот ΡˆΡ‚ΠΎ ја ΠΎΠ΄Ρ€Π΅Π΄ΡƒΠ²Π° ΠΏΠΎΡ€Ρ‚Π°Ρ‚Π° 8080:

jupyter notebook --no-browser --port=8080 --allow-root

Π‘Π»Π΅Π΄Π½ΠΎ, ΠΎΡ‚Π²ΠΎΡ€Π°Ρ˜ΡœΠΈ Π΄Ρ€ΡƒΠ³ΠΎ Ρ˜Π°Π·ΠΈΡ‡Π΅ Π²ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° Cmder ΠΊΠΎΠ½Π·ΠΎΠ»Π° (Π³ΠΎΡ€Π½ΠΎΡ‚ΠΎ ΠΌΠ΅Π½ΠΈ - Π”ΠΈΡ˜Π°Π»ΠΎΠ³ Π·Π° Π½ΠΎΠ²Π° ΠΊΠΎΠ½Π·ΠΎΠ»Π°) ќС сС ΠΏΠΎΠ²Ρ€Π·Π΅ΠΌΠ΅ ΠΏΡ€Π΅ΠΊΡƒ ΠΏΠΎΡ€Ρ‚Π°Ρ‚Π° 8080 со сСрвСрот ΠΏΡ€Π΅ΠΊΡƒ SSH:

ssh -L 8080:localhost:8080 root@server-ip-or-hostname

Кога ќС ја внСсСмС ΠΏΡ€Π²Π°Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°, ќС Π½ΠΈ Π±ΠΈΠ΄Π°Ρ‚ ΠΏΠΎΠ½ΡƒΠ΄Π΅Π½ΠΈ врски Π·Π° ΠΎΡ‚Π²ΠΎΡ€Π°ΡšΠ΅ Π½Π° Jupyter Π²ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ прСлистувач:

To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-18788-open.html
    Or copy and paste one of these URLs:
        http://localhost:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311
     or http://127.0.0.1:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311

АјдС Π΄Π° ја искористимС врската Π·Π° localhost:8080. ΠšΠΎΠΏΠΈΡ€Π°Ρ˜Ρ‚Π΅ ја цСлосната ΠΏΠ°Ρ‚Π΅ΠΊΠ° ΠΈ Π·Π°Π»Π΅ΠΏΠ΅Ρ‚Π΅ ја Π²ΠΎ Π»Π΅Π½Ρ‚Π°Ρ‚Π° Π·Π° адрСси Π½Π° Π»ΠΎΠΊΠ°Π»Π½ΠΈΠΎΡ‚ прСлистувач Π½Π° Π²Π°ΡˆΠΈΠΎΡ‚ ΠΊΠΎΠΌΠΏΡ˜ΡƒΡ‚Π΅Ρ€. ЌС сС ΠΎΡ‚Π²ΠΎΡ€ΠΈ Jupyter Notebook.

АјдС Π΄Π° создадСмС Π½ΠΎΠ²Π° Ρ‚Π΅Ρ‚Ρ€Π°Ρ‚ΠΊΠ°: Ново - Π‘Π΅Π»Π΅ΠΆΠ½ΠΈΠΊ - ΠŸΠ°Ρ˜Ρ‚ΠΎΠ½ 3.

АјдС Π΄Π° ја ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π½Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° ситС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ ΡˆΡ‚ΠΎ Π³ΠΈ инсталиравмС. АјдС Π΄Π° Π³ΠΎ внСсСмС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΡ‚ PyTorch ΠΊΠΎΠ΄ Π²ΠΎ Jupyter ΠΈ Π΄Π° Π³ΠΎ ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠ΅ ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ (ΠΊΠΎΠΏΡ‡Π΅ Run):

from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)

Π Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΎΡ‚ Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π±ΠΈΠ΄Π΅ Π½Π΅ΡˆΡ‚ΠΎ Π²Π°ΠΊΠ°:

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Ако ΠΈΠΌΠ°Ρ‚Π΅ сличСн Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚, Ρ‚ΠΎΠ³Π°Ρˆ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π²ΠΌΠ΅ сè ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ ΠΈ ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ Π΄Π° Ρ€Π°Π·Π²ΠΈΠ²Π°ΠΌΠ΅ нСвронска ΠΌΡ€Π΅ΠΆΠ°!

БоздавањС нСвронска ΠΌΡ€Π΅ΠΆΠ°

ЌС создадСмС нСвронска ΠΌΡ€Π΅ΠΆΠ° Π·Π° ΠΏΡ€Π΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡšΠ΅ слики. Π”Π° Π³ΠΎ Π·Π΅ΠΌΠ΅ΠΌΠ΅ ΠΎΠ²Π° ΠΊΠ°ΠΊΠΎ основа лидСрство.

Π—Π° Π΄Π° ја ΠΎΠ±ΡƒΡ‡ΠΈΠΌΠ΅ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°, ќС ја користимС јавно достапната Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ CIFAR10. Има класи: β€žΠ°Π²ΠΈΠΎΠ½β€œ, β€žΠ°Π²Ρ‚ΠΎΠΌΠΎΠ±ΠΈΠ»β€œ, β€žΠΏΡ‚ΠΈΡ†Π°β€œ, β€žΠΌΠ°Ρ‡ΠΊΠ°β€œ, β€žΠ΅Π»Π΅Π½β€œ, β€žΠΊΡƒΡ‡Π΅β€œ, β€žΠΆΠ°Π±Π°β€œ, β€žΠΊΠΎΡšβ€œ, β€žΠ±Ρ€ΠΎΠ΄β€œ, β€žΠΊΠ°ΠΌΠΈΠΎΠ½β€œ. Π‘Π»ΠΈΠΊΠΈΡ‚Π΅ Π²ΠΎ CIFAR10 сС 3x32x32, односно 3-ΠΊΠ°Π½Π°Π»Π½ΠΈ слики Π²ΠΎ боја ΠΎΠ΄ 32x32 пиксСли.

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ
Π—Π° Ρ€Π°Π±ΠΎΡ‚Π°, ќС Π³ΠΎ користимС ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΡ‚ создадСн ΠΎΠ΄ PyTorch Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° со слики - torchvision.

ЌС Π³ΠΈ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ слСднитС Ρ‡Π΅ΠΊΠΎΡ€ΠΈ ΠΏΠΎ рСдослСд:

  • Π’Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅ Π½Π° Π·Π±ΠΈΡ€ΠΊΠΈΡ‚Π΅ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π·Π° ΠΎΠ±ΡƒΠΊΠ° ΠΈ Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅
  • Π”Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π° Π½Π° нСвронска ΠΌΡ€Π΅ΠΆΠ°
  • ΠœΡ€Π΅ΠΆΠ½Π° ΠΎΠ±ΡƒΠΊΠ° Π·Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π·Π° ΠΎΠ±ΡƒΠΊΠ°
  • ΠœΡ€Π΅ΠΆΠ½ΠΎ Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ ΠΎΠ΄ тСстот
  • АјдС Π΄Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΠΌΠ΅ ΠΎΠ±ΡƒΠΊΠ° ΠΈ Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсор

ЌС Π³ΠΎ ΠΈΠ·Π²Ρ€ΡˆΠΈΠΌΠ΅ Ρ†Π΅Π»ΠΈΠΎΡ‚ ΠΊΠΎΠ΄ ΠΏΠΎΠ΄ΠΎΠ»Ρƒ Π²ΠΎ Jupyter Notebook.

Π’Ρ‡ΠΈΡ‚ΡƒΠ²Π°ΡšΠ΅ ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅ Π½Π° CIFAR10

ΠšΠΎΠΏΠΈΡ€Π°Ρ˜Ρ‚Π΅ Π³ΠΎ ΠΈ ΡΡ‚Π°Ρ€Ρ‚ΡƒΠ²Π°Ρ˜Ρ‚Π΅ Π³ΠΎ слСдниов ΠΊΠΎΠ΄ Π²ΠΎ Jupyter:


import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

ΠžΠ΄Π³ΠΎΠ²ΠΎΡ€ΠΎΡ‚ Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π±ΠΈΠ΄Π΅:

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz
Extracting ./data/cifar-10-python.tar.gz to ./data
Files already downloaded and verified

АјдС Π΄Π° ΠΏΡ€ΠΈΠΊΠ°ΠΆΠ΅ΠΌΠ΅ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ слики Π·Π° ΠΎΠ±ΡƒΠΊΠ° Π·Π° Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅:


import matplotlib.pyplot as plt
import numpy as np

# functions to show an image

def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()

# show images
imshow(torchvision.utils.make_grid(images))
# print labels
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π”Π΅Ρ„ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π° Π½Π° нСвронска ΠΌΡ€Π΅ΠΆΠ°

АјдС ΠΏΡ€Π²ΠΎ Π΄Π° размислимС ΠΊΠ°ΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° нСвронската ΠΌΡ€Π΅ΠΆΠ° Π·Π° ΠΏΡ€Π΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡšΠ΅ слики. Ова Π΅ Сдноставна ΠΌΡ€Π΅ΠΆΠ° ΠΎΠ΄ Ρ‚ΠΎΡ‡ΠΊΠ° Π΄ΠΎ Ρ‚ΠΎΡ‡ΠΊΠ°. Π“ΠΈ Π·Π΅ΠΌΠ° Π²Π»Π΅Π·Π½ΠΈΡ‚Π΅ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ, Π³ΠΈ ΠΏΠΎΠΌΠΈΠ½ΡƒΠ²Π° Π½ΠΈΠ· Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ слоСви Π΅Π΄Π΅Π½ ΠΏΠΎ Π΅Π΄Π΅Π½, Π° ΠΏΠΎΡ‚ΠΎΠ° ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄ΡƒΠ²Π° ΠΈΠ·Π»Π΅Π·Π½ΠΈ ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ.

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

АјдС Π΄Π° создадСмС слична ΠΌΡ€Π΅ΠΆΠ° Π²ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° ΠΎΠΊΠΎΠ»ΠΈΠ½Π°:


import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()

НиС, исто Ρ‚Π°ΠΊΠ°, Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π° Π·Π° Π·Π°Π³ΡƒΠ±Π° ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ‚ΠΎΡ€


import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

ΠœΡ€Π΅ΠΆΠ½Π° ΠΎΠ±ΡƒΠΊΠ° Π·Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π·Π° ΠΎΠ±ΡƒΠΊΠ°

Π”Π° ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ Π΄Π° ја Ρ‚Ρ€Π΅Π½ΠΈΡ€Π°ΠΌΠ΅ Π½Π°ΡˆΠ°Ρ‚Π° нСвронска ΠΌΡ€Π΅ΠΆΠ°. Π’Π΅ ΠΌΠΎΠ»ΠΈΠΌΠ΅ ΠΈΠΌΠ°Ρ˜Ρ‚Π΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ Π΄Π΅ΠΊΠ° ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ќС ја ΠΈΠ·Π²Ρ€ΡˆΠΈΡ‚Π΅ ΠΎΠ²Π°Π° ΡˆΠΈΡ„Ρ€Π°, ќС Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΏΠΎΡ‡Π΅ΠΊΠ°Ρ‚Π΅ Π½Π΅ΠΊΠΎΠ΅ Π²Ρ€Π΅ΠΌΠ΅ Π΄ΠΎΠ΄Π΅ΠΊΠ° Π½Π΅ сС Π·Π°Π²Ρ€ΡˆΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π°. Ми Ρ‚Ρ€Π΅Π±Π°Π° 5 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ. ΠŸΠΎΡ‚Ρ€Π΅Π±Π½ΠΎ Π΅ Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° сС ΠΎΠ±ΡƒΡ‡ΠΈ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°.

 for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Π“ΠΎ Π΄ΠΎΠ±ΠΈΠ²Π°ΠΌΠ΅ слСдниот Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚:

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π“ΠΎ Π·Π°Ρ‡ΡƒΠ²ΡƒΠ²Π°ΠΌΠ΅ Π½Π°ΡˆΠΈΠΎΡ‚ ΠΎΠ±ΡƒΡ‡Π΅Π½ ΠΌΠΎΠ΄Π΅Π»:

PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)

ΠœΡ€Π΅ΠΆΠ½ΠΎ Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈΡ‚Π΅ ΠΎΠ΄ тСстот

Ја ΠΎΠ±ΡƒΡ‡ΠΈΠ²ΠΌΠ΅ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π·Π±ΠΈΡ€ Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ Π·Π° ΠΎΠ±ΡƒΠΊΠ°. Но, Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π²ΠΎΠΎΠΏΡˆΡ‚ΠΎ Π½Π°ΡƒΡ‡ΠΈΠ»Π° Π½Π΅ΡˆΡ‚ΠΎ.

ЌС Π³ΠΎ тСстирамС ΠΎΠ²Π° со ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΎΠ·Π½Π°ΠΊΠ°Ρ‚Π° Π½Π° класата ΡˆΡ‚ΠΎ ја Π΄Π°Π²Π° нСвронската ΠΌΡ€Π΅ΠΆΠ° ΠΈ ќС ја тСстирамС Π·Π° Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ Π΄Π°Π»ΠΈ Π΅ вистина. Ако ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ, Π³ΠΎ Π΄ΠΎΠ΄Π°Π²Π°ΠΌΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΊΠΎΡ‚ Π½Π° списокот со Ρ‚ΠΎΡ‡Π½ΠΈ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΡƒΠ²Π°ΡšΠ°.
АјдС Π΄Π° ΠΏΡ€ΠΈΠΊΠ°ΠΆΠ΅ΠΌΠ΅ слика ΠΎΠ΄ тСст сСт:

dataiter = iter(testloader)
images, labels = dataiter.next()

# print images
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π‘Π΅Π³Π° Π΄Π° ΠΏΠΎΠ±Π°Ρ€Π°ΠΌΠ΅ ΠΎΠ΄ нСвронската ΠΌΡ€Π΅ΠΆΠ° Π΄Π° Π½ΠΈ ΠΊΠ°ΠΆΠ΅ ΡˆΡ‚ΠΎ Π΅ Π½Π° ΠΎΠ²ΠΈΠ΅ слики:


net = Net()
net.load_state_dict(torch.load(PATH))

outputs = net(images)

_, predicted = torch.max(outputs, 1)

print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]
                              for j in range(4)))

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ ΠΈΠ·Π³Π»Π΅Π΄Π°Π°Ρ‚ ΠΏΡ€ΠΈΠ»ΠΈΡ‡Π½ΠΎ Π΄ΠΎΠ±Ρ€ΠΈ: ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΡƒΠ²Π°ΡˆΠ΅ Ρ‚Ρ€ΠΈ ΠΎΠ΄ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ слики.

АјдС Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π½ΠΈΠ· Ρ†Π΅Π»Π°Ρ‚Π° Π±Π°Π·Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ.


correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

ИзглСда Π΄Π΅ΠΊΠ° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π·Π½Π°Π΅ Π½Π΅ΡˆΡ‚ΠΎ ΠΈ Ρ€Π°Π±ΠΎΡ‚ΠΈ. Π”ΠΎΠΊΠΎΠ»ΠΊΡƒ Π³ΠΈ ΠΎΠ΄Ρ€Π΅Π΄ΠΈ класитС ΠΏΠΎ случаСн ΠΈΠ·Π±ΠΎΡ€, точноста Π±ΠΈ Π±ΠΈΠ»Π° 10%.

Π‘Π΅Π³Π° Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ ΠΊΠΎΠΈ класи ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π³ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΡƒΠ²Π° ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΠΎ:

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1


for i in range(10):
    print('Accuracy of %5s : %2d %%' % (
        classes[i], 100 * class_correct[i] / class_total[i]))

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π‘Π΅ Ρ‡ΠΈΠ½ΠΈ Π΄Π΅ΠΊΠ° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π΅ Π½Π°Ρ˜Π΄ΠΎΠ±Ρ€Π° Π²ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΡƒΠ²Π°ΡšΠ΅ Π½Π° Π°Π²Ρ‚ΠΎΠΌΠΎΠ±ΠΈΠ»ΠΈ ΠΈ Π±Ρ€ΠΎΠ΄ΠΎΠ²ΠΈ: 71% точност.

Π—Π½Π°Ρ‡ΠΈ, ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ. Π‘Π΅Π³Π° Π΄Π° сС ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° ја прСнСсСмС Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор (GPU) ΠΈ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ ΡˆΡ‚ΠΎ сС ΠΌΠ΅Π½ΡƒΠ²Π°.

ΠžΠ±ΡƒΠΊΠ° Π½Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор

ΠŸΡ€Π²ΠΎ Π½Π°ΠΊΡ€Π°Ρ‚ΠΊΠΎ ќС објаснам ΡˆΡ‚ΠΎ Π΅ CUDA. CUDA (Compute Unified Device Architecture) Π΅ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½Π° ΠΊΠΎΠΌΠΏΡ˜ΡƒΡ‚Π΅Ρ€ΡΠΊΠ° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° Ρ€Π°Π·Π²ΠΈΠ΅Π½Π° ΠΎΠ΄ NVIDIA Π·Π° ΠΎΠΏΡˆΡ‚ΠΎ ΠΏΡ€Π΅ΡΠΌΠ΅Ρ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсорски Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ (GPU). Π‘ΠΎ CUDA, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ°Ρ‚ Π΄Ρ€Π°ΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ Π΄Π° Π³ΠΈ Π·Π°Π±Ρ€Π·Π°Π°Ρ‚ ΠΊΠΎΠΌΠΏΡ˜ΡƒΡ‚Π΅Ρ€ΡΠΊΠΈΡ‚Π΅ Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ со ΠΈΡΠΊΠΎΡ€ΠΈΡΡ‚ΡƒΠ²Π°ΡšΠ΅ Π½Π° ΠΌΠΎΡœΡ‚Π° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΡ‚Π΅ процСсори. Оваа ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ° Π΅ вСќС инсталирана Π½Π° Π½Π°ΡˆΠΈΠΎΡ‚ сСрвСр ΡˆΡ‚ΠΎ Π³ΠΎ ΠΊΡƒΠΏΠΈΠ²ΠΌΠ΅.

АјдС ΠΏΡ€Π²ΠΎ Π΄Π° Π³ΠΎ Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ Π½Π°ΡˆΠΈΠΎΡ‚ Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсор ΠΊΠ°ΠΊΠΎ ΠΏΡ€Π²ΠΈΠΎΡ‚ Π²ΠΈΠ΄Π»ΠΈΠ² cuda ΡƒΡ€Π΅Π΄.

device = torch . device ( "cuda:0" if torch . cuda . is_available () else "cpu" )
# Assuming that we are on a CUDA machine, this should print a CUDA device:
print ( device )

Π’Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€Π²Π° нСвронска ΠΌΡ€Π΅ΠΆΠ° Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (GPU). Π’ΠΎΠ΄ΠΈΡ‡ Π·Π° ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ†ΠΈ

Π˜ΡΠΏΡ€Π°ΡœΠ°ΡšΠ΅ Π½Π° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π΄ΠΎ Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор:

net.to(device)

Π˜ΡΡ‚ΠΎ Ρ‚Π°ΠΊΠ°, ќС ΠΌΠΎΡ€Π° Π΄Π° ΠΈΡΠΏΡ€Π°ΡœΠ°ΠΌΠ΅ Π²Π»Π΅Π·ΠΎΠ²ΠΈ ΠΈ Ρ†Π΅Π»ΠΈ Π½Π° сСкој Ρ‡Π΅ΠΊΠΎΡ€ Π΄ΠΎ Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор:

inputs, labels = data[0].to(device), data[1].to(device)

АјдС ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Π΄Π° ја ΠΎΠ±ΡƒΡ‡ΠΈΠΌΠ΅ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
    inputs, labels = data[0].to(device), data[1].to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Овој ΠΏΠ°Ρ‚ ΠΌΡ€Π΅ΠΆΠ½ΠΈΠΎΡ‚ Ρ‚Ρ€Π΅Π½ΠΈΠ½Π³ Ρ‚Ρ€Π°Π΅ΡˆΠ΅ ΠΎΠΊΠΎΠ»Ρƒ 3 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ. Π”Π° потсСтимС Π΄Π΅ΠΊΠ° истата Ρ„Π°Π·Π° Π½Π° ΠΊΠΎΠ½Π²Π΅Π½Ρ†ΠΈΠΎΠ½Π°Π»Π΅Π½ процСсор Ρ‚Ρ€Π°Π΅ΡˆΠ΅ 5 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ. Π Π°Π·Π»ΠΈΠΊΠ°Ρ‚Π° Π½Π΅ Π΅ Π·Π½Π°Ρ‡Π°Ρ˜Π½Π°, ΠΎΠ²Π° сС случува Π·Π°Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ Π½Π°ΡˆΠ°Ρ‚Π° ΠΌΡ€Π΅ΠΆΠ° Π½Π΅ Π΅ Ρ‚ΠΎΠ»ΠΊΡƒ Π³ΠΎΠ»Π΅ΠΌΠ°. Кога користитС Π³ΠΎΠ»Π΅ΠΌΠΈ Π½ΠΈΠ·ΠΈ Π·Π° ΠΎΠ±ΡƒΠΊΠ°, Ρ€Π°Π·Π»ΠΈΠΊΠ°Ρ‚Π° ΠΏΠΎΠΌΠ΅Ρ“Ρƒ Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор ΠΈ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π°Π»Π½ΠΈΠΎΡ‚ процСсор ќС сС Π·Π³ΠΎΠ»Π΅ΠΌΠΈ.

Π‘Π΅ Ρ‡ΠΈΠ½ΠΈ Π΄Π΅ΠΊΠ° Ρ‚ΠΎΠ° Π΅ сè. Π¨Ρ‚ΠΎ успСавмС Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅:

  • Π Π°Π·Π³Π»Π΅Π΄Π°Π²ΠΌΠ΅ ΡˆΡ‚ΠΎ Π΅ Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈΠΎΡ‚ процСсор ΠΈ Π³ΠΎ ΠΈΠ·Π±Ρ€Π°Π²ΠΌΠ΅ сСрвСрот Π½Π° кој Π΅ инсталиран;
  • ΠŸΠΎΡΡ‚Π°Π²ΠΈΠ²ΠΌΠ΅ софтвСрско ΠΎΠΏΠΊΡ€ΡƒΠΆΡƒΠ²Π°ΡšΠ΅ Π·Π° создавањС нСвронска ΠΌΡ€Π΅ΠΆΠ°;
  • Π‘ΠΎΠ·Π΄Π°Π΄ΠΎΠ²ΠΌΠ΅ нСвронска ΠΌΡ€Π΅ΠΆΠ° Π·Π° ΠΏΡ€Π΅ΠΏΠΎΠ·Π½Π°Π²Π°ΡšΠ΅ слики ΠΈ ја ΠΎΠ±ΡƒΡ‡ΠΈΠ²ΠΌΠ΅;
  • Ја ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΠ²ΠΌΠ΅ ΠΌΡ€Π΅ΠΆΠ½Π°Ρ‚Π° ΠΎΠ±ΡƒΠΊΠ° ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³Ρ€Π°Ρ„ΠΈΡ‡ΠΊΠΈ процСсор ΠΈ Π΄ΠΎΠ±ΠΈΠ²ΠΌΠ΅ Π·Π³ΠΎΠ»Π΅ΠΌΡƒΠ²Π°ΡšΠ΅ Π½Π° Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π°.

Π‘ΠΎ задоволство ќС ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€Π°ΠΌ Π½Π° ΠΏΡ€Π°ΡˆΠ°ΡšΠ° Π²ΠΎ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅.

Π˜Π·Π²ΠΎΡ€: www.habr.com

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€