R neuralnet - compute memberikan jawaban yang konstan

11

Saya mencoba menggunakan neuralnetpaket R (dokumentasi di sini ) untuk prediksi.

Inilah yang saya coba lakukan:

library(neuralnet)
x <- cbind(runif(50, min=1, max=500), runif(50, min=1, max=500))
y <- x[, 1] * x[, 2]
train <- data.frame(x, y)
n <- names(train)
f <- as.formula(paste('y ~', paste(n[!n %in% 'y'], collapse = ' + ')))
net <- neuralnet(f, train, hidden = c(5, 5), threshold=0.01)
print(net)

all: neuralnet(formula = f, data = train, hidden = c(5, 5), threshold = 0.01)

1 repetition was calculated.

    Error Reached Threshold Steps
1 66136930789    0.004658283648 97938

test <- cbind(runif(10, min=1, max=500), runif(10, min=1, max=500))
res <- compute(net, test)
res$net.result
         [,1]
[1,] 58749.01798
[2,] 58749.01798
[3,] 58749.01798
[4,] 58749.01798
[5,] 58749.01798
[6,] 58749.01798
[7,] 58749.01798
[8,] 58749.01798
[9,] 58749.01798
[10,] 58749.01798

Adakah yang bisa menjelaskan mengapa kesalahan begitu besar dan mengapa semua nilai yang diprediksi hampir konstan?

luckyi
sumber

Jawaban:

6

Saya bukan ahli dalam jaring saraf tetapi saya pikir poin-poin berikut mungkin membantu Anda. Ada juga beberapa posting yang bagus, misalnya yang ini di unit tersembunyi , yang bisa Anda cari di situs ini tentang apa yang dilakukan jaring saraf yang mungkin berguna bagi Anda.

1 Kesalahan besar: mengapa contoh Anda tidak berfungsi sama sekali

mengapa kesalahan begitu besar dan mengapa semua nilai yang diprediksi hampir konstan?

Ini karena jaringan saraf tidak dapat menghitung fungsi perkalian yang Anda berikan dan mengeluarkan angka konstan di tengah rentang y, terlepas dari x, adalah cara terbaik untuk meminimalkan kesalahan selama pelatihan. (Perhatikan bagaimana 58749 cukup dekat dengan rata-rata mengalikan dua angka antara 1 dan 500 secara bersamaan.)

Sangat sulit untuk melihat bagaimana jaringan saraf dapat menghitung fungsi multiplikasi dengan cara yang masuk akal. Pikirkan tentang bagaimana setiap node dalam jaringan menggabungkan hasil yang dihitung sebelumnya: Anda mengambil jumlah tertimbang dari output dari node sebelumnya (dan kemudian menerapkan fungsi sigmoidal untuk itu, lihat, misalnya Pengantar Jaringan Saraf Tiruan , untuk mengeruk output di antara dan ). Bagaimana Anda akan mendapatkan jumlah tertimbang untuk memberi Anda kelipatan dua input? (Saya kira, bagaimanapun, bahwa mungkin untuk mengambil banyak lapisan tersembunyi untuk membuat multiplikasi bekerja dengan cara yang sangat dibuat-buat.)111

2 Minima lokal: mengapa contoh yang masuk akal secara teoritis mungkin tidak berfungsi

Namun, bahkan ketika mencoba melakukan penambahan Anda mengalami masalah dalam contoh Anda: jaringan tidak berhasil berlatih. Saya percaya bahwa ini karena masalah kedua: mendapatkan minimum lokal selama pelatihan. Bahkan, sebagai tambahan, menggunakan dua lapisan 5 unit tersembunyi terlalu rumit untuk menghitung penambahan. Jaringan tanpa unit tersembunyi berlatih dengan sangat baik:

x <- cbind(runif(50, min=1, max=500), runif(50, min=1, max=500))
y <- x[, 1] + x[, 2]
train <- data.frame(x, y)
n <- names(train)
f <- as.formula(paste('y ~', paste(n[!n %in% 'y'], collapse = ' + ')))
net <- neuralnet(f, train, hidden = 0, threshold=0.01)
print(net) # Error 0.00000001893602844

Tentu saja, Anda bisa mengubah masalah asli Anda menjadi masalah tambahan dengan mengambil log, tapi saya rasa ini bukan yang Anda inginkan, jadi teruskan ...

3 Jumlah contoh pelatihan dibandingkan dengan jumlah parameter untuk diperkirakan

Jadi apa cara yang masuk akal untuk menguji jaring saraf Anda dengan dua lapis 5 unit tersembunyi seperti yang Anda miliki semula? Jaring saraf sering digunakan untuk klasifikasi, jadi memutuskan apakah tampaknya merupakan pilihan masalah yang masuk akal. Saya menggunakan dan . Perhatikan bahwa ada beberapa parameter yang harus dipelajari.k = ( 1 , 2 , 3 , 4 , 5 ) c = 3750xk>ck=(1,2,3,4,5)c=3750

Dalam kode di bawah ini saya mengambil pendekatan yang sangat mirip dengan Anda kecuali bahwa saya melatih dua jaring saraf, satu dengan 50 contoh dari set pelatihan, dan satu dengan 500.

library(neuralnet)
set.seed(1) # make results reproducible
N=500
x <- cbind(runif(N, min=1, max=500), runif(N, min=1, max=500), runif(N, min=1, max=500), runif(N, min=1, max=500), runif(N, min=1, max=500))
y <- ifelse(x[,1] + 2*x[,1] + 3*x[,1] + 4*x[,1] + 5*x[,1] > 3750, 1, 0)
trainSMALL <- data.frame(x[1:(N/10),], y=y[1:(N/10)])
trainALL <- data.frame(x, y)
n <- names(trainSMALL)
f <- as.formula(paste('y ~', paste(n[!n %in% 'y'], collapse = ' + ')))
netSMALL <- neuralnet(f, trainSMALL, hidden = c(5,5), threshold = 0.01)
netALL <- neuralnet(f, trainALL, hidden = c(5,5), threshold = 0.01)
print(netSMALL) # error 4.117671763
print(netALL) # error 0.009598461875

# get a sense of accuracy w.r.t small training set (in-sample)
cbind(y, compute(netSMALL,x)$net.result)[1:10,]
      y                 
 [1,] 1  0.587903899825
 [2,] 0  0.001158500142
 [3,] 1  0.587903899825
 [4,] 0  0.001158500281
 [5,] 0 -0.003770868805
 [6,] 0  0.587903899825
 [7,] 1  0.587903899825
 [8,] 0  0.001158500142
 [9,] 0  0.587903899825
[10,] 1  0.587903899825

# get a sense of accuracy w.r.t full training set (in-sample)
cbind(y, compute(netALL,x)$net.result)[1:10,]
      y                 
 [1,] 1  1.0003618092051
 [2,] 0 -0.0025677656844
 [3,] 1  0.9999590121059
 [4,] 0 -0.0003835722682
 [5,] 0 -0.0003835722682
 [6,] 0 -0.0003835722199
 [7,] 1  1.0003618092051
 [8,] 0 -0.0025677656844
 [9,] 0 -0.0003835722682
[10,] 1  1.0003618092051

Jelas bahwa netALLmelakukan jauh lebih baik! Kenapa ini? Lihatlah apa yang Anda dapatkan dengan plot(netALL)perintah:

masukkan deskripsi gambar di sini

Saya membuatnya menjadi 66 parameter yang diperkirakan selama pelatihan (5 input dan 1 input bias untuk masing-masing 11 node). Anda tidak dapat memperkirakan 66 parameter dengan 50 contoh pelatihan dengan andal. Saya menduga dalam hal ini Anda mungkin dapat mengurangi jumlah parameter untuk diperkirakan dengan mengurangi jumlah unit. Dan Anda dapat melihat dari membangun jaringan saraf untuk melakukan penambahan bahwa jaringan saraf yang lebih sederhana mungkin kurang mengalami masalah selama pelatihan.

Tetapi sebagai aturan umum dalam pembelajaran mesin apa pun (termasuk regresi linier) Anda ingin memiliki lebih banyak contoh pelatihan daripada perkiraan parameter.

TooTone
sumber
1
Banyak informasi untuk dipikirkan, terima kasih! Anda benar sekali! Jika variabel dinormalisasi, jumlah contoh pelatihan lebih besar dan jumlah neuron pada satu lapisan tersembunyi sama dengan satu, itu akan terlihat jauh lebih baik. Tentu saja, bukan fungsi perkalian tetapi sesuatu yang serupa. Ah, jika saya mendapat respons luar biasa 2 minggu yang lalu, semuanya akan lebih mudah. Namun, sangat berterima kasih atas balasan Anda, terima kasih!
luckyi