Unit Testing Adalah Teman Anda
Ada pepatah di antara para penulis bahwa "Semua tulisan adalah penulisan ulang" - artinya, sebagian besar tulisan direvisi. Untuk pemrogram (atau setidaknya ilmuwan data) ungkapan itu dapat diucapkan ulang sebagai "Semua pengkodean adalah debugging."
Setiap kali Anda menulis kode, Anda perlu memverifikasi bahwa kode itu berfungsi sebagaimana mestinya. Metode terbaik yang pernah saya temukan untuk memverifikasi kebenaran adalah memecah kode Anda menjadi segmen kecil, dan memverifikasi bahwa setiap segmen berfungsi. Ini dapat dilakukan dengan membandingkan keluaran segmen dengan apa yang Anda ketahui sebagai jawaban yang benar. Ini disebut pengujian unit . Menulis unit test yang baik adalah kunci untuk menjadi ahli statistik / ilmuwan data / ahli pembelajaran mesin / praktisi jaringan saraf yang baik. Tidak ada pengganti.
Anda harus memeriksa bahwa kode Anda bebas dari bug sebelum dapat menyesuaikan kinerja jaringan! Jika tidak, Anda mungkin juga mengatur kursi geladak di RMS Titanic .
Ada dua fitur jaringan saraf yang membuat verifikasi bahkan lebih penting daripada jenis pembelajaran mesin atau model statistik lainnya.
Jaringan saraf bukan algoritma "off-the-shelf" dalam cara yang acak hutan atau regresi logistik. Bahkan untuk jaringan yang sederhana, umpan-maju, tanggung jawab sebagian besar pada pengguna untuk membuat banyak keputusan tentang bagaimana jaringan dikonfigurasi, terhubung, diinisialisasi dan dioptimalkan. Ini berarti menulis kode, dan menulis kode berarti men-debug.
Bahkan ketika kode jaringan saraf dijalankan tanpa memunculkan pengecualian, jaringan masih dapat memiliki bug! Bug-bug ini bahkan mungkin merupakan jenis yang berbahaya di mana jaringan akan berlatih, tetapi terjebak pada solusi yang kurang optimal, atau jaringan yang dihasilkan tidak memiliki arsitektur yang diinginkan. ( Ini adalah contoh perbedaan antara kesalahan sintaksis dan semantik .)
Posting Medium ini , " Bagaimana cara menguji kode pembelajaran mesin ," oleh Chase Roberts membahas pengujian unit untuk model pembelajaran mesin secara lebih rinci. Saya meminjam contoh kode kereta ini dari artikel:
def make_convnet(input_image):
net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
return net
Apakah Anda melihat kesalahannya? Banyak operasi yang berbeda tidak benar - benar digunakan karena hasil sebelumnya terlalu banyak ditulis dengan variabel baru. Menggunakan blok kode ini dalam jaringan masih akan melatih dan bobot akan diperbarui dan kehilangan bahkan mungkin berkurang - tetapi kode pasti tidak melakukan apa yang dimaksudkan. (Penulis juga tidak konsisten tentang menggunakan tanda kutip tunggal atau ganda tapi itu murni gaya.)
Kesalahan pemrograman paling umum yang berkaitan dengan jaringan saraf adalah
- Variabel dibuat tetapi tidak pernah digunakan (biasanya karena kesalahan copy-paste);
- Ekspresi untuk pembaruan gradien salah;
- Pembaruan berat tidak diterapkan;
- Fungsi kerugian tidak diukur pada skala yang benar (misalnya, kehilangan lintas-entropi dapat dinyatakan dalam probabilitas atau log)
- Kehilangan tidak sesuai untuk tugas (misalnya, menggunakan kerugian lintas-entropi kategoris untuk tugas regresi).
Merangkak Sebelum Anda Berjalan; Berjalan Sebelum Menjalankan
Jaringan saraf yang luas dan dalam, dan jaringan saraf dengan kabel eksotis, adalah Hot Thing saat ini dalam pembelajaran mesin. Tetapi jaringan-jaringan ini tidak sepenuhnya terbentuk; desainer mereka dibangun untuk mereka dari unit yang lebih kecil. Pertama, bangun jaringan kecil dengan satu lapisan tersembunyi dan verifikasi apakah itu berfungsi dengan benar. Kemudian secara bertahap tambahkan kompleksitas model tambahan, dan verifikasi bahwa masing-masing berfungsi dengan baik.
Terlalu sedikit neuron dalam suatu lapisan dapat membatasi representasi yang dipelajari jaringan, yang menyebabkan kurang pas. Terlalu banyak neuron dapat menyebabkan pemasangan berlebihan karena jaringan akan "menghafal" data pelatihan.
Bahkan jika Anda dapat membuktikan bahwa secara matematis, hanya sejumlah kecil neuron yang diperlukan untuk memodelkan masalah, sering kali memiliki "beberapa" neuron membuat pengoptimal lebih mudah menemukan konfigurasi "baik". (Tapi saya tidak berpikir ada orang yang sepenuhnya mengerti mengapa hal ini terjadi.) Saya memberikan contoh tentang hal ini dalam konteks masalah XOR di sini: Tidakkah iterasi saya diperlukan untuk melatih NN untuk XOR dengan MSE <0,001 terlalu tinggi? .
Memilih jumlah lapisan tersembunyi memungkinkan jaringan mempelajari abstraksi dari data mentah. Pembelajaran mendalam adalah hal yang populer akhir-akhir ini, dan jaringan dengan banyak lapisan telah menunjukkan hasil yang mengesankan. Tetapi menambahkan terlalu banyak lapisan tersembunyi dapat membuat overfitting risiko atau membuatnya sangat sulit untuk mengoptimalkan jaringan.
Memilih kabel jaringan yang pintar dapat melakukan banyak pekerjaan untuk Anda. Apakah sumber data Anda setuju dengan arsitektur jaringan khusus? Jaringan saraf convolutional dapat mencapai hasil yang mengesankan pada sumber data, gambar atau audio yang "terstruktur". Jaringan saraf berulang dapat bekerja dengan baik pada tipe data sekuensial, seperti bahasa alami atau data deret waktu. Koneksi residual dapat meningkatkan jaringan umpan-maju yang dalam.
Pelatihan Jaringan Saraf Seperti Memetik Kunci
Untuk mencapai hasil terbaik, atau bahkan hanya hasil yang bagus, Anda harus mengatur semua bagian yang dikonfigurasikan untuk bekerja sama dengan baik . Menyiapkan konfigurasi jaringan saraf yang benar-benar dipelajari sama seperti mengambil kunci: semua bagian harus berbaris tepat. Sama seperti itu tidak cukup untuk memiliki satu gelas di tempat yang tepat, juga tidak cukup untuk hanya memiliki arsitektur, atau hanya pengoptimal, diatur dengan benar.
Pilihan konfigurasi penyetelan tidak sesederhana seperti mengatakan bahwa satu jenis pilihan konfigurasi (mis. Tingkat pembelajaran) lebih atau kurang penting daripada yang lain (misalnya jumlah unit), karena semua pilihan ini berinteraksi dengan semua pilihan lain, jadi satu pilihan dapat dilakukan dengan baik dalam kombinasi dengan pilihan lain yang dibuat di tempat lain .
Ini adalah daftar opsi konfigurasi yang tidak lengkap yang bukan juga opsi regularisasi atau opsi optimisasi numerik.
Semua topik ini adalah bidang penelitian aktif.
Inisialisasi jaringan sering diabaikan sebagai sumber bug jaringan saraf. Inisialisasi terlalu besar interval dapat mengatur bobot awal terlalu besar, yang berarti bahwa neuron tunggal memiliki pengaruh besar terhadap perilaku jaringan.
Perbedaan utama antara jaringan saraf dan model regresi adalah bahwa jaringan saraf adalah komposisi banyak fungsi nonlinier, yang disebut fungsi aktivasi . (Lihat: Apa perbedaan penting antara jaringan saraf dan regresi linier )
Hasil jaringan saraf klasik terfokus pada fungsi aktivasi sigmoidal (fungsi logistik atau ). Hasil baru-baru ini telah menemukan bahwa unit ReLU (atau serupa) cenderung bekerja lebih baik karena memiliki gradien yang lebih curam, sehingga pembaruan dapat diterapkan dengan cepat. (Lihat: Mengapa kita menggunakan ReLU dalam jaringan saraf dan bagaimana kita menggunakannya? ) Satu peringatan tentang ReLU adalah fenomena "neuron mati", yang dapat menghambat pembelajaran; relus yang bocor dan varian serupa menghindari masalah ini. Lihattanh
Ada sejumlah opsi lain. Lihat: Daftar lengkap fungsi aktivasi di jaringan saraf dengan pro / kontra
Koneksi residual adalah pengembangan rapi yang dapat membuatnya lebih mudah untuk melatih jaringan saraf. "Pembelajaran Residual yang Dalam untuk Pengenalan Gambar"
Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun Di: CVPR. (2016). Selain itu, mengubah urutan operasi dalam blok residual selanjutnya dapat meningkatkan jaringan yang dihasilkan. " Pemetaan Identitas di Deep Residual Networks " oleh Kaiming He, Xiangyu Zhang, Shaoqing Ren, dan Jian Sun.
Optimalisasi non-cembung sulit
Fungsi objektif dari jaringan saraf hanya cembung ketika tidak ada unit tersembunyi, semua aktivasi linier, dan matriks desain adalah peringkat penuh - karena konfigurasi ini secara identik merupakan masalah regresi biasa.
Dalam semua kasus lain, masalah optimisasi adalah non-cembung, dan optimasi non-cembung sulit. Tantangan pelatihan jaringan saraf sudah diketahui (lihat: Mengapa sulit untuk melatih jaringan saraf yang dalam? ). Selain itu, jaringan saraf memiliki sejumlah besar parameter, yang membatasi kita hanya pada metode orde pertama (lihat: Mengapa metode Newton tidak banyak digunakan dalam pembelajaran mesin? ). Ini adalah bidang penelitian yang sangat aktif.
Menyetel tingkat pembelajaran terlalu besar akan menyebabkan pengoptimalan menyimpang, karena Anda akan melompat dari satu sisi "jurang" ke sisi lainnya. Pengaturan ini terlalu kecil akan mencegah Anda membuat kemajuan nyata, dan mungkin memungkinkan kebisingan yang melekat dalam SGD membanjiri perkiraan gradien Anda.
Kliping gradien mengubah skala norma gradien jika berada di atas ambang batas. Dulu saya berpikir bahwa ini adalah parameter set-and-forget, biasanya pada 1,0, tetapi saya menemukan bahwa saya bisa membuat model bahasa LSTM secara dramatis lebih baik dengan menetapkannya ke 0,25. Saya tidak tahu mengapa itu terjadi.
Penjadwalan tingkat pembelajaran dapat mengurangi tingkat pembelajaran selama pelatihan. Dalam pengalaman saya, mencoba menggunakan penjadwalan sangat mirip dengan regex : ini menggantikan satu masalah ("Bagaimana saya bisa belajar untuk melanjutkan setelah zaman tertentu?") Dengan dua masalah ("Bagaimana saya bisa belajar untuk melanjutkan setelah zaman tertentu ? "dan" Bagaimana saya memilih jadwal yang baik? "). Orang lain bersikeras bahwa penjadwalan sangat penting. Saya akan membiarkan Anda memutuskan.
Memilih ukuran minibatch yang baik dapat mempengaruhi proses pembelajaran secara tidak langsung, karena mini-batch yang lebih besar cenderung memiliki varian yang lebih kecil ( law-of-large-number ) daripada mini-batch yang lebih kecil. Anda ingin mini-batch cukup besar untuk menjadi informatif tentang arah gradien, tetapi cukup kecil sehingga SGD dapat mengatur jaringan Anda.
Ada sejumlah varian pada penurunan gradien stokastik yang menggunakan momentum, tingkat pembelajaran adaptif, pembaruan Nesterov dan sebagainya untuk meningkatkan SGD vanilla. Merancang pengoptimal yang lebih baik sangat banyak bidang penelitian aktif. Beberapa contoh:
Ketika pertama kali keluar, pengoptimal Adam menghasilkan banyak minat. Tetapi beberapa penelitian baru-baru ini menemukan bahwa SGD dengan momentum dapat mengungguli metode gradien adaptif untuk jaringan saraf. " Nilai Marginal dari Metode Gradien Adaptif dalam Pembelajaran Mesin " oleh Ashia C. Wilson, Rebecca Roelofs, Mitchell Stern, Nathan Srebro, Benjamin Recht
Tetapi di sisi lain, makalah ini baru-baru ini mengusulkan pengoptimal tingkat pembelajaran adaptif baru yang seharusnya menutup kesenjangan antara metode tingkat adaptif dan SGD dengan momentum. " Menutup Celah Generalisasi Metode Gradien Adaptif dalam Pelatihan Jaringan Saraf Tiruan " oleh Jinghui Chen, Quanquan Gu
Metode gradien adaptif, yang mengadopsi informasi gradien historis untuk secara otomatis menyesuaikan tingkat pembelajaran, telah diamati untuk menggeneralisasi lebih buruk daripada stochastic gradient descent (SGD) dengan momentum dalam pelatihan jaringan saraf yang dalam. Ini meninggalkan cara untuk menutup kesenjangan generalisasi metode gradien adaptif masalah terbuka. Dalam karya ini, kami menunjukkan bahwa metode gradien adaptif seperti Adam, Amsgrad, kadang-kadang "terlalu beradaptasi". Kami merancang algoritma baru, yang disebut metode estimasi momentum adaptif sebagian (Padam), yang menyatukan Adam / Amsgrad dengan SGD untuk mencapai yang terbaik dari kedua dunia. Eksperimen pada tolok ukur standar menunjukkan bahwa Padam dapat mempertahankan laju konvergensi cepat sebagai Adam / Amsgrad sambil menggeneralisasi dan SGD dalam melatih jaringan saraf yang dalam.
Normalisasi
Skala data dapat membuat perbedaan besar dalam pelatihan.
Sebelum menyajikan data ke jaringan saraf, standarisasi data memiliki 0 mean dan varians unit, atau berbaring dalam interval kecil seperti dapat meningkatkan pelatihan. Ini sama dengan pra-pengkondisian, dan menghilangkan efek yang dimiliki unit pada bobot jaringan. Misalnya, panjang dalam milimeter dan panjang dalam kilometer keduanya mewakili konsep yang sama, tetapi berada pada skala yang berbeda. Rincian yang tepat tentang cara membakukan data bergantung pada seperti apa tampilan data Anda.[ - 0,5 , 0,5 ]
Normalisasi layer dapat meningkatkan pelatihan jaringan dengan menjaga mean berjalan dan standar deviasi untuk aktivasi neuron. Tidak dipahami mengapa hal ini membantu pelatihan, dan tetap merupakan area penelitian yang aktif.
- " Memahami Normalisasi Kelompok" oleh Johan Bjorck, Carla Gomes, Bart Selman
- " Menuju Pemahaman Teoritis Normalisasi Batch " oleh Jonas Kohler, Hadi Daneshmand, Aurelien Lucchi, Ming Zhou, Klaus Neymeyr, Thomas Hofmann
- " Bagaimana Normalisasi Batch Membantu Optimalisasi? (Tidak, Ini Bukan Soal Internal Covariate Shift) " oleh Shibani Santurkar, Dimitris Tsipras, Andrew Ilyas, Aleksander Madry
Regularisasi
Memilih dan menyelaraskan pengaturan jaringan adalah bagian penting dari membangun model yang menggeneralisasi dengan baik (yaitu, model yang tidak sesuai dengan data pelatihan). Namun, pada saat itu jaringan Anda sedang berjuang untuk mengurangi hilangnya data pelatihan - ketika jaringan tidak belajar - regularisasi dapat mengaburkan apa masalahnya.
Ketika jaringan saya tidak belajar, saya mematikan semua regularisasi dan memverifikasi bahwa jaringan yang tidak diatur berfungsi dengan benar. Lalu saya menambahkan setiap bagian regularisasi kembali, dan memverifikasi bahwa masing-masing bekerja di sepanjang jalan.
Taktik ini dapat menunjukkan dengan tepat di mana beberapa regularisasi mungkin tidak ditetapkan dengan baik. Beberapa contohnya adalah
L2 (alias pembusukan berat) atau regularisasi diatur terlalu besar, sehingga bobotnya tidak bisa bergerak.L1
Dua bagian dari regularisasi berada dalam konflik. Sebagai contoh, secara luas diamati bahwa normalisasi dan dropout layer sulit untuk digunakan bersama. Karena keduanya sangat berguna, memahami cara menggunakan keduanya adalah bidang penelitian yang aktif.
Simpan Buku Catatan Eksperimen
Ketika saya mengatur jaringan saraf, saya tidak membuat kode pengaturan parameter apa pun. Sebagai gantinya, saya melakukannya dalam file konfigurasi (mis., JSON) yang dibaca dan digunakan untuk mengisi detail konfigurasi jaringan saat runtime. Saya menyimpan semua file konfigurasi ini. Jika saya melakukan modifikasi parameter, saya membuat file konfigurasi baru. Akhirnya, saya menambahkan sebagai komentar semua kerugian per-zaman untuk pelatihan dan validasi.
Alasan mengapa saya begitu obsesif untuk mempertahankan hasil lama adalah karena ini membuatnya sangat mudah untuk kembali dan meninjau eksperimen sebelumnya. Ini juga lindung nilai terhadap kesalahan mengulangi percobaan buntu yang sama. Secara psikologis, juga memungkinkan Anda melihat kembali dan mengamati "Nah, proyek mungkin tidak di mana saya ingin menjadi hari ini, tapi saya membuat kemajuan dibandingkan ke tempat saya minggu yang lalu."k
Sebagai contoh, saya ingin belajar tentang model bahasa LSTM, jadi saya memutuskan untuk membuat bot Twitter yang menulis tweet baru sebagai tanggapan terhadap pengguna Twitter lainnya. Saya mengerjakan ini di waktu senggang saya, antara sekolah pascasarjana dan pekerjaan saya. Butuh waktu sekitar satu tahun, dan saya mengulangi sekitar 150 model yang berbeda sebelum sampai ke model yang melakukan apa yang saya inginkan: menghasilkan teks berbahasa Inggris baru yang (semacam) masuk akal. (Salah satu poin penting, dan sebagian alasan mengapa diperlukan begitu banyak upaya, adalah bahwa itu tidak cukup untuk hanya mendapatkan kehilangan sampel yang rendah, karena model awal yang kehilangan data awal telah berhasil menghafal data pelatihan, jadi itu hanya mereproduksi blok teks erat kata demi kata dalam konfirmasi - butuh beberapa penyesuaian untuk membuat model lebih spontan dan masih memiliki kehilangan rendah.)