មាតិកា[លាក់][បង្ហាញ]
ខួរក្បាលអាចប្រៀបធៀបទៅនឹងបណ្តាញសរសៃប្រសាទ។ នេះគឺជាការប្រៀបធៀបដែលជាធម្មតាត្រូវបានប្រើដើម្បីជួយនរណាម្នាក់ថ្មីចំពោះប្រធានបទឱ្យយល់ពីគំនិតនៅពីក្រោយការរៀនម៉ាស៊ីន និងបណ្តាញសរសៃប្រសាទសិប្បនិម្មិត។
ដោយសារតែមានស្រទាប់ជាច្រើននៃការគណនាគណិតវិទ្យា និងស្ថិតិដែលកំពុងដំណើរការនៅពីក្រោយឆាក ការកំណត់បណ្តាញទាំងនេះជាមុខងារគណិតវិទ្យាគឺជាវិធីសាស្ត្រកម្រិតខ្ពស់ជាង។
នេះគឺសម្រាប់អ្នកដែលចាប់អារម្មណ៍ក្នុងការរៀនម៉ាស៊ីន ហើយចង់មើលពីរបៀបដែលកូដបណ្តាញសរសៃប្រសាទ Python ត្រូវបានសរសេរ។
នៅក្នុងអត្ថបទនេះ យើងនឹងបង្ហាញពីរបៀបបង្កើតបណ្តាញសរសៃប្រសាទជ្រៅដែលបានតភ្ជាប់យ៉ាងពេញលេញ (DNN) ពីដំបូងនៅក្នុង ពស់ថ្លាន់ 3.
ទិដ្ឋភាពទូទៅនៃរចនាសម្ព័ន្ធឯកសារសម្រាប់កូដបណ្តាញសរសៃប្រសាទ Python របស់យើង។
វានឹងមានឯកសារចំនួនបីត្រូវបានបង្កើតឡើងនៅទីនេះ។ ទីមួយគឺឯកសារ nn.py សាមញ្ញ ដែលនឹងត្រូវបានពិភាក្សានៅក្នុង "ការដំឡើងមុខងារជំនួយ" និង "ការកសាងបណ្តាញសរសៃប្រសាទពីការកោស"។
យើងក៏នឹងមានឯកសារមួយឈ្មោះថា mnist loader.py ដើម្បីផ្ទុកទិន្នន័យសាកល្បង ដូចដែលបានពិពណ៌នានៅក្នុង "កំពុងផ្ទុកទិន្នន័យ MNIST"។
ជាចុងក្រោយ យើងនឹងមានឯកសារមួយឈ្មោះថា test.py ដែលនឹងត្រូវបានបើកដំណើរការនៅក្នុងស្ថានីយ ដើម្បីសាកល្បងបណ្តាញសរសៃប្រសាទរបស់យើង។
ឯកសារនេះត្រូវបានពិពណ៌នាយ៉ាងលម្អិតនៅក្នុង "ការធ្វើតេស្តដែលកំពុងដំណើរការ"។
ការដំឡើង
បណ្ណាល័យ NumPy Python ត្រូវតែទាញយក ដើម្បីធ្វើតាមការណែនាំនេះ។ អ្នកអាចសម្រេចវាដោយប្រើពាក្យបញ្ជាខាងក្រោមនៅលើស្ថានីយ៖
ការនាំចូលម៉ូឌុល និងដំឡើងមុខងារជំនួយ
បណ្ណាល័យតែពីរដែលយើងត្រូវការគឺចៃដន្យ និង NumPy ដែលយើងនឹងនាំចូលភ្លាមៗ។ សម្រាប់ទម្ងន់ដំបូងនៃបណ្តាញសរសៃប្រសាទរបស់យើង យើងនឹងសាប់ពួកវាដោយប្រើបណ្ណាល័យចៃដន្យ។
ដើម្បីបង្កើនល្បឿនការគណនារបស់យើង យើងនឹងប្រើ NumPy ឬ np (តាមអនុសញ្ញា វាត្រូវបាននាំចូលជាញឹកញាប់ជា np)។ មុខងារជំនួយពីររបស់យើងនឹងត្រូវបានធ្វើឡើងបន្ទាប់ពីការនាំចូលរបស់យើង។ មុខងារ sigmoid ពីរ៖ មួយ និង sigmoid prime ។
ការតំរែតំរង់នៃភស្តុភារនឹងចាត់ថ្នាក់ទិន្នន័យដោយប្រើមុខងារ sigmoid ខណៈដែល backpropagation នឹងគណនាដីសណ្ត ឬជម្រាលដោយប្រើមុខងារ sigmoid prime។
ការបង្កើតថ្នាក់បណ្តាញ
ការកសាងបណ្តាញសរសៃប្រសាទដែលភ្ជាប់យ៉ាងពេញលេញគឺជាការផ្តោតអារម្មណ៍តែមួយគត់នៃផ្នែកនេះ។ ថ្នាក់បណ្តាញនឹងរួមបញ្ចូលមុខងារទាំងអស់ដែលកើតឡើងបន្ទាប់។ មុខងារ Object() { [កូដដើម] } នឹងត្រូវបានបង្កើតដំបូងនៅក្នុងថ្នាក់បណ្តាញរបស់យើង។
អាគុយម៉ង់មួយ ទំហំត្រូវបានទាមទារដោយមុខងារ Object() { [កូដដើម] } ។ ទំហំអថេរគឺជាបណ្តុំនៃតម្លៃលេខដែលតំណាងឱ្យចំនួនថ្នាំងបញ្ចូលដែលមានវត្តមាននៅក្នុងស្រទាប់នីមួយៗនៃបណ្តាញសរសៃប្រសាទរបស់យើង។
យើងចាប់ផ្តើមលក្ខណៈសម្បត្តិចំនួនបួននៅក្នុងវិធីសាស្រ្ត __init__ របស់យើង។ អថេរបញ្ចូល ទំហំ ត្រូវបានប្រើដើម្បីកំណត់បញ្ជីទំហំស្រទាប់ និងចំនួនស្រទាប់ លេខស្រទាប់រៀងៗខ្លួន។
ជំហានដំបូងគឺកំណត់ដោយចៃដន្យនូវភាពលំអៀងដំបូងរបស់បណ្តាញរបស់យើងទៅស្រទាប់នីមួយៗដែលធ្វើតាមស្រទាប់បញ្ចូល។
ជាចុងក្រោយ តំណភ្ជាប់នីមួយៗរវាងស្រទាប់បញ្ចូល និងទិន្នផលមានទម្ងន់របស់វាបង្កើតដោយចៃដន្យ។ Np.Random.Randn() ផ្តល់នូវគំរូចៃដន្យដែលទាញចេញពីការចែកចាយធម្មតាសម្រាប់បរិបទ។
មុខងារបញ្ជូនបន្ត
នៅក្នុងបណ្តាញសរសៃប្រសាទ ព័ត៌មានត្រូវបានបញ្ជូនបន្តដោយមុខងារ feedforward ។ អាគុយម៉ង់មួយ a ដែលបង្ហាញពីវ៉ិចទ័រសកម្មបច្ចុប្បន្ននឹងត្រូវបានទាមទារដោយមុខងារនេះ។
មុខងារនេះប៉ាន់ប្រមាណការធ្វើឱ្យសកម្មនៅស្រទាប់នីមួយៗដោយការធ្វើឡើងវិញលើភាពលំអៀង និងទម្ងន់ទាំងអស់នៅក្នុងបណ្តាញ។ ចម្លើយដែលបានផ្តល់ឲ្យគឺការទស្សន៍ទាយដែលជាសកម្មភាពនៃស្រទាប់ចុងក្រោយ។
ការចុះជម្រាលជម្រាលខ្នាតតូច
ក្រុមការងារថ្នាក់ Network របស់យើងគឺ Gradient Descent។ នៅក្នុងកំណែនេះ យើងប្រើ mini-batch (stochastic) gradient descent ដែលជាការប្រែប្រួលដែលបានកែប្រែនៃ gradient descent។
នេះបង្ហាញថាបណ្តុំទិន្នន័យតូចមួយនឹងត្រូវបានប្រើដើម្បីធ្វើបច្ចុប្បន្នភាពគំរូរបស់យើង។ អាគុយម៉ង់ស្រេចចិត្តចំនួនបួនត្រូវបានបញ្ជូនទៅវិធីសាស្ត្រនេះ។ អថេរដែលត្រូវការទាំងបួនគឺសំណុំទិន្នន័យការបណ្តុះបណ្តាលចំនួននៃសម័យកាលទំហំតូចនិងអត្រាសិក្សា (eta)។
ទិន្នន័យតេស្តអាចរកបានតាមការស្នើសុំ។ យើងនឹងផ្គត់ផ្គង់ទិន្នន័យសាកល្បង នៅពេលដែលយើងវាយតម្លៃបណ្តាញនេះនៅទីបំផុត។ ចំនួនគំរូនៅក្នុងមុខងារនេះដំបូងត្រូវបានកំណត់ទៅជាប្រវែងនៃបញ្ជី នៅពេលដែលទិន្នន័យបណ្តុះបណ្តាលត្រូវបានបំលែងទៅជាប្រភេទបញ្ជី។
យើងក៏អនុវត្តដំណើរការដូចគ្នានេះផងដែរ ដើម្បីសាកល្បងទិន្នន័យដែលត្រូវបានផ្តល់ឱ្យ។ នេះគឺដោយសារតែជំនួសឱ្យការត្រលប់មកពួកយើងជាបញ្ជី ពួកគេពិតជា zip នៃបញ្ជី។ នៅពេលយើងផ្ទុកគំរូទិន្នន័យ MNIST នៅពេលក្រោយ យើងនឹងស្វែងយល់បន្ថែមអំពីបញ្ហានេះ។
ប្រសិនបើយើងអាចប្រាកដថាយើងផ្តល់ទិន្នន័យទាំងពីរប្រភេទជាបញ្ជី នោះការបញ្ជូនប្រភេទនេះមិនចាំបាច់ចាំបាច់នោះទេ។
នៅពេលដែលយើងមានទិន្នន័យ យើងនឹងឆ្លងកាត់វគ្គបណ្តុះបណ្តាលជារង្វង់។ រយៈពេលបណ្តុះបណ្តាលគឺត្រឹមតែមួយជុំនៃការបណ្តុះបណ្តាលបណ្តាញសរសៃប្រសាទប៉ុណ្ណោះ។ ដំបូងឡើយ យើងធ្វើការសាប់ទិន្នន័យនៅក្នុងសម័យនីមួយៗ ដើម្បីធានាបាននូវភាពចៃដន្យ មុនពេលបង្កើតបញ្ជីនៃបណ្តុំតូចៗ។
មុខងារអាប់ដេតខ្នាតតូចបណ្តុំដែលត្រូវបានពិភាក្សាខាងក្រោមនឹងត្រូវបានហៅសម្រាប់បណ្តុំខ្នាតតូចនីមួយៗ។ ភាពត្រឹមត្រូវនៃការធ្វើតេស្តក៏នឹងត្រូវបានបញ្ជូនមកវិញផងដែរ ប្រសិនបើទិន្នន័យតេស្តមាន។
មុខងារជំនួយការដេរីវេនៃថ្លៃដើម
ចូរបង្កើតមុខងារជំនួយដែលហៅថា cost derivative ជាមុនសិន មុននឹងយើងបង្កើតកូដ backpropagation ។ ប្រសិនបើយើងធ្វើខុសនៅក្នុងស្រទាប់ទិន្នផលរបស់យើង មុខងារដេរីវេនៃតម្លៃនឹងបង្ហាញវា។
វាទាមទារធាតុបញ្ចូលពីរ៖ អារេធ្វើឱ្យសកម្មទិន្នផល និង y-coordinates នៃតម្លៃលទ្ធផលដែលរំពឹងទុក។
មុខងារបន្តពូជ
វ៉ិចទ័រធ្វើឱ្យសកម្មបច្ចុប្បន្នរបស់យើង ការធ្វើឱ្យសកម្ម ក៏ដូចជាវ៉ិចទ័រធ្វើឱ្យសកម្មផ្សេងទៀត សកម្មភាព និង z-វ៉ិចទ័រ zs ទាំងអស់ត្រូវតែរក្សាទុកក្នុងចិត្ត។ ស្រទាប់ដែលហៅថាស្រទាប់បញ្ចូលត្រូវបានធ្វើឱ្យសកម្មជាមុនសិន។
យើងនឹងពិនិត្យមើលភាពលំអៀង និងទម្ងន់នីមួយៗ បន្ទាប់ពីដាក់ពួកវាឡើង។ រង្វិលជុំនីមួយៗពាក់ព័ន្ធនឹងការគណនាវ៉ិចទ័រ z ជាផលិតផលចំនុចនៃទម្ងន់ និងការធ្វើឱ្យសកម្ម បន្ថែមវាទៅក្នុងបញ្ជី zs គណនាការធ្វើឱ្យសកម្មឡើងវិញ និងបន្ថែមការធ្វើឱ្យសកម្មដែលបានធ្វើបច្ចុប្បន្នភាពទៅក្នុងបញ្ជីសកម្មភាព។
ទីបំផុតគណិតវិទ្យា។ ដីសណ្តដែលស្មើនឹងកំហុសពីស្រទាប់មុនដែលគុណនឹង sigmoid prime នៃធាតុចុងក្រោយនៃវ៉ិចទ័រ zs ត្រូវបានគណនាមុនពេលយើងចាប់ផ្តើមការបញ្ជូនថយក្រោយរបស់យើង។
ស្រទាប់ចុងក្រោយនៃ nabla b ត្រូវបានកំណត់ជាដីសណ្ត ហើយស្រទាប់ចុងក្រោយនៃ nabla w ត្រូវបានកំណត់ជាផលិតផលចំនុចនៃដីសណ្ត និងស្រទាប់ទីពីរទៅចុងក្រោយនៃការធ្វើឱ្យសកម្ម (បញ្ជូនដូច្នេះយើងអាចធ្វើគណិតវិទ្យាបាន) .
យើងបន្តដូចមុន ដោយចាប់ផ្តើមពីស្រទាប់ទីពីរ ហើយបញ្ចប់ដោយចុងក្រោយ ហើយដំណើរការម្តងទៀតបន្ទាប់ពីបញ្ចប់ស្រទាប់ចុងក្រោយទាំងនេះ។ បន្ទាប់មក nablas ត្រូវបានផ្តល់ឱ្យត្រឡប់មកវិញជា tuple ។
ការធ្វើបច្ចុប្បន្នភាពការចុះជម្រាលជម្រាលខ្នាតតូច
វិធីសាស្រ្ត SGD (stochastic gradient descent) របស់យើងពីមុនពេលរួមបញ្ចូលការធ្វើបច្ចុប្បន្នភាពខ្នាតតូច។ ដោយសារវាត្រូវបានប្រើប្រាស់ក្នុង SGD ប៉ុន្តែក៏តម្រូវឱ្យមាន backprop ផងដែរ ខ្ញុំបានពិភាក្សាអំពីកន្លែងដែលត្រូវដាក់មុខងារនេះ។
ទីបំផុត ខ្ញុំបានសម្រេចចិត្តបង្ហោះវានៅទីនេះ។ វាចាប់ផ្តើមដោយបង្កើត 0 វ៉ិចទ័រនៃ nablas' និង weights' ដូចគ្នានឹងមុខងារ backprop របស់យើងដែរ។
វាទាមទារការសិក្សាខ្នាតតូច និងអត្រាការសិក្សា eta ជាធាតុចូលពីររបស់វា។ នៅក្នុង mini-batch បន្ទាប់មកយើងប្រើមុខងារ backprop ដើម្បីទទួលបាន delta នៃ nabla array នីមួយៗសម្រាប់ input, x, and output, y ។ បន្ទាប់មកបញ្ជី nabla ត្រូវបានធ្វើបច្ចុប្បន្នភាពជាមួយ deltas ទាំងនេះ។
ជាចុងក្រោយ យើងប្រើអត្រាសិក្សា និង nablas ដើម្បីធ្វើបច្ចុប្បន្នភាពទម្ងន់ និងភាពលំអៀងរបស់បណ្តាញ។ តម្លៃនីមួយៗត្រូវបានធ្វើបច្ចុប្បន្នភាពទៅតម្លៃថ្មីបំផុត អត្រាសិក្សាតិចជាង គុណនឹងទំហំតូច ហើយបន្ទាប់មកបន្ថែមទៅតម្លៃ nabla ។
វាយតម្លៃមុខងារ
មុខងារវាយតម្លៃគឺជាមុខងារចុងក្រោយដែលយើងត្រូវសរសេរ។ ទិន្នន័យសាកល្បងគឺជាការបញ្ចូលតែមួយគត់សម្រាប់មុខងារនេះ។ នៅក្នុងមុខងារនេះ យើងគ្រាន់តែប្រៀបធៀបលទ្ធផលនៃបណ្តាញជាមួយនឹងលទ្ធផលដែលរំពឹងទុក y ។ តាមរយៈការផ្តល់ចំណីបញ្ចូល x បញ្ជូនបន្ត លទ្ធផលនៃបណ្តាញត្រូវបានកំណត់។
លេខកូដពេញលេញ
ពេលយើងបញ្ចូលកូដទាំងអស់ នោះជារបៀបដែលវាបង្ហាញ។
ការធ្វើតេស្តបណ្តាញសរសៃប្រសាទ
កំពុងផ្ទុកទិន្នន័យ MNIST
នេះ ទិន្នន័យ MNIST គឺនៅក្នុងទម្រង់ .pkl.gz ដែលយើងនឹងបើកដោយប្រើ GZIP ហើយផ្ទុកជាមួយ pickle ។ ចូរយើងសរសេរវិធីសាស្រ្តរហ័សដើម្បីផ្ទុកទិន្នន័យនេះជា tuple នៃទំហំ XNUMX បែងចែកទៅជាការបណ្តុះបណ្តាល សុពលភាព និងទិន្នន័យសាកល្បង។
ដើម្បីធ្វើឱ្យទិន្នន័យរបស់យើងកាន់តែងាយស្រួលក្នុងការគ្រប់គ្រង យើងនឹងសរសេរមុខងារមួយផ្សេងទៀតដើម្បីអ៊ិនកូដ y ទៅក្នុងអារេ 10 ធាតុ។ អារេនឹងមាន 0s ទាំងអស់ លើកលែងតែ 1 ដែលផ្គូផ្គងលេខត្រឹមត្រូវរបស់រូបភាព។
យើងនឹងប្រើទិន្នន័យផ្ទុកមូលដ្ឋាន និងវិធីសាស្ត្រអ៊ិនកូដក្តៅមួយ ដើម្បីផ្ទុកទិន្នន័យរបស់យើងទៅជាទម្រង់ដែលអាចអានបាន។ មុខងារមួយទៀតនឹងត្រូវបានសរសេរដែលនឹងបំប្លែងតម្លៃ x របស់យើងទៅជាបញ្ជីទំហំ 784 ដែលត្រូវគ្នានឹងរូបភាព 784 ភីកសែល ហើយតម្លៃ y របស់យើងទៅជាទម្រង់វ៉ិចទ័រដែលបានអ៊ិនកូដក្តៅតែមួយ។
បន្ទាប់មកយើងនឹងបញ្ចូលតម្លៃ x និង y ដែលសន្ទស្សន៍មួយត្រូវគ្នានឹងតម្លៃផ្សេងទៀត។ នេះអនុវត្តចំពោះសំណុំទិន្នន័យបណ្តុះបណ្តាល សុពលភាព និងការធ្វើតេស្ត។ បន្ទាប់មកយើងត្រឡប់ទិន្នន័យដែលបានផ្លាស់ប្តូរ។
ការធ្វើតេស្តសាកល្បង
យើងនឹងបង្កើតឯកសារថ្មីមួយដែលមានឈ្មោះថា "mnist loader" ដែលនឹងនាំចូលទាំងបណ្តាញសរសៃប្រសាទដែលយើងបានបង្កើតពីមុន (សាមញ្ញ nn) និងកម្មវិធីផ្ទុកទិន្នន័យ MNIST មុនពេលយើងចាប់ផ្តើមសាកល្បង។
នៅក្នុងឯកសារនេះ អ្វីដែលយើងត្រូវធ្វើគឺនាំចូលទិន្នន័យ បង្កើតបណ្តាញដែលមានទំហំស្រទាប់បញ្ចូល 784 និងទំហំស្រទាប់ទិន្នផល 10 ដំណើរការមុខងារ SGD របស់បណ្តាញនៅលើទិន្នន័យបណ្តុះបណ្តាល បន្ទាប់មកសាកល្បងវាដោយប្រើទិន្នន័យសាកល្បង។
សូមចងចាំថាសម្រាប់បញ្ជីនៃស្រទាប់បញ្ចូលរបស់យើង វាមិនមានអ្វីខុសប្លែកពីលេខណាមួយរវាង 784 និង 10។ យើងអាចផ្លាស់ប្តូរស្រទាប់ផ្សេងទៀតតាមវិធីដែលយើងចូលចិត្ត។ គ្រាន់តែទំហំបញ្ចូល និងទិន្នផលត្រូវបានជួសជុល។
បីស្រទាប់គឺមិនចាំបាច់; យើងអាចប្រើបួន ប្រាំ ឬសូម្បីតែពីរ។ សូមរីករាយសាកល្បងជាមួយវា។
សន្និដ្ឋាន
នៅទីនេះដោយប្រើ Python 3 យើងបង្កើតបណ្តាញសរសៃប្រសាទពីទទេ។ រួមជាមួយនឹងគណិតវិទ្យាកម្រិតខ្ពស់ យើងក៏បានពិភាក្សាអំពីលក្ខណៈជាក់លាក់នៃការអនុវត្តផងដែរ។
យើងបានចាប់ផ្តើមដោយអនុវត្តមុខងារជំនួយ។ សម្រាប់ណឺរ៉ូនដំណើរការ មុខងារសំខាន់របស់ sigmoid និង sigmoid គឺសំខាន់ណាស់។ បន្ទាប់មកយើងដាក់ឱ្យអនុវត្តមុខងារ feedforward ដែលជាដំណើរការមូលដ្ឋានសម្រាប់ការផ្តល់ទិន្នន័យទៅក្នុងបណ្តាញសរសៃប្រសាទ។
បន្ទាប់មក យើងបានបង្កើតមុខងារ gradient descent នៅក្នុង Python ដែលជាម៉ាស៊ីនដែលជំរុញបណ្តាញសរសៃប្រសាទរបស់យើង។ ដើម្បីកំណត់ទីតាំង “មីនីម៉ាក្នុងមូលដ្ឋាន” និងបង្កើនប្រសិទ្ធភាពទម្ងន់ និងភាពលំអៀងរបស់ពួកគេ បណ្តាញសរសៃប្រសាទរបស់យើងប្រើការចុះជម្រាល។ យើងបានបង្កើតមុខងារ backpropagation ដោយប្រើ ជម្រាលជម្រាល.
តាមរយៈការផ្តល់ព័ត៌មានថ្មីៗនៅពេលដែលលទ្ធផលមិនត្រូវគ្នានឹងស្លាកសញ្ញាត្រឹមត្រូវ មុខងារនេះអនុញ្ញាតឱ្យបណ្តាញសរសៃប្រសាទ "រៀន"។
ជាចុងក្រោយ យើងដាក់ Python ថ្មីរបស់យើង។ បណ្តាញសរសៃប្រសាទ ដើម្បីធ្វើតេស្តដោយប្រើសំណុំទិន្នន័យ MNIST ។ អ្វីៗដំណើរការយ៉ាងរលូន។
រីករាយកូដ
សូមផ្ដល់យោបល់