Nano-neuron adalah versi neuron yang disederhanakan dari konsep jaringan saraf. Nano-neuron melakukan tugas yang paling sederhana dan dilatih untuk mengubah suhu dari derajat Celsius ke derajat Fahrenheit.
Kode NanoNeuron.js terdiri dari 7 fungsi JavaScript sederhana yang melibatkan pembelajaran, pelatihan, prediksi, dan propagasi sinyal model secara langsung dan mundur. Tujuan penulisan fungsi-fungsi ini adalah untuk memberikan pembaca sebuah penjelasan yang minimal dan mendasar (intuisi) tentang bagaimana, bagaimanapun, sebuah mesin dapat "belajar". Kode tidak menggunakan pustaka pihak ketiga. Seperti kata pepatah, hanya fungsi JavaScript "vanilla" yang sederhana.
Fungsi-fungsi ini sama sekali bukan panduan lengkap untuk pembelajaran mesin. Banyak konsep pembelajaran mesin hilang atau disederhanakan! Penyederhanaan ini diperbolehkan untuk tujuan tunggal - untuk memberikan pembaca pemahaman dan intuisi paling mendasar tentang bagaimana sebuah mesin dapat, pada prinsipnya, "belajar", sehingga, sebagai akibatnya, "MAGIC pembelajaran mesin" terdengar lebih dan lebih kepada pembaca sebagai "MATEMATIKA pembelajaran mesin".

Apa yang akan dipelajari oleh nano-neuron kami
Anda mungkin pernah mendengar tentang neuron dalam konteks jaringan saraf . Nano-neuron adalah versi yang disederhanakan dari neuron yang sama. Dalam contoh ini, kita akan menulis implementasinya dari awal. Untuk kesederhanaan, kami tidak akan membangun jaringan nano-neuron. Kami akan fokus pada pembuatan satu nano-neuron dan mencoba mengajarinya cara mengubah suhu dari derajat Celsius ke derajat Fahrenheit. Dengan kata lain, kami akan mengajarinya untuk memprediksi suhu dalam derajat Fahrenheit berdasarkan suhu dalam derajat Celsius.
Omong-omong, rumus untuk mengubah derajat Celcius ke derajat Fahrenheit adalah sebagai berikut:

Tetapi saat ini, nano-neuron kami tidak tahu apa-apa tentang formula ini ...
Model nano-neuron
Mari kita mulai dengan membuat fungsi yang menggambarkan model nano-neuron kita. Model ini adalah hubungan linear sederhana antara x
dan y
, yang terlihat seperti ini: y = w * x + b
. Sederhananya, nano-neuron kami adalah anak yang dapat menggambar garis lurus dalam sistem koordinat XY
.
Variabel w
dan b
adalah parameter model. Sebuah nano-neuron hanya tahu dua parameter fungsi linear ini. Parameter-parameter ini adalah apa yang akan dipelajari oleh nano-neuron kami selama proses pelatihan.
Satu-satunya hal yang dapat dilakukan oleh nano-neuron pada tahap ini adalah untuk mensimulasikan hubungan linier. Dia melakukan ini dalam metode predict()
, yang mengambil variabel x
pada input dan memprediksi variabel y
pada output. Tanpa sihir.
function NanoNeuron(w, b) { this.w = w; this.b = b; this.predict = (x) => { return x * this.w + this.b; } }
_ (... tunggu ... regresi linier adalah Anda, atau apa?) _
Konversi derajat Celcius ke derajat Fahrenheit
Suhu dalam derajat Celsius dapat dikonversi ke derajat Fahrenheit sesuai dengan rumus: f = 1.8 * c + 32
, di mana c
adalah suhu dalam derajat Celsius dan f
adalah suhu dalam derajat Fahrenheit.
function celsiusToFahrenheit(c) { const w = 1.8; const b = 32; const f = c * w + b; return f; };
Sebagai hasilnya, kami ingin nano-neuron kami dapat mensimulasikan fungsi khusus ini. Dia harus menebak (mengetahui) bahwa parameter w = 1.8
dan b = 32
tanpa mengetahuinya terlebih dahulu.
Beginilah tampilan fungsi konversi pada bagan. Itulah yang harus dipelajari "bayi" nano-saraf kami untuk "menggambar":

Pembuatan data
Dalam pemrograman klasik, kita tahu input data ( x
) dan algoritma untuk mengkonversi data ini (parameter w
dan b
), tetapi data output ( y
) tidak diketahui. Output dihitung berdasarkan input menggunakan algoritma yang dikenal. Dalam pembelajaran mesin, sebaliknya, hanya data input dan output ( x
dan y
) yang diketahui, tetapi algoritma untuk beralih dari x
ke y
diketahui (parameter w
dan b
).
Ini adalah generasi input dan output yang akan kita lakukan sekarang. Kita perlu menghasilkan data untuk melatih model kita dan data untuk menguji model. Fungsi pembantu celsiusToFahrenheit()
akan membantu kami dalam hal ini. Masing-masing set data pelatihan dan tes adalah satu set pasangan x
dan y
. Misalnya, jika x = 2
, maka y = 35,6
dan seterusnya.
Di dunia nyata, sebagian besar data kemungkinan dikumpulkan , bukan dihasilkan . Misalnya, data yang dikumpulkan tersebut dapat berupa serangkaian "foto wajah" -> "nama orang".
Kami akan menggunakan dataset PELATIHAN untuk melatih nano-neuron kami. Sebelum dia tumbuh dan mampu mengambil keputusan sendiri, kita harus mengajarinya apa yang "benar" dan apa yang "salah" menggunakan data "benar" dari set pelatihan.
Omong-omong, di sini prinsip kehidupan "sampah di pintu masuk - sampah di pintu keluar" jelas ditelusuri. Jika nano-neuron melemparkan "kebohongan" ke dalam kit pelatihan bahwa 5 ° C dikonversi menjadi 1000 ° F, maka setelah banyak iterasi pelatihan, ia akan percaya ini dan akan dengan benar mengkonversi semua nilai suhu kecuali 5 ° C. Kita harus sangat berhati-hati dengan data pelatihan yang kita muat setiap hari ke dalam jaringan saraf otak kita.
Terganggu. Mari kita lanjutkan.
Kami akan menggunakan set data TEST untuk menilai seberapa baik nano-neuron kami telah dilatih dan dapat membuat prediksi yang benar pada data baru yang tidak dia lihat selama pelatihannya.
function generateDataSets() {
Estimasi kesalahan prediksi
Kita membutuhkan metrik tertentu (pengukuran, jumlah, peringkat) yang akan menunjukkan seberapa dekat prediksi nano-neuron dengan true. Dengan kata lain, angka / metrik / fungsi ini harus menunjukkan seberapa benar atau salahnya neuron nano. Seperti di sekolah, seorang siswa bisa mendapat nilai 5
atau 2
untuk kendalinya.
Dalam kasus nano-neuron, kesalahannya (kesalahan) antara nilai sebenarnya dari y
dan nilai prediction
akan dihasilkan oleh rumus:

Seperti dapat dilihat dari rumus, kita akan menganggap kesalahan sebagai perbedaan sederhana antara kedua nilai. Semakin dekat nilainya satu sama lain, semakin kecil perbedaannya. Kami menggunakan kuadrat di sini untuk menyingkirkan tanda, sehingga pada akhirnya (1 - 2) ^ 2
setara dengan (2 - 1) ^ 2
. Pembagian dengan 2
terjadi semata-mata untuk menyederhanakan makna turunan dari fungsi ini dalam rumus untuk propagasi kembali sinyal (lebih lanjut tentang ini di bawah).
Fungsi kesalahan dalam hal ini akan terlihat seperti ini:
function predictionCost(y, prediction) { return (y - prediction) ** 2 / 2;
Perambatan sinyal langsung
Perambatan sinyal langsung melalui model kami berarti membuat prediksi untuk semua pasangan dari yTrain
data pelatihan yTrain
dan yTrain
dan menghitung rata-rata kesalahan (error) dari prediksi ini.
Kami hanya membiarkan nano-neuron kami "berbicara", memungkinkannya untuk membuat prediksi (mengkonversi suhu). Pada saat yang sama, nano-neuron pada tahap ini bisa sangat salah. Nilai rata-rata kesalahan prediksi akan menunjukkan kepada kita seberapa jauh model kita / mendekati kebenaran saat ini. Nilai kesalahan sangat penting di sini, karena dengan mengubah parameter w
dan b
dan propagasi sinyal langsung lagi, kita dapat mengevaluasi apakah nano-neuron kita telah menjadi "lebih pintar" dengan parameter baru atau tidak.
Kesalahan prediksi rata-rata nano-neuron akan dilakukan menggunakan rumus berikut:

Di mana m
adalah jumlah salinan pelatihan (dalam kasus kami, kami memiliki 100
pasangan data).
Inilah cara kami dapat menerapkan ini dalam kode:
function forwardPropagation(model, xTrain, yTrain) { const m = xTrain.length; const predictions = []; let cost = 0; for (let i = 0; i < m; i += 1) { const prediction = nanoNeuron.predict(xTrain[i]); cost += predictionCost(yTrain[i], prediction); predictions.push(prediction); }
Propagasi Balik Sinyal
Sekarang kita tahu bagaimana nano-neuron kita benar atau salah dalam prediksi (berdasarkan nilai rata-rata kesalahan), bagaimana kita bisa membuat prediksi lebih akurat?
Perambatan sinyal terbalik akan membantu kita dalam hal ini. Perambatan kembali sinyal adalah proses mengevaluasi kesalahan dari nano-neuron dan kemudian menyesuaikan parameternya w
dan b
sehingga prediksi nano-neuron berikutnya untuk seluruh rangkaian data pelatihan menjadi sedikit lebih akurat.
Di sinilah pembelajaran mesin menjadi seperti sihir. Konsep kunci di sini adalah turunan dari fungsi , yang menunjukkan ukuran langkah apa dan ke arah mana kita perlu mengambil untuk mendekati minimum fungsi (dalam kasus kami, minimum fungsi kesalahan).
Tujuan akhir pelatihan nano-neuron adalah untuk menemukan minimum fungsi kesalahan (lihat fungsi di atas). Jika kita dapat menemukan nilai w
dan b
di mana nilai rata-rata dari fungsi kesalahan kecil, maka ini berarti nano-neuron kita dapat mengatasi prediksi suhu dalam derajat Fahrenheit dengan baik.
Derivatif adalah topik besar dan terpisah yang tidak akan kita bahas dalam artikel ini. MathIsFun adalah sumber yang bagus yang dapat memberikan pemahaman dasar tentang turunan.
Satu hal yang harus kita pelajari dari esensi derivatif dan yang akan membantu kita memahami bagaimana backpropagation sinyal bekerja adalah bahwa turunan dari suatu fungsi pada titik x
dan y
, menurut definisi, adalah garis singgung pada kurva fungsi ini di x
dan y
dan menunjukkan kita arah ke minimum fungsi .

Gambar diambil dari MathIsFun
Misalnya, dalam grafik di atas, Anda melihat bahwa pada titik (x=2, y=4)
kemiringan garis singgung menunjukkan kepada kita bahwa kita perlu bergerak ke
dan ke
untuk mencapai minimum fungsi. Juga perhatikan bahwa semakin besar kemiringan garis singgung, semakin cepat kita harus bergerak ke titik minimum.
Turunan dari fungsi rata-rata kesalahan rata-rata averageCost
dengan parameter w
dan b
akan terlihat seperti ini:


Di mana m
adalah jumlah salinan pelatihan (dalam kasus kami, kami memiliki 100
pasangan data).
Anda dapat membaca lebih detail tentang cara mengambil turunan dari fungsi kompleks di sini .
function backwardPropagation(predictions, xTrain, yTrain) { const m = xTrain.length;
Pelatihan model
Sekarang kita tahu bagaimana memperkirakan kesalahan / kesalahan prediksi model nano-neuron kami untuk semua data pelatihan (propagasi sinyal langsung). Kita juga tahu bagaimana menyesuaikan parameter w
dan b
model nano-neuron (propagasi balik sinyal) untuk meningkatkan akurasi prediksi. Masalahnya adalah jika kita melakukan propagasi sinyal maju dan mundur hanya sekali, maka ini tidak akan cukup bagi model kita untuk mengidentifikasi dan mempelajari dependensi dan hukum dalam data pelatihan. Anda dapat membandingkan ini dengan kunjungan sekolah satu hari siswa. Dia harus pergi ke sekolah secara teratur, hari demi hari, tahun demi tahun, untuk mempelajari semua materi.
Jadi, kita harus mengulangi propagasi maju dan mundur sinyal berkali-kali. Inilah yang dilakukan trainModel()
. Dia seperti "guru" untuk model nano-neuron kami:
- dia akan menghabiskan waktu (
epochs
) dengan nano-neuron kita yang masih konyol, mencoba untuk melatihnya, - dia akan menggunakan buku-buku khusus (
yTrain
data yTrain
dan yTrain
) untuk pelatihan, - itu mendorong "siswa" kami untuk belajar lebih rajin (lebih cepat) menggunakan parameter
alpha
, yang pada dasarnya mengendalikan kecepatan belajar.
Beberapa kata tentang parameter alpha
. Ini hanya koefisien (pengganda) untuk nilai-nilai variabel dW
dan dB
, yang kami hitung selama propagasi belakang sinyal. Jadi, turunannya menunjukkan kepada kita arah ke minimum fungsi kesalahan (tanda-tanda nilai dW
dan dB
memberi tahu kita tentang hal ini). Derivatif juga menunjukkan kepada kita seberapa cepat kita perlu bergerak menuju minimum fungsi (nilai absolut dW
dan dB
memberi tahu kita tentang hal ini). Sekarang kita perlu mengalikan ukuran langkah dengan alpha
untuk menyesuaikan kecepatan pendekatan kita ke minimum (ukuran langkah total). Kadang-kadang, jika kita menggunakan nilai besar untuk alpha
, kita bisa melakukan langkah besar sehingga kita hanya bisa melangkahi minimum dari fungsi, sehingga melewatkannya.
Dengan analogi dengan "guru", semakin kuat dia akan memaksa "siswa-nano" kita untuk belajar, semakin cepat dia akan belajar, TETAPI, jika Anda memaksakan dan menekannya dengan sangat keras, "siswa-nano" kita mungkin mengalami gangguan saraf dan sepenuhnya apatis dan dia tidak akan belajar apa pun.
Kami akan memperbarui parameter model kami w
dan b
sebagai berikut:


Dan inilah bagaimana pelatihan itu sendiri terlihat:
function trainModel({model, epochs, alpha, xTrain, yTrain}) {
Menyatukan semua fitur
Waktu untuk menggunakan semua fungsi yang dibuat sebelumnya bersama-sama.
Buat instance dari model nano-neuron. Saat ini, nano-neuron tidak tahu apa-apa tentang parameter w
dan b
. Jadi mari kita atur w
dan b
secara acak.
const w = Math.random();
Kami menghasilkan set pelatihan dan data uji.
const [xTrain, yTrain, xTest, yTest] = generateDataSets();
Sekarang mari kita coba latih model kita menggunakan langkah-langkah kecil ( 0.0005
) untuk 70000
era. Anda dapat bereksperimen dengan parameter ini, mereka ditentukan secara empiris.
const epochs = 70000; const alpha = 0.0005; const trainingCostHistory = trainModel({model: nanoNeuron, epochs, alpha, xTrain, yTrain});
Mari kita periksa bagaimana nilai kesalahan model kami berubah selama pelatihan. Kami berharap bahwa nilai kesalahan setelah pelatihan harus jauh lebih sedikit daripada sebelum pelatihan. Ini berarti nano-neuron kita lebih bijaksana. Pilihan sebaliknya juga dimungkinkan, ketika setelah pelatihan, kesalahan prediksi hanya meningkat (misalnya, nilai besar dari langkah alpha
pembelajaran).
console.log(' :', trainingCostHistory[0]);
Dan di sini adalah bagaimana nilai kesalahan model berubah selama pelatihan. Pada sumbu x
adalah zaman (dalam ribuan). Kami berharap grafik akan menurun.

Mari kita lihat parameter apa yang dipelajari nano-neuron kita. Kami berharap bahwa parameter w
dan b
akan mirip dengan parameter dengan nama yang sama dari fungsi celsiusToFahrenheit()
( w = 1.8
dan b = 32
), karena itu adalah nano-neuron yang saya coba simulasikan.
console.log(' -:', {w: nanoNeuron.w, b: nanoNeuron.b});
Seperti yang Anda lihat, nano-neuron sangat dekat dengan fungsi celsiusToFahrenheit()
.
Sekarang mari kita lihat seberapa akurat prediksi nano-neuron kita untuk data uji yang tidak dia lihat selama pelatihan. Kesalahan prediksi untuk data uji harus dekat dengan kesalahan prediksi untuk data pelatihan. Ini berarti bahwa nano-neuron telah mempelajari dependensi yang benar dan dapat dengan benar mengabstraksikan pengalamannya dari data yang sebelumnya tidak diketahui (ini adalah nilai keseluruhan model).
[testPredictions, testCost] = forwardPropagation(nanoNeuron, xTest, yTest); console.log(' :', testCost);
Sekarang, karena "nano-baby" kami terlatih dengan baik di "sekolah" dan sekarang tahu bagaimana mengkonversi derajat Celsius ke derajat Fahrenheit secara akurat bahkan untuk data yang tidak dia lihat, kita dapat memanggilnya "cukup pintar". Sekarang kita bahkan bisa meminta saran padanya tentang konversi suhu, dan itulah tujuan dari seluruh pelatihan.
const tempInCelsius = 70; const customPrediction = nanoNeuron.predict(tempInCelsius); console.log(`- "", ${tempInCelsius}°C :`, customPrediction);
Sangat dekat! Seperti orang lain, nano-neuron kami baik, tetapi tidak sempurna :)
Pengodean yang berhasil!
Cara menjalankan dan menguji nano-neuron
Anda dapat mengkloning repositori dan menjalankan nano neuron secara lokal:
git clone https://github.com/trekhleb/nano-neuron.git cd nano-neuron
node ./NanoNeuron.js
Konsep yang terlewatkan
Konsep pembelajaran mesin berikut telah dihilangkan atau disederhanakan untuk kemudahan penjelasan.
Pemisahan set pelatihan dan data uji
Biasanya Anda memiliki satu set data besar. Bergantung pada jumlah salinan dalam set ini, pembagiannya ke dalam set pelatihan dan tes dapat dilakukan dalam proporsi 70/30. Data di set harus dicampur secara acak sebelum dipisah. Jika jumlah data besar (misalnya, jutaan), maka pembagian ke dalam set tes dan pelatihan dapat dilakukan dalam proporsi mendekati 90/10 atau 95/5.
Kekuatan online
Biasanya Anda tidak akan menemukan kasus ketika hanya satu neuron yang digunakan. Kekuatan ada di jaringan neuron semacam itu. Jaringan saraf dapat mempelajari ketergantungan yang jauh lebih kompleks.
Juga dalam contoh di atas, nano-neuron kami mungkin terlihat lebih seperti regresi linier sederhana daripada jaringan saraf.
Input Normalisasi
Sebelum pelatihan, biasanya untuk menormalkan data input .
Implementasi vektor
Untuk jaringan saraf, perhitungan vektor (matriks) jauh lebih cepat daripada perhitungan for
loop. Biasanya propagasi sinyal langsung dan mundur dilakukan menggunakan operasi matriks menggunakan, misalnya, perpustakaan Python Numpy .
Fungsi Kesalahan Minimum
Fungsi kesalahan yang kami gunakan untuk neuron nano sangat sederhana. Itu harus mengandung komponen logaritmik . Suatu perubahan dalam rumus untuk fungsi kesalahan juga akan memerlukan perubahan dalam formula untuk perambatan sinyal maju dan mundur.
Fungsi aktivasi
Biasanya nilai output neuron melewati fungsi aktivasi. Untuk aktivasi, fungsi-fungsi seperti Sigmoid , ReLU dan lainnya dapat digunakan.