Keras: jaringan saraf sederhana dengan data sederhana tidak berfungsi

Aug 20 2020

Saya mencoba membuat jaringan saraf yang sangat sederhana: satu lapisan tersembunyi, dengan 2 neuron. Untuk beberapa data yang sangat sederhana: hanya satu fitur.

import numpy as np
X=np.concatenate([np.linspace(0,10,100),np.linspace(11,20,100),np.linspace(21,30,100)])
y=np.concatenate([np.repeat(0,100),np.repeat(1,100),np.repeat(0,100)])

Ini modelnya

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, activation='sigmoid'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='sgd', metrics=['accuracy'])
model.fit(X, y, epochs=200)

Secara teori, model ini seharusnya berhasil. Tetapi bahkan setelah 1000 epoch, akurasinya masih 0,667.

Epoch 999/1000
10/10 [==============================] - 0s 1ms/step - loss: 0.5567 - accuracy: 0.6667
Epoch 1000/1000
10/10 [==============================] - 0s 2ms/step - loss: 0.5566 - accuracy: 0.6667

Saya pikir saya melakukan sesuatu yang salah. Bisakah Anda menyarankan beberapa modifikasi?

Tampaknya ada banyak minimum lokal dan inisialisasi dapat mengubah model akhir. Ini adalah kasus ketika menguji dengan paket nnetdi R. Saya harus menguji banyak benih, saya menemukan model ini (antara lain).

Dan ini adalah struktur yang ingin saya buat dengan keras: satu lapisan tersembunyi dengan 2 neuron. Fungsi aktivasi adalah sigmoid.

Jadi saya bertanya-tanya apakah keras memiliki masalah yang sama dengan inisialisasi. Dengan paket ini nnetdi R, saya pikir ini bukan paket yang "sempurna". Dan saya pikir keras akan lebih efektif. Jika inisialisasi penting, apakah keras menguji inisialisasi yang berbeda? Jika tidak mengapa? Mungkin karena secara umum, dengan lebih banyak data (dan lebih banyak fitur), ini berfungsi lebih baik (tanpa menguji banyak inisialisasi)?

Misalnya, dengan kmean, tampaknya inisialisasi yang berbeda diuji.

Jawaban

3 Mitiku Aug 26 2020 at 16:19

Pertanyaan ini menunjukkan pentingnya normalisasi data masukan untuk jaringan saraf. Tanpa normalisasi, terkadang melatih jaringan saraf sulit karena pengoptimalan mungkin macet di beberapa minimum lokal.

Saya ingin memulai dengan visualisasi kumpulan data. Datasetnya adalah 1D dan setelah dinormalisasi dengan normalisasi standar terlihat seperti berikut.

X_original = np.concatenate([np.linspace(0, 10, 100), np.linspace(
11, 20, 100), np.linspace(21, 30, 100)])
X = (X_original - X_original.mean())/X_original.std()

y = np.concatenate(
        [np.repeat(0, 100), np.repeat(1, 100), np.repeat(0, 100)])
plt.figure()
plt.scatter(X, np.zeros(X.shape[0]), c=y)
plt.show()

Cara terbaik untuk memisahkan titik data ini ke dalam kelas masing-masing adalah dengan menggambar dua garis pada ruang masukan. Karena ruang masukan adalah 1D, batas klasifikasi hanya berupa titik 1D.

Ini menyiratkan bahwa jaringan lapisan tunggal seperti regresi logistik tidak dapat mengklasifikasikan kumpulan data ini. Tetapi jaringan neural dengan dua lapisan yang diikuti oleh aktivasi nonlinier seharusnya dapat mengklasifikasikan kumpulan data tersebut.

Sekarang dengan normalisasi, dan skrip pelatihan berikut model dapat dengan mudah belajar untuk mengklasifikasikan poin.

model = Sequential()
model.add(Dense(2, activation='sigmoid'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
                  optimizer=keras.optimizers.Adam(1e-1), metrics=['accuracy'])
model.fit(X, y, epochs=20)

Train on 300 samples
Epoch 1/20
300/300 [==============================] - 1s 2ms/sample - loss: 0.6455 - accuracy: 0.6467
Epoch 2/20
300/300 [==============================] - 0s 79us/sample - loss: 0.6493 - accuracy: 0.6667
Epoch 3/20
300/300 [==============================] - 0s 85us/sample - loss: 0.6397 - accuracy: 0.6667
Epoch 4/20
300/300 [==============================] - 0s 100us/sample - loss: 0.6362 - accuracy: 0.6667
Epoch 5/20
300/300 [==============================] - 0s 115us/sample - loss: 0.6342 - accuracy: 0.6667
Epoch 6/20
300/300 [==============================] - 0s 96us/sample - loss: 0.6317 - accuracy: 0.6667
Epoch 7/20
300/300 [==============================] - 0s 93us/sample - loss: 0.6110 - accuracy: 0.6667
Epoch 8/20
300/300 [==============================] - 0s 110us/sample - loss: 0.5746 - accuracy: 0.6667
Epoch 9/20
300/300 [==============================] - 0s 142us/sample - loss: 0.5103 - accuracy: 0.6900
Epoch 10/20
300/300 [==============================] - 0s 124us/sample - loss: 0.4207 - accuracy: 0.9367
Epoch 11/20
300/300 [==============================] - 0s 124us/sample - loss: 0.3283 - accuracy: 0.9833
Epoch 12/20
300/300 [==============================] - 0s 124us/sample - loss: 0.2553 - accuracy: 0.9800
Epoch 13/20
300/300 [==============================] - 0s 138us/sample - loss: 0.2030 - accuracy: 1.0000
Epoch 14/20
300/300 [==============================] - 0s 124us/sample - loss: 0.1624 - accuracy: 1.0000
Epoch 15/20
300/300 [==============================] - 0s 150us/sample - loss: 0.1375 - accuracy: 1.0000
Epoch 16/20
300/300 [==============================] - 0s 122us/sample - loss: 0.1161 - accuracy: 1.0000
Epoch 17/20
300/300 [==============================] - 0s 115us/sample - loss: 0.1025 - accuracy: 1.0000
Epoch 18/20
300/300 [==============================] - 0s 126us/sample - loss: 0.0893 - accuracy: 1.0000
Epoch 19/20
300/300 [==============================] - 0s 121us/sample - loss: 0.0804 - accuracy: 1.0000
Epoch 20/20
300/300 [==============================] - 0s 132us/sample - loss: 0.0720 - accuracy: 1.0000

Karena modelnya sangat sederhana, pilihan kecepatan pembelajaran dan pengoptimal memengaruhi kecepatan pembelajaran. Dengan pengoptimal SGD dan kecepatan pembelajaran 1e-1, model mungkin memerlukan waktu lebih lama untuk dilatih daripada pengoptimal Adam dengan kecepatan pembelajaran yang sama.