Saya mencoba melatih CNN untuk mengkategorikan teks berdasarkan topik. Ketika saya menggunakan cross-entropy biner saya mendapatkan akurasi ~ 80%, dengan cross-entropy kategoris saya mendapatkan akurasi ~ 50%.
Saya tidak mengerti mengapa ini terjadi. Ini masalah multikelas, bukankah itu berarti saya harus menggunakan cross-entropy kategoris dan bahwa hasil dengan binary cross-entropy tidak ada artinya?
model.add(embedding_layer)
model.add(Dropout(0.25))
# convolution layers
model.add(Conv1D(nb_filter=32,
filter_length=4,
border_mode='valid',
activation='relu'))
model.add(MaxPooling1D(pool_length=2))
# dense layers
model.add(Flatten())
model.add(Dense(256))
model.add(Dropout(0.25))
model.add(Activation('relu'))
# output layer
model.add(Dense(len(class_id_index)))
model.add(Activation('softmax'))
Lalu saya mengkompilasinya seperti ini menggunakan categorical_crossentropy
fungsi loss:
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
atau
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
Secara intuitif masuk akal mengapa saya ingin menggunakan lintas-entropi kategoris, saya tidak mengerti mengapa saya mendapatkan hasil yang baik dengan biner, dan hasil yang buruk dengan kategorikal.
machine-learning
keras
neural-network
deep-learning
conv-neural-network
Daniel Messias
sumber
sumber
categorical_crossentropy
. Label juga perlu dikonversi ke dalam format kategorikal. Lihatto_categorical
untuk melakukan ini. Juga lihat definisi crossentropies kategorikal dan biner di sini .categorical_crossentropy
. Jika Anda memiliki dua kelas, mereka akan direpresentasikan sebagai0, 1
dalam label biner dan10, 01
dalam format label kategorikal.Dense(1, activation='softmax')
untuk klasifikasi biner adalah salah. Ingat output softmax adalah distribusi probabilitas yang berjumlah satu. Jika Anda hanya ingin memiliki satu neuron output dengan klasifikasi biner, gunakan sigmoid dengan entropi silang biner.Jawaban:
Alasan untuk perbedaan kinerja yang jelas antara entropi kategorikal & biner ini adalah apa yang telah dilaporkan pengguna xtof54 dalam jawabannya di bawah ini , yaitu:
Saya ingin menguraikan lebih lanjut tentang ini, menunjukkan masalah mendasar yang sebenarnya, menjelaskannya, dan menawarkan obat.
Perilaku ini bukan bug; alasan yang mendasari adalah masalah yang agak halus & tidak berdokumen tentang bagaimana Keras benar-benar menebak keakuratan mana yang akan digunakan, tergantung pada fungsi kerugian yang telah Anda pilih, ketika Anda memasukkannya
metrics=['accuracy']
dalam kompilasi model Anda. Dengan kata lain, saat opsi kompilasi pertama Andavalid, yang kedua:
tidak akan menghasilkan apa yang Anda harapkan, tetapi alasannya bukan penggunaan entropi silang biner (yang, pada prinsipnya, merupakan fungsi kerugian yang benar-benar valid).
Mengapa demikian? Jika Anda memeriksa kode sumber metrik , Keras tidak mendefinisikan satu metrik akurasi, tetapi beberapa yang berbeda, di antaranya
binary_accuracy
dancategorical_accuracy
. Apa yang terjadi di bawah tenda adalah bahwa, karena Anda telah memilih entropi silang biner sebagai fungsi kerugian Anda dan belum menentukan metrik akurasi tertentu, Keras (salah ...) menyimpulkan bahwa Anda tertarik padabinary_accuracy
, dan inilah yang dikembalikan - padahal sebenarnya Anda tertarik dengancategorical_accuracy
.Mari kita verifikasi bahwa inilah masalahnya, menggunakan contoh MNIST CNN di Keras, dengan modifikasi berikut:
Untuk memperbaiki hal ini, yaitu menggunakan entropi memang biner lintas sebagai fungsi kerugian Anda (seperti yang saya katakan, tidak ada yang salah dengan ini, setidaknya pada prinsipnya) sementara masih mendapatkan kategoris akurasi yang diperlukan oleh masalah di tangan, Anda harus meminta secara eksplisit untuk
categorical_accuracy
di kompilasi model sebagai berikut:Dalam contoh MNIST, setelah pelatihan, penilaian, dan prediksi set tes seperti yang saya tunjukkan di atas, kedua metrik sekarang sama, seperti seharusnya:
Pengaturan sistem:
UPDATE : Setelah posting saya, saya menemukan bahwa masalah ini sudah diidentifikasi dalam jawaban ini .
sumber
loss='categorical_crossentropy', metrics=['categorical_accuracy']
klasifikasi multi-kelas? Ini akan menjadi intuisi sayaItu semua tergantung pada jenis masalah klasifikasi yang Anda hadapi. Ada tiga kategori utama
Dalam kasus pertama, cross-entropy biner harus digunakan dan target harus dikodekan sebagai vektor satu-panas.
Dalam kasus kedua, lintas-entropi kategoris harus digunakan dan target harus dikodekan sebagai vektor satu-panas.
Dalam kasus terakhir, cross-entropy biner harus digunakan dan target harus dikodekan sebagai vektor satu-panas. Setiap neuron output (atau unit) dianggap sebagai variabel biner acak yang terpisah, dan kehilangan untuk seluruh vektor output adalah produk dari hilangnya variabel biner tunggal. Oleh karena itu itu adalah produk dari cross-entropy biner untuk setiap unit output tunggal.
Entropi silang biner didefinisikan sebagai
dan lintas-entropi kategoris didefinisikan sebagai
di mana
c
indeks melebihi jumlah kelassumber
c
indeksnya berlebihan dalam rumus cross-entropy biner, tidak perlu ada di sana (karena hanya ada 2 kelas dan probabilitas masing-masing kelas tertanamy(x)
. Jika tidak, rumus-rumus itu harus benar, tetapi melihat mereka tidak kerugian, mereka adalah likelihood Jika Anda ingin kehilangan Anda harus mengambil.log
ini.Saya menemukan masalah "terbalik" - Saya mendapatkan hasil yang baik denganategical_crossentropy (dengan 2 kelas) dan buruk dengan binary_crossentropy. Tampaknya masalah itu dengan fungsi aktivasi yang salah. Pengaturan yang benar adalah:
binary_crossentropy
: aktivasi sigmoid, target skalarcategorical_crossentropy
: aktivasi softmax, target enkode satu-panassumber
Ini kasus yang sangat menarik. Sebenarnya dalam pengaturan Anda, pernyataan berikut ini benar:
Ini berarti bahwa hingga faktor penggandaan konstan, kerugian Anda setara. Perilaku aneh yang Anda amati selama fase pelatihan mungkin menjadi contoh dari fenomena berikut:
adam
- tingkat pembelajaran memiliki nilai yang jauh lebih kecil daripada yang ada di awal pelatihan (itu karena sifat pengoptimal ini). Itu membuat pelatihan lebih lambat dan mencegah jaringan Anda dari mis. Meninggalkan minimum lokal yang buruk menjadi kurang mungkin.Itu sebabnya faktor konstan ini dapat membantu jika terjadi
binary_crossentropy
. Setelah banyak zaman - nilai laju pembelajaran lebih besar daripada dalamcategorical_crossentropy
kasus. Saya biasanya memulai kembali pelatihan (dan fase pembelajaran) beberapa kali ketika saya memperhatikan perilaku tersebut atau / dan menyesuaikan bobot kelas menggunakan pola berikut:Hal ini membuat kerugian dari kelas yang kurang sering menyeimbangkan pengaruh kerugian kelas yang dominan pada awal pelatihan dan di bagian selanjutnya dari proses optimisasi.
EDIT:
Sebenarnya - saya memeriksa itu meskipun dalam kasus matematika:
harus memegang - dalam kasus
keras
itu tidak benar, karenakeras
secara otomatis menormalkan semua output untuk jumlah hingga1
. Inilah alasan sebenarnya di balik perilaku aneh ini karena dalam kasus multiklasifikasi, normalisasi seperti itu membahayakan pelatihan.sumber
Setelah mengomentari @Marcin jawaban, saya lebih hati-hati memeriksa salah satu kode siswa saya di mana saya menemukan perilaku aneh yang sama, bahkan setelah hanya 2 zaman! (Jadi penjelasan @ Marcin sangat tidak mungkin dalam kasus saya).
Dan saya menemukan bahwa jawabannya sebenarnya sangat sederhana: akurasi yang dihitung dengan metode Keras
evaluate
hanya salah ketika menggunakan binary_crossentropy dengan lebih dari 2 label. Anda dapat memeriksa sendiri dengan menghitung ulang keakuratannya (panggilan pertama metode Keras "memprediksi" dan kemudian menghitung jumlah jawaban yang benar yang dikembalikan oleh prediksi): Anda mendapatkan keakuratan yang sebenarnya, yang jauh lebih rendah daripada yang "dinilai" Keras.sumber
contoh sederhana di bawah pengaturan multi-kelas untuk menggambarkan
misalkan Anda memiliki 4 kelas (satu kode dikodekan) dan di bawah ini hanya satu prediksi
true_label = [0,1,0,0] predict_label = [0,0,1,0]
saat menggunakan kategorical_crossentropy, akurasinya hanya 0, itu hanya peduli jika Anda mendapatkan kelas yang bersangkutan dengan benar.
namun ketika menggunakan binary_crossentropy, akurasi dihitung untuk semua kelas, itu akan menjadi 50% untuk prediksi ini. dan hasil akhir akan menjadi rata-rata dari akurasi individu untuk kedua kasus.
dianjurkan untuk menggunakan masalah kategorical_crossentropy untuk multi-kelas (kelas saling eksklusif) tetapi binary_crossentropy untuk masalah multi-label.
sumber
Karena ini adalah masalah multi-kelas, Anda harus menggunakan kategorical_crossentropy, entropi lintas biner akan menghasilkan hasil palsu, kemungkinan besar hanya akan mengevaluasi dua kelas pertama saja.
50% untuk masalah multi-kelas bisa sangat baik, tergantung pada jumlah kelas. Jika Anda memiliki n kelas, maka 100 / n adalah kinerja minimum yang dapat Anda peroleh dengan menghasilkan kelas acak.
sumber
saat menggunakan
categorical_crossentropy
kerugian, target Anda harus dalam format kategorikal (misalnya jika Anda memiliki 10 kelas, target untuk setiap sampel harus berupa vektor 10 dimensi yang semuanya nol kecuali angka 1 pada indeks yang sesuai dengan kelas Sampel).sumber
Lihatlah persamaan Anda dapat menemukan bahwa entropi lintas biner tidak hanya menghukum label tersebut = 1, prediksi = 0, tetapi juga label = 0, prediksi = 1.
Namun lintas entropi kategoris hanya menghukum label tersebut = 1 tetapi diprediksi = 1. Itulah sebabnya kami membuat asumsi bahwa hanya ada SATU label positif.
sumber
Anda melewati array target bentuk (x-redup, y-redup) saat menggunakan sebagai kerugian
categorical_crossentropy
.categorical_crossentropy
mengharapkan target berupa matriks biner (1s dan 0s) dari bentuk (sampel, kelas). Jika target Anda adalah kelas integer, Anda dapat mengonversinya ke format yang diharapkan melalui:Atau, Anda dapat menggunakan fungsi kerugian
sparse_categorical_crossentropy
sebagai gantinya, yang memang mengharapkan target bilangan bulat.sumber
Binary_crossentropy (y_target, y_predict) tidak perlu diterapkan dalam masalah klasifikasi biner. .
Dalam kode sumber binary_crossentropy () ,
nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output)
fungsi TensorFlow sebenarnya digunakan. Dan, dalam dokumentasi , dikatakan bahwa:sumber