Apa perbedaan antara sparse_softmax_cross_entropy_with_logits dan softmax_cross_entropy_with_logits?

111

Saya baru-baru ini menemukan tf.nn.sparse_softmax_cross_entropy_with_logits dan saya tidak tahu apa perbedaannya dibandingkan dengan tf.nn.softmax_cross_entropy_with_logits .

Apakah satu-satunya perbedaan bahwa vektor pelatihan yharus dienkode dengan one-hot saat menggunakan sparse_softmax_cross_entropy_with_logits?

Membaca API, saya tidak dapat menemukan perbedaan lain apa pun dibandingkan softmax_cross_entropy_with_logits. Tapi mengapa kita membutuhkan fungsi ekstra?

Tidakkah seharusnya softmax_cross_entropy_with_logitsmenghasilkan hasil yang sama seperti sparse_softmax_cross_entropy_with_logits, jika dilengkapi dengan data pelatihan / vektor yang dienkode dengan one-hot?

daniel451
sumber
1
Saya tertarik untuk melihat perbandingan kinerja mereka jika keduanya dapat digunakan (misalnya dengan label gambar eksklusif); Saya berharap versi sparse lebih efisien, setidaknya dari segi memori.
Yibo Yang
1
Lihat juga pertanyaan ini , yang membahas semua fungsi cross-entropy di tensorflow (ternyata ada banyak sekali).
Maxim

Jawaban:

175

Memiliki dua fungsi yang berbeda sangatlah mudah , karena keduanya menghasilkan hasil yang sama.

Perbedaannya sederhana:

  • Sebab sparse_softmax_cross_entropy_with_logits, label harus memiliki bentuk [batch_size] dan dtype int32 atau int64. Setiap label adalah int dalam kisaran [0, num_classes-1].
  • Sebab softmax_cross_entropy_with_logits, label harus memiliki bentuk [batch_size, num_classes] dan dtype float32 atau float64.

Label yang digunakan softmax_cross_entropy_with_logitsadalah salah satu versi terbaru dari label yang digunakan sparse_softmax_cross_entropy_with_logits.

Perbedaan kecil lainnya adalah dengan sparse_softmax_cross_entropy_with_logits, Anda dapat memberi -1 sebagai label untuk kehilangan 0label ini.

Olivier Moindrot
sumber
15
Apakah -1 benar? Seperti dalam dokumentasinya: "Setiap entri di label harus berupa indeks dalam [0, num_classes). Nilai lain akan memunculkan pengecualian saat operasi ini dijalankan pada CPU, dan mengembalikan NaN untuk baris kerugian dan gradien yang sesuai pada GPU."
pengguna1761806
1
[0, num_classes) = [0, num_classes-1]
Karthik C
24

Saya hanya ingin menambahkan 2 hal pada jawaban yang diterima yang juga dapat Anda temukan di dokumentasi TF.

Pertama:

tf.nn.softmax_cross_entropy_with_logits

CATATAN: Meskipun kelas saling eksklusif, probabilitasnya tidak perlu. Semua yang diperlukan adalah setiap baris label adalah distribusi probabilitas yang valid. Jika tidak, perhitungan gradien akan salah.

Kedua:

tf.nn.sparse_softmax_cross_entropy_with_logits

CATATAN: Untuk operasi ini, probabilitas label yang diberikan dianggap eksklusif. Artinya, kelas lunak tidak diperbolehkan, dan vektor label harus memberikan indeks spesifik tunggal untuk kelas sebenarnya untuk setiap baris logit (setiap entri minibatch).

Tarik0
sumber
4
Apa yang harus kita gunakan jika kelas tidak saling eksklusif. Maksud saya, jika kita menggabungkan beberapa label kategori?
Hayro
Saya juga membaca ini. Jadi itu berarti kita menerapkan probabilitas kelas pada cross entropy daripada menganggapnya sebagai vektor onehot.
Shamane Siriwardhana
@Hayro - Apakah maksud Anda Anda tidak dapat melakukan satu hot encoding? Saya pikir Anda harus melihat model yang berbeda. Ini menyebutkan sesuatu seperti "akan lebih sesuai untuk membangun 4 pengklasifikasi regresi logistik biner" Untuk terlebih dahulu memastikan Anda dapat memisahkan kelas.
ashley
21

Kedua fungsi tersebut menghitung hasil yang sama dan sparse_softmax_cross_entropy_with_logits menghitung entropi silang secara langsung pada label renggang alih-alih mengonversinya dengan enkode one-hot .

Anda dapat memverifikasi ini dengan menjalankan program berikut:

import tensorflow as tf
from random import randint

dims = 8
pos  = randint(0, dims - 1)

logits = tf.random_uniform([dims], maxval=3, dtype=tf.float32)
labels = tf.one_hot(pos, dims)

res1 = tf.nn.softmax_cross_entropy_with_logits(       logits=logits, labels=labels)
res2 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=tf.constant(pos))

with tf.Session() as sess:
    a, b = sess.run([res1, res2])
    print a, b
    print a == b

Di sini saya membuat logitsvektor acak dengan panjang dimsdan menghasilkan label yang dikodekan satu panas (di mana elemen di posadalah 1 dan lainnya adalah 0).

Setelah itu saya menghitung softmax dan sparse softmax dan membandingkan hasilnya. Coba jalankan ulang beberapa kali untuk memastikan selalu menghasilkan keluaran yang sama

Salvador Dali
sumber