AI-For-Beginners/translations/km/lessons/4-ComputerVision/08-TransferLearning/TrainingTricks.md

112 lines
20 KiB
Markdown

# យុទ្ធសាស្ត្រ​បណ្តុះបណ្តាល​រៀនជ្រៅ
នៅពេលដែលបណ្តាញអនុវត្តកាន់តែជ្រៅ ការបណ្តុះបណ្តាលរបស់ពួកវាក្លាយទៅជាការលំបាកបន្ថែមទៀត។ បញ្ហាមួយសំខាន់គឺហៅថា [ចំណុចបាត់បង់ទ្រង់ទ្រាយកាត់ត់](https://en.wikipedia.org/wiki/Vanishing_gradient_problem) ឬ [ចំណុចបែកបាក់ទ្រង់ទ្រាយកាត់ត់](https://deepai.org/machine-learning-glossary-and-terms/exploding-gradient-problem#:~:text=Exploding%20gradients%20are%20a%20problem,updates%20are%20small%20and%20controlled.)។ [អត្ថបទនេះ](https://towardsdatascience.com/the-vanishing-exploding-gradient-problem-in-deep-neural-networks-191358470c11) ផ្តល់នូវការណែនាំល្អស្តីពីបញ្ហាទាំងនេះ។
ដើម្បីធ្វើឱ្យការបណ្តុះបណ្តាលបណ្តាញជ្រៅមានប្រសិទ្ធភាពច្រើនขึ้น មានបច្ចេកទេសមួយចំនួនដែលអាចប្រើបាន។
## រក្សាតម្លៃក្នុងលំហសមរម្យ
ដើម្បីធ្វើឱ្យការគណនាតាត្បាលមានស្ថិរភាព យើងចង់ធ្វើឱ្យប្រាកដថាតម្លៃទាំងអស់ក្នុងបណ្តាញបណ្តាញអនុវត្តរបស់យើងស្ថិតនៅក្នុងលំហសមរម្យ ជាទូទៅ[-1..1] ឬ [0..1]។ វាមិនមែនជាការទាមទារយ៉ាងតឹងរឹងទេ ប៉ុន្តែធម្មជាតិនៃការគណនាចំនួនបន្តិចបន្តួចគឺថាតម្លៃដែលមានទំហំនានាផ្សេងគ្នាមិនអាចគ្រប់គ្រងបានយ៉ាងត្រឹមត្រូវរួមគ្នា។ ឧទាហរណ៍ ប្រសិនបើយើងបូក 10<sup>-10</sup> និង 10<sup>10</sup> យើងប្រហែលជាបាន 10<sup>10</sup> ព្រោះតម្លៃតូចនឹងត្រូវបាន "បំលែង" ទៅលំដាប់ដូចគ្នាដូចតម្លៃធំ ជាធម្មតាម៉ង់ទីស្សាតិត្រូវបាត់បង់។
មុខងារបញ្ចេញផ្សេងៗភាគច្រើនមានបម្រែបម្រួលមិនប៉ុនប៉ងនៅជុំវិញ [-1..1] ដូច្នេះវាមានន័យក្នុងការតំលើងទិន្នន័យចូលទាំងអស់ទៅលំហ [-1..1] ឬ [0..1] ។
## ការចាប់ផ្តើមផ្ដល់ទម្ងន់ដើម
អក្នុងលក្ខណៈល្អបំផុត យើងចង់ឲ្យតម្លៃស្ថិតនៅក្នុងជួរដូចគ្នាបន្ទាប់ពីការស្វែងកាត់តបណ្តាញ។ ដូច្នេះវាសំខាន់ក្នុងការចាប់ផ្តើមផ្ដល់ទម្ងន់ដោយវិធីដែលរក្សាតំបន់បែងចែកនៃតម្លៃ។
ការបែងចែកធម្មតា **N(0,1)** មិនមែនជាគំនិតល្អទេ ដោយសារបើយើងមាន *n* តម្លៃចូល កម្រិតបញ្ចេញផ្គត់ផ្គង់នៃលទ្ធផលនឹងជាប្រេកង់ *n* ហើយតម្លៃឆ្លងទៅអាចទៅកាន់លំហ [0..1]។
ការចាប់ផ្តើមផ្ដល់ទម្ងន់ខាងក្រោមគឺប្រើជារឿយៗ៖
* ការបែងចែកស្មើ -- `uniform`
* **N(0,1/n)** -- `gaussian`
* **N(0,1/&radic;n_in)** ធានាថាសម្រាប់ទិន្នន័យចូលដែលមានមធ្យមសូន្យ និងកម្រិតបញ្ចេញផ្គត់ផ្គង់ 1 មធ្យម/គុណនៃកម្រិតបញ្ចេញផ្គត់ផ្គង់នឹងមាននៅ
* **N(0,&radic;2/(n_in+n_out))** -- ហៅថា **ចាប់ផ្តើម Xavier** (`glorot`), វាជួយរក្សាសញ្ញានៅក្នុងជួរទាំងក្នុងការស្ទង់តាមមុខនិងត្រឡប់ក្រោយ
## Batch Normalization
បើទោះបីបង្កើតផ្ដល់ទម្ងន់បានត្រឹមត្រូវ ក៏ទម្ងន់អាចកើនឡើង ឬ​តូច​ណាស់​ក្នុងអំឡុងការបណ្តុះបណ្តាល ហើយវានឹងធ្វើឲ្យសញ្ញាចេញពីជួរត្រឹមត្រូវ។ យើងអាចយកសញ្ញាត្រឡប់វិញដោយប្រើនឹកស្មានវិធី **normalization** មួយ។ ខណៈដែលវាមានច្រើនយ៉ាង (Weight Normalization, Layer Normalization) វិធីដែលប្រើប្រាស់ច្រើនជាងគេគឺ Batch Normalization។
គំនិតនៃ **batch normalization** គឺយកតម្លៃទាំងអស់ក្នុង minibatch ហើយអនុវត្ត normalization (យបានដកមធ្យម និងបែងចែកដោយកម្រិតបញ្ចេញផ្គត់ផ្គង់) ដោយផ្អែកលើតម្លៃទាំងនោះ។ វាត្រូវបានអនុវត្តជាជាន់បណ្តាញមួយដែលអនុវត្ត normalization នេះបន្ទាប់ពីបូកទម្ងន់ ប៉ុន្តែមុនមុខងារបញ្ចេញ។ ផលវិបាក គឺយើងបានឃើញគុណភាពចុងក្រោយខ្ពស់ និងការបណ្តុះបណ្តាលរហ័ស។
នេះជាឯកសារដើម [original paper](https://arxiv.org/pdf/1502.03167.pdf) ស្តីពី batch normalization, [ការពន្យល់ក្នុងវិគីភីឌា](https://en.wikipedia.org/wiki/Batch_normalization), និង [អត្ថបទណែនាំល្អ](https://towardsdatascience.com/batch-normalization-in-3-levels-of-understanding-14c2da90a338) (និងមួយ [ជារុស្សី](https://habrahabr.ru/post/309302/))។
## Dropout
**Dropout** គឺជាបច្ចេកទេសគួរឱ្យចាប់អារម្មណ៍ដែលដកចេញភាគរយចៃដន្យនៃន្យូរ៉ូនក្នុងអំឡុងការបណ្តុះបណ្តាល។ វាត្រូវបានអនុវត្តជាជាន់មួយដែលមានប៉ារ៉ាម៉ែត្រជាមួយ (ភាគរយន្យូរ៉ូនដែលត្រូវដកចេញ ជាទូទៅ ១០%-៥០%) ហើយក្នុងអំឡុងការបណ្តុះបណ្តាល វាកំណត់តម្លៃឡុងទាំងចៃដន្យនៃវ៉ិចទ័រចូល ដើម្បីបញ្ចូនទៅជាន់បន្ទាប់។
បើទោះបីវាដូចជាគំនិតអស្ចារ្យ អ្នកអាចមើលឃើញផលប៉ះពាល់របស់ dropout លើការបណ្តុះបណ្តាលម៉ាស៊ីនបំបែកលេខ MNIST នៅក្នុងកំណត់កិច្ច [`Dropout.ipynb`](Dropout.ipynb)។ វាផ្តល់នូវល្បឿនបណ្តុះបណ្តាលរហ័ស និងអនុញ្ញាតឱ្យយើងទទួលបានភាពត្រឹមត្រូវខ្ពស់ជាងមុនក្នុងចំនួន epoch តិចជាង។
ផលប៉ះពាល់នេះអាចពន្យល់បានជា៖
* វាអាចត្រូវបានគេចាត់ទុកជា​ឧបករណ៍ចុកចាប់ចៃដន្យទៅលើម៉ូដែល ដែលយកការបង្រួមចំណុចពីខ្នាតតូច
* វាអាចត្រូវបានគេដាក់ជារបៀប *ការเฉลี่ยម៉ូដែលដោយហេតុផល* ព្រោះយើងអាចនិយាយថា ក្នុងអំឡុង dropout យើងកំពុងបណ្តុះបណ្តាលម៉ូដែលខុសគ្នាខ្លះៗ
> *មនុស្សមួយចំនួនម្នាក់និយាយថា នៅពេលមនុស្សម្នាក់ផឹកស្រា ហើយព្យាយាមរៀនអ្វីមួយ គេនឹងចងចាំបានល្អជាងពេលឆៅពេលព្រឹក ព្រោះខួរក្បាលដែលមានន្យូរ៉ូនខូចខាតខ្លះព្យាយាមបត់បែនខ្លួនប្រសើរឡើងដើម្បីយល់ផ្លូវច្បាស់។ យើងមិនដែលសាកល្បងថាវាជាការពិតរឺអ្វីទេ។*
## ការទប់ស្កាត់ overfitting
មួយក្នុងចំណោមចំណុចសំខាន់នៃការរៀនជ្រៅគឺមានសមត្ថភាពទប់ស្កាត់ [overfitting](../../3-NeuralNetworks/05-Frameworks/Overfitting.md)។ ខណៈដែលវាអាចជាចំណាប់អារម្មណ៍ក្នុងការប្រើម៉ូដែលបណ្តាញអនុវត្តមានថាមពលខ្លាំង យើងគួរតែនៅតែតុល្យភាពចំនួនប៉ារ៉ាម៉ែត្រម៉ូដែល ជាមួយចំនួនគំរូបណ្តុះបណ្តាល។
> ទុកចិត្តទាត់ខ្លួនឯងក្នុងគំនិត [overfitting](../../3-NeuralNetworks/05-Frameworks/Overfitting.md) ដែលយើងបានណែនាំជាមុន!
មានវិធីជាច្រើនដើម្បីទប់ស្កាត់ overfitting៖
* បញ្ឈប់បន្ទាន់ -- ត្រួតពិនិត្យកំហុសលើកំណត់ត្រាបញ្ជាក់ជាបន្តបន្ទាប់ ហើយបញ្ឈប់បណ្តុះបណ្តាលពេលកំហុសកំណត់ត្រាបញ្ជាក់ចាប់ផ្តើមកើនឡើង។
* Weight Decay / Regularization ផ្ទាល់រំលេច -- បន្ថែមពិន័យបន្ថែមលើអនុគមន៍ខាតសម្រាប់តម្លៃទម្ងន់ខ្ពស់ ដែលទប់ស្កាត់មិនឲ្យម៉ូដែលមានលទ្ធផលមិនស្ថិតស្ថេរណ៍
* ការជម្រះម៉ូដែល -- បណ្តុះបណ្តាលម៉ូដែលជាច្រើន ហើយបន្ទាប់មកជម្រះលទ្ធផល។ វាជួយថយចុះភាពខុសគ្នា។
* Dropout (ការជម្រះម៉ូដែលដោយហេតុផល)
## Optimizers / Training Algorithms
ចំណុចសំខាន់មួយទៀតក្នុងការបណ្តុះបណ្តាលគឺជ្រើសរើសអាល់គ័រីធម៍បណ្តុះបណ្តាលល្អ។ ខណៈដែល **gradient descent** ចំណូលដល់ជាជម្រើសសមរម្យ ប៉ុន្តាមួយចំនួនពេលវាអាចយឺតពេក ឬមានបញ្ហាផ្សេងៗ។
ក្នុងការរៀនជ្រៅ យើងប្រើ **Stochastic Gradient Descent** (SGD) ដែលជាការធ្វើ gradient descent លើ minibatches ដែលជ្រើសរើសចៃដន្យពីសំណុំបណ្តុះបណ្តាល។ ទម្ងន់ត្រូវបានកែប្រែដោយរូបមន្តនេះ៖
w<sup>t+1</sup> = w<sup>t</sup> - &eta;&nabla;&lagran;
### Momentum
នៅក្នុង **momentum SGD** យើងរក្សាផ្នែកមួយនៃ gradient ពីជំហានមុនៗ។ វាស្រដៀងពេលដែលយើងចត់ឲ្យទៅលើក្រោមល្បឿនមួយ ហើយទទួលបានគ្រោះថ្នាក់បាតុកម្មមួយទៅទិសដៅផ្សេង អ្នកមិនបម្លែងដងផ្លូវភ្លាមទេ ប៉ុន្តែរក្សាផ្នែកនៃចលនាដើម។ នៅទីនេះយើងបញ្ចូលវ៉ិចទ័រថ្មី v ដើម្បីតំណាងឱ្យ *ល្បឿន*
* v<sup>t+1</sup> = &gamma; v<sup>t</sup> - &eta;&nabla;&lagran;
* w<sup>t+1</sup> = w<sup>t</sup>+v<sup>t+1</sup>
នៅទីនេះ​ប៉ារ៉ាម៉ែត្រ &gamma; រាយការណ៍ពីកម្រិតដែលយើងយក inertia ទៅគិត៖ &gamma;=0 តំណាងឱ្យ SGD ដើម; &gamma;=1 ជាសមីការចលនា​សុទ្ធ។
### Adam, Adagrad, និងផ្សេងៗទៀត
ដោយសារនៅក្នុងជាន់មួយៗ យើងគុណសញ្ញាជាមួយម៉ាទ្រីស W<sub>i</sub> មួយ ដែលអាស្រ័យទៅលើ ||W<sub>i</sub>||, gradient អាចត្រូវបន្ថយទៅជាមួយ 0 ឬកើនឡើងឥតដែនកំណត់។ នេះគឺជាមូលដ្ឋាននៃបញ្ហា Exploding/Vanishing Gradients។
ដំណោះស្រាយមួយសម្រាប់បញ្ហានេះគឺប្រើទិសដៅ gradient ទេ តម្លៃអប្បបរមាត្រូវបានរំលង គឺ
w<sup>t+1</sup> = w<sup>t</sup> - &eta;(&nabla;&lagran;/||&nabla;&lagran;||), ដែល ||&nabla;&lagran;|| = &radic;&sum;(&nabla;&lagran;)<sup>2</sup>
អាល់គ័រីធម៍នេះហៅថា **Adagrad**។ អាល់គ័រីធម៍ផ្សេងទៀត ដែលប្រើគំនិតដូចគ្នា៖ **RMSProp**, **Adam**
> **Adam** ត្រូវបានចាត់ទុកថាជាអាល់គ័រីធម៍មានប្រសិទ្ធភាពខ្ពស់សម្រាប់ករណីជាច្រើន ដូច្នេះបើអ្នកមិនប្រាកដថាត្រូវប្រើអ្វី គួរតែប្រើ Adam ។
### ការកាត់ gradient (Gradient clipping)
Gradient clipping ជាការបន្ថែមលើគំនិតខាងលើ។ នៅពេល ||&nabla;&lagran;|| &le; &theta; យើងគិត gradient ដើមក្នុងការបង្កើតទម្ងន់ ហើយនៅពេល ||&nabla;&lagran;|| > &theta; - យើងបែងចែក gradient ដោយកម្រិតវា។ នៅទីនេះ &theta; ជាប៉ារ៉ាម៉ែត្រ ដែលនៅភាគច្រើននាយយក &theta;=1 ឬ &theta;=10។
### ការថយចុះអត្រាសិក្សា (Learning rate decay)
ភាពជោគជ័យនៃការបណ្តុះបណ្តាលជាញឹកញាប់អាស្រ័យលើប៉ារ៉ាម៉ែត្រ អត្រាសិក្សា &eta;។ វាមានហេតុផលក្នុងការព្យាយាមពីថាតម្លៃ &eta; ខ្ពស់នាំឲ្យមានការបណ្តុះបណ្តាលរហ័ស ខណៈដែលវាជារឿងដែលយើងចង់បាននៅដំបូងនៃការបណ្តុះបណ្តាល ហើយបន្ទាប់មកតម្លៃតូច​នៃ &eta; អនុញ្ញាតឲ្យយើងកែប្រែបណ្តាញបានល្អប្រសើរ។ ដូច្នេះ ក្នុងភាគច្រើនករណី យើងចង់ថយចុះ &eta; ក្នុងដំណើរការបណ្តុះបណ្តាល។
នេះអាចធ្វើបាន ដោយគុណ &eta; ជាមួយចំនួនមួយ (ឧ. 0.98) បន្ទាប់ពីមួយ epoch នៃការបណ្តុះបណ្តាល ឬដោយប្រើ **សៀវភៅរៀនអត្រា** ជាមួយវិធីសាស្ត្រលំបាកច្រើន។
## សំណង់បណ្តាញផ្សេងៗ
ការជ្រើសរើសសំណង់បណ្តាញត្រឹមត្រូវសម្រាប់បញ្ហារបស់អ្នកអាចពិបាក។ ជាធម្មតាយើងនឹងយកសំណង់ដែលបានបញ្ជាក់ថាដំណើរការល្អសម្រាប់ភារកិច្ចជាក់លាក់របស់យើង (ឬស្រដៀង)។ នេះជាវិចារណារូបមន្តល្អមួយ [good overview](https://www.topbots.com/a-brief-history-of-neural-network-architectures/) នៃសំណង់បណ្តាញសម្រាប់កុំព្យូទ័រមើលឃើញ។
> វាសំខាន់ក្នុងការជ្រើសរើសសំណង់ដែលមានថាមពលគ្រប់គ្រាន់សម្រាប់ចំនួនគំរូបណ្តុះបណ្តាលដែលយើងមាន។ ជ្រើសរើសម៉ូដែលមានថាមពលខ្លាំងរឹតតែខ្លាំង អាចនាំឲ្យមាន​[overfitting](../../3-NeuralNetworks/05-Frameworks/Overfitting.md)។
វិធីល្អមួយទៀតគឺប្រើសំណង់ដែលអាចប្លាស់ប្ដូរផ្អែកលើបរិមាណភាពចំរូងចំរាសត្រូវបានទាមទារ។ ក្នុងកម្រិតមួយ សំណង់ **ResNet** និង **Inception** មានលក្ខណៈស្វ័យប្រតិទិន។ [មើលបន្ថែមសំណង់រចនាគំរូកុំព្យូទ័រមើលឃើញ](../07-ConvNets/CNN_Architectures.md)។
---
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**ការប្រុងប្រយត្ន័**
ឯកសារនេះត្រូវបានបម្លែងភាសាដោយប្រើសេវាកម្មបកប្រែ AI [Co-op Translator](https://github.com/Azure/co-op-translator)។ នៅពេលដែលយើងខិតខំផ្តល់នូវភាពត្រឹមត្រូវ សូមជ្រាបថាការបកប្រែមAutomated អាចមានកំហុស ឬភាពមិនត្រឹមត្រូវ។ ឯកសារដើមនៅភាសាដើមគួរត្រូវបានណែនាំជាធាតុយោងផ្លូវការជាក់ស្តែង។ សម្រាប់ព័ត៌មានសំខាន់ៗ អំពីការបកប្រែដោយអ្នកជំនាញមនុស្សគួរត្រូវបានណែនាំ។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការបកប្រែខុសដោយសារប្រើប្រាស់ការបកប្រែនេះឡើយ។
<!-- CO-OP TRANSLATOR DISCLAIMER END -->