Saya melatih jaringan saraf (detail tidak penting) di mana data target adalah vektor sudut (antara 0 dan 2 * pi). Saya mencari saran tentang cara menyandikan data ini. Inilah yang sedang saya coba (dengan kesuksesan terbatas):
1) Pengodean 1-of-C: I bin pengaturan kemungkinan sudut menjadi 1000 atau lebih sudut diskrit dan kemudian menunjukkan sudut tertentu dengan menempatkan 1 pada indeks yang relevan. Masalah dengan ini, adalah bahwa jaringan hanya belajar untuk mengeluarkan semua 0 (karena ini hampir persis benar).
2) Penskalaan sederhana: Saya meningkatkan rentang output jaringan ([0,1]) menjadi [0,2 * pi]. Masalahnya di sini adalah bahwa sudut secara alami memiliki topologi melingkar (yaitu 0,0001 dan 2 * pi sebenarnya bersebelahan). Dengan jenis pengkodean ini, informasi itu hilang.
Setiap saran akan sangat dihargai!
sumber
Jawaban:
pengantar
Saya menemukan pertanyaan ini sangat menarik, saya berasumsi seseorang telah meletakkan kertas di atasnya, tapi ini hari libur saya, jadi saya tidak ingin mengejar referensi.
Jadi kita bisa menganggapnya sebagai representasi / pengkodean dari output, yang saya lakukan dalam jawaban ini. Saya tetap berpikir bahwa ada cara yang lebih baik, di mana Anda bisa menggunakan fungsi kerugian yang sedikit berbeda. (Mungkin jumlah perbedaan kuadrat, menggunakan modulo pengurangan 2 ).π
Tetapi selanjutnya dengan jawaban yang sebenarnya.
metode
Saya mengusulkan bahwa sudut direpresentasikan sebagai sepasang nilai, sinus dan cosinus nya.θ
Jadi fungsi encoding adalah: dan fungsi penguraiannya adalah:θ ↦ ( dosa( θ ) , cos( θ ) ) ( y1, y2) ↦ arctan2 ( y1, y2)
Untukarctan2menjadi garis singgung terbalik, menjaga arah di semua kuadran)
Secara teori, Anda dapat bekerja secara setara dengan sudut jika alat Anda digunakan didukung
atan2
sebagai fungsi layer (mengambil tepat 2 input dan menghasilkan 1 output). TensorFlow melakukan ini sekarang, dan mendukung penurunan gradien di atasnya , meskipun tidak dimaksudkan untuk penggunaan ini. Saya menyelidiki menggunakanout = atan2(sigmoid(ylogit), sigmoid(xlogit))
dengan fungsi kerugianmin((pred - out)^2, (pred - out - 2pi)^2)
. Saya menemukan bahwa itu dilatih jauh lebih buruk daripada menggunakanouts = tanh(ylogit), outc = tanh(xlogit))
dengan fungsi kehilangan0.5((sin(pred) - outs)^2 + (cos(pred) - outc)^2
. Yang saya pikir dapat dikaitkan dengan gradien yang terputus-putusatan2
Pengujian saya di sini menjalankannya sebagai fungsi preprocessing
Untuk mengevaluasi ini saya mendefinisikan tugas:
Saya menerapkan fungsi secara acak menghasilkan gambar-gambar ini, dengan garis di sudut acak (NB: versi sebelumnya dari posting ini menggunakan lereng acak, bukan sudut acak. Terima kasih kepada @Ari Herman untuk menunjukkannya. Sekarang sudah diperbaiki). Saya membangun beberapa jaringan saraf untuk mengevaluasi kinerja di sana. Detail lengkap implementasinya ada di notebook Jupyter ini . Semua kode dalam Julia , dan saya menggunakan perpustakaan jaringan saraf Mocha .
Sebagai perbandingan, saya menyajikannya terhadap metode penskalaan alternatif ke 0,1. dan untuk memasukkan ke dalam 500 nampan dan menggunakan softmax soft-label. Saya tidak terlalu senang dengan yang terakhir, dan merasa saya perlu mengubahnya. Itulah sebabnya, tidak seperti yang lain saya hanya mengujinya untuk 1.000 iterasi, vs dua lainnya yang dijalankan untuk 1.000 dan 10.000
Pengaturan eksperimen
Untuk setiap jejak 1.000 pelatihan, dan 1.000 gambar uji dihasilkan secara acak.
Jaringan evaluasi memiliki satu lapisan tersembunyi dengan lebar 500. Neuron Sigmoid digunakan dalam lapisan tersembunyi.
Itu dilatih oleh Stochastic Gradient Decent, dengan tingkat pembelajaran tetap 0,01, dan momentum tetap 0,9.
Tidak ada regularisasi, atau putus sekolah yang digunakan. Juga tidak ada konvolusi dll. Jaringan sederhana, yang saya harap menyarankan bahwa hasil ini akan digeneralisasi
Sangat mudah untuk mengubah parameter ini dalam kode uji , dan saya mendorong orang untuk melakukannya. (dan cari bug dalam tes).
Hasil
Hasil saya adalah sebagai berikut:
Saya juga menyajikan akurasi pada berbagai tingkat granularity. Keakuratan menjadi bagian dari kasus uji itu jadi berkarat. Jadi
accuracy_to_point01
berarti itu dihitung sebagai benar jika output berada dalam 0,01 dari sudut yang sebenarnya. Tak satu pun dari representasi mendapatkan hasil yang sempurna, tapi itu sama sekali tidak mengejutkan mengingat bagaimana matematika floating point bekerja.Jika Anda melihat sejarah posting ini Anda akan melihat hasilnya memang sedikit berisik, sedikit berbeda setiap kali saya memutarnya kembali. Tetapi urutan umum dan skala nilai tetap sama; sehingga memungkinkan kita untuk menarik beberapa kesimpulan.
Diskusi
Pengkodean sin / cos berkinerja jauh lebih baik daripada pengodean 0-1 yang diskalakan. Peningkatannya adalah sejauh pada 1.000 pelatihan iterasi dosa / cos melakukan sekitar 3 kali lebih baik pada kebanyakan metrik daripada skala adalah pada 10.000 iterasi.
Saya pikir, sebagian ini terkait dengan peningkatan generalisasi, karena keduanya mendapatkan kesalahan kuadrat rata-rata yang hampir sama pada set pelatihan, setidaknya sekali 10.000 iterasi dijalankan.
Tampaknya juga bahwa pada skala absolut untuk bergerak melampaui kinerja ini, jaringan saraf yang lebih baik diperlukan. Daripada yang sangat sederhana yang diuraikan di atas dalam pengaturan eksperimental.
Kesimpulan.
Tampaknya representasi dosa / cos sejauh ini adalah yang terbaik, dari representasi yang saya selidiki di sini. Ini masuk akal, karena memang memiliki nilai yang halus saat Anda bergerak di sekitar lingkaran. Saya juga suka bahwa kebalikannya dapat dilakukan dengan arctan2 , yang elegan.
sumber
tan(angle)
Berikut ini adalah implementasi Python lain yang membandingkan pengodean yang diusulkan Lyndon White dengan pendekatan binned. Kode di bawah ini menghasilkan output berikut:
sumber
Ini versi percobaan Python saya. Saya menyimpan banyak detail implementasi Anda yang sama, khususnya saya menggunakan ukuran gambar yang sama, ukuran lapisan jaringan, tingkat pembelajaran, momentum, dan metrik kesuksesan.
Setiap jaringan yang diuji memiliki satu lapisan tersembunyi (ukuran = 500) dengan neuron logistik. Neuron output berupa linear atau softmax seperti disebutkan. Saya menggunakan 1.000 gambar latihan dan 1.000 gambar uji yang dibuat secara independen, secara acak (jadi mungkin ada pengulangan). Pelatihan terdiri dari 50 iterasi melalui set pelatihan.
Saya bisa mendapatkan akurasi yang cukup baik menggunakan pengkodean binning dan "gaussian" (nama saya dibuat; mirip dengan binning kecuali bahwa vektor output target memiliki bentuk exp (-pi * ([1,2,3, ... , 500] - idx) ** 2) di mana idx adalah indeks yang sesuai dengan sudut yang benar). Kode di bawah ini; inilah hasil saya:
Kesalahan tes untuk penyandian (cos, sin):
1.000 gambar pelatihan, 1.000 gambar uji, 50 iterasi, output linier
Berarti: 0,0911558142071
Median: 0,0429723541743
Minimum: 2.77769843793e-06
Maksimal: 6.2608513539
Akurasi menjadi 0,1: 85,2%
Akurasi hingga 0,01: 11,6%
Akurasi hingga 0,001: 1,0%
Kesalahan tes untuk penyandian [-1,1]:
1.000 gambar pelatihan, 1.000 gambar uji, 50 iterasi, output linier
Berarti: 0,234181700523
Median: 0.17460197307
Minimal: 0,000473665840258
Maksimal: 6.00637777237
Akurasi menjadi 0,1: 29,9%
Akurasi hingga 0,01: 3,3%
Akurasi hingga 0,001: 0,1%
Kesalahan tes untuk penyandian 1-of-500:
1.000 gambar pelatihan, 1.000 gambar uji, 50 iterasi, output softmax
Berarti: 0,0298767021922
Median: 0,00388858079174
Minimum: 4.08712407829e-06
Maksimal: 6.2784479965
Akurasi menjadi 0,1: 99,6%
Akurasi hingga 0,01: 88,9%
Akurasi hingga 0,001: 13,5%
Kesalahan tes untuk penyandian gaussian:
1.000 gambar pelatihan, 1.000 gambar uji, 50 iterasi, output softmax
Saya tidak tahu mengapa hasil kami tampaknya bertentangan satu sama lain, tetapi tampaknya perlu diselidiki lebih lanjut.
sumber
Cara lain untuk menyandikan sudut adalah sebagai satu set dari dua nilai:
Ini akan memiliki masalah yang mirip dengan arctan2 dalam hal gradien tidak terdefinisi pada theta = 0. Saya tidak punya waktu untuk melatih jaringan dan membandingkan dengan pengkodean lainnya tetapi dalam makalah ini teknik ini kelihatannya cukup berhasil.
sumber