Apa itu log, softmax dan softmax_cross_entropy_with_logits?

351

Saya akan melalui dokumen API tensorflow di sini . Dalam dokumentasi tensorflow, mereka menggunakan kata kunci yang disebut logits. Apa itu? Dalam banyak metode dalam API API ditulis seperti

tf.nn.softmax(logits, name=None)

Jika yang tertulis logitshanya itu Tensors, mengapa mempertahankan nama yang berbeda logits?

Hal lain adalah ada dua metode yang tidak bisa saya bedakan. Mereka

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

Apa perbedaan di antara mereka? Dokumen tidak jelas bagi saya. Saya tahu apa yang harus tf.nn.softmaxdilakukan. Tapi tidak yang lain. Contoh akan sangat membantu.

Shubhashis
sumber

Jawaban:

427

Log hanya berarti bahwa fungsi beroperasi pada output unscaled dari lapisan sebelumnya dan bahwa skala relatif untuk memahami unit adalah linier. Ini berarti, khususnya, jumlah input mungkin tidak sama dengan 1, bahwa nilainya bukan probabilitas (Anda mungkin memiliki input 5).

tf.nn.softmaxmenghasilkan hanya hasil menerapkan fungsi softmax ke tensor input. Softmax "menekan" input sehingga sum(input) = 1: ini adalah cara normalisasi. Bentuk output dari softmax sama dengan input: itu hanya menormalkan nilai. Output dari softmax dapat diartikan sebagai probabilitas.

a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508  0.205666    0.25120102  0.37474789]]

Sebaliknya, tf.nn.softmax_cross_entropy_with_logitshitung entropi silang dari hasil setelah menerapkan fungsi softmax (tapi itu melakukannya bersama-sama dengan cara yang lebih cermat secara matematis). Ini mirip dengan hasil:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)

Entropi silang adalah metrik ringkasan: merangkum seluruh elemen. Output tf.nn.softmax_cross_entropy_with_logitspada [2,5]tensor bentuk adalah bentuk [2,1](dimensi pertama diperlakukan sebagai bets).

Jika Anda ingin melakukan optimasi untuk meminimalkan entropi silang DAN Anda melakukan softmax setelah lapisan terakhir, Anda harus menggunakan tf.nn.softmax_cross_entropy_with_logitsalih-alih melakukannya sendiri, karena mencakup kasus sudut yang tidak stabil secara matematis dengan cara yang benar secara matematis. Jika tidak, Anda akan meretasnya dengan menambahkan epsilons kecil di sana-sini.

Diedit 2016-02-07: Jika Anda memiliki label kelas tunggal, di mana objek hanya bisa menjadi milik satu kelas, Anda sekarang dapat mempertimbangkan untuk menggunakan tf.nn.sparse_softmax_cross_entropy_with_logitssehingga Anda tidak perlu mengubah label Anda menjadi array satu-panas yang padat. Fungsi ini ditambahkan setelah rilis 0.6.0.

dga
sumber
1
Tentang softmax_cross_entropy_with_logits, saya tidak tahu apakah saya menggunakannya dengan benar. Hasilnya tidak stabil di kode saya. Kode yang sama berjalan dua kali, akurasi total berubah dari 0,6 menjadi 0,8. cross_entropy = tf.nn.softmax_cross_entropy_with_logits(tf.nn.softmax(tf.add(tf.matmul(x,W),b)),y) cost=tf.reduce_mean(cross_entropy). Tetapi ketika saya menggunakan cara lain, pred=tf.nn.softmax(tf.add(tf.matmul(x,W),b)) cost =tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1))hasilnya stabil dan lebih baik.
Rida
15
Anda melakukan double-softmax di baris pertama Anda. softmax_cross_entropy_with_logits mengharapkan log yang tidak berskala, bukan output dari tf.nn.softmax. Anda hanya ingin tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W, b))dalam kasus Anda.
dga
7
@ Dga saya pikir Anda memiliki kesalahan ketik dalam kode Anda, bharus di luar braket,tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W), b)
jrieke
1
apa artinya "bahwa skala relatif untuk memahami unit adalah linier." bagian dari kalimat pertama Anda artinya?
Charlie Parker
5
Diperbaharui - tetapi jawaban Anda sedikit salah ketika Anda mengatakan bahwa "[t] bentuk output dari softmax sama dengan input - itu hanya menormalkan nilai". Softmax tidak hanya "menekan" nilai-nilai sehingga jumlah mereka sama dengan 1. Ini juga mendistribusikan ulang, dan itu mungkin alasan utama mengapa itu digunakan. Lihat stackoverflow.com/questions/17187507/… , terutama jawaban Piotr Czapla.
Paolo Perrotta
282

Versi pendek:

Misalkan Anda memiliki dua tensor, di mana y_hat berisi skor yang dihitung untuk setiap kelas (misalnya, dari y = W * x + b) dan y_trueberisi label benar yang disandikan satu-panas.

y_hat  = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded

Jika Anda menginterpretasikan skor dalam y_hat sebagai probabilitas log yang tidak dinormalkan , maka itu adalah log .

Selain itu, total kerugian lintas-entropi yang dihitung dengan cara ini:

y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

pada dasarnya setara dengan total kehilangan lintas-entropi yang dihitung dengan fungsi softmax_cross_entropy_with_logits() :

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

Versi panjang:

Di lapisan output dari jaringan saraf Anda, Anda mungkin akan menghitung array yang berisi skor kelas untuk setiap instance pelatihan Anda, seperti dari perhitungan y_hat = W*x + b. Sebagai contoh, di bawah ini saya telah membuat ay_hat array 2 x 3, di mana baris terkait dengan instance pelatihan dan kolom sesuai dengan kelas. Jadi di sini ada 2 contoh pelatihan dan 3 kelas.

import tensorflow as tf
import numpy as np

sess = tf.Session()

# Create example y_hat.
y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]]))
sess.run(y_hat)
# array([[ 0.5,  1.5,  0.1],
#        [ 2.2,  1.3,  1.7]])

Perhatikan bahwa nilai tidak dinormalisasi (yaitu baris tidak menambahkan hingga 1). Untuk menormalkannya, kita dapat menerapkan fungsi softmax, yang menginterpretasikan input sebagai probabilitas log yang tidak dinormalisasi (alias log dinormalisasi ) dan output probabilitas linear yang dinormalisasi.

y_hat_softmax = tf.nn.softmax(y_hat)
sess.run(y_hat_softmax)
# array([[ 0.227863  ,  0.61939586,  0.15274114],
#        [ 0.49674623,  0.20196195,  0.30129182]])

Sangat penting untuk memahami sepenuhnya apa yang dikatakan output softmax. Di bawah ini saya telah menunjukkan tabel yang lebih jelas mewakili output di atas. Dapat dilihat bahwa, misalnya, probabilitas pelatihan contoh 1 menjadi "Kelas 2" adalah 0,619. Probabilitas kelas untuk setiap instance pelatihan dinormalisasi, sehingga jumlah setiap baris adalah 1.0.

                      Pr(Class 1)  Pr(Class 2)  Pr(Class 3)
                    ,--------------------------------------
Training instance 1 | 0.227863   | 0.61939586 | 0.15274114
Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182

Jadi sekarang kita memiliki probabilitas kelas untuk setiap instance pelatihan, di mana kita dapat mengambil argmax () dari setiap baris untuk menghasilkan klasifikasi akhir. Dari atas, kami dapat membuat instance pelatihan 1 milik "Kelas 2" dan instance pelatihan 2 milik "Kelas 1".

Apakah klasifikasi ini benar? Kita perlu mengukur terhadap label yang sebenarnya dari set pelatihan. Anda akan membutuhkan y_truearray yang dikodekan satu-panas , di mana lagi baris adalah contoh pelatihan dan kolom adalah kelas. Di bawah ini saya telah membuat contoh y_truearray satu-panas di mana label sebenarnya untuk instance pelatihan 1 adalah "Kelas 2" dan label sebenarnya untuk instance pelatihan 2 adalah "Kelas 3".

y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]))
sess.run(y_true)
# array([[ 0.,  1.,  0.],
#        [ 0.,  0.,  1.]])

Apakah distribusi probabilitas y_hat_softmaxdekat dengan distribusi probabilitas y_true? Kita bisa menggunakan kehilangan lintas-entropi untuk mengukur kesalahan.

Formula untuk kehilangan lintas-entropi

Kita dapat menghitung kehilangan lintas-entropi berdasarkan baris-bijaksana dan melihat hasilnya. Di bawah ini kita dapat melihat bahwa instance pelatihan 1 memiliki kerugian sebesar 0,479, sedangkan instance pelatihan 2 memiliki kehilangan yang lebih tinggi sebesar 1,200. Hasil ini masuk akal karena dalam contoh kami di atas, y_hat_softmaxmenunjukkan bahwa contoh pelatihan 1 probabilitas tertinggi adalah untuk "Kelas 2", yang cocok dengan contoh pelatihan 1 di y_true; Namun, prediksi untuk instance pelatihan 2 menunjukkan probabilitas tertinggi untuk "Kelas 1", yang tidak cocok dengan kelas sebenarnya "Kelas 3".

loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])
sess.run(loss_per_instance_1)
# array([ 0.4790107 ,  1.19967598])

Apa yang benar-benar kita inginkan adalah kerugian total dari semua contoh pelatihan. Jadi kita dapat menghitung:

total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]))
sess.run(total_loss_1)
# 0.83934333897877944

Menggunakan softmax_cross_entropy_with_logits ()

Sebagai gantinya, kami dapat menghitung total kehilangan entropi silang menggunakan tf.nn.softmax_cross_entropy_with_logits()fungsi, seperti yang ditunjukkan di bawah ini.

loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)
sess.run(loss_per_instance_2)
# array([ 0.4790107 ,  1.19967598])

total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
sess.run(total_loss_2)
# 0.83934333897877922

Perhatikan itu total_loss_1dan total_loss_2hasilkan pada dasarnya hasil yang setara dengan beberapa perbedaan kecil dalam digit terakhir. Namun, Anda mungkin juga menggunakan pendekatan kedua: dibutuhkan satu baris kode kurang dan mengakumulasi lebih sedikit kesalahan numerik karena softmax dilakukan untuk Anda di dalamnya softmax_cross_entropy_with_logits().

stackoverflowuser2010
sumber
Saya mengkonfirmasi semua hal di atas. Kode sederhana: M = tf.random.uniform([100, 10], minval=-1.0, maxval=1.0); labels = tf.one_hot(tf.random.uniform([100], minval=0, maxval=10 , dtype='int32'), 10); tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=M) - tf.reduce_sum(-tf.nn.log_softmax(M)*tf.one_hot(labels, 10), -1)mengembalikan mendekati nol di mana
Sami A. Haija
51

tf.nn.softmaxmenghitung propagasi maju melalui lapisan softmax. Anda menggunakannya selama evaluasi model ketika Anda menghitung probabilitas bahwa output model.

tf.nn.softmax_cross_entropy_with_logitsmenghitung biaya untuk lapisan softmax. Ini hanya digunakan selama pelatihan .

Log adalah probabilitas log yang tidak dinormalkan mengeluarkan model (nilai-nilai yang dihasilkan sebelum normalisasi softmax diterapkan pada mereka).

Ian Goodfellow
sumber
2
Saya mengerti. Mengapa tidak memanggil fungsinya, tf.nn.softmax_cross_entropy_sans_normalization?
auro
8
@ auro karena menormalkan nilai-nilai (internal) selama perhitungan lintas-entropi. Maksudnya tf.nn.softmax_cross_entropy_with_logitsadalah untuk mengevaluasi seberapa banyak model menyimpang dari label emas, bukan untuk memberikan output yang dinormalisasi.
erickrf
1
Dalam kasus menggunakan tf.nn.sparse_softmax_cross_entropy_with_logits () menghitung biaya lapisan softmax yang jarang, dan dengan demikian hanya boleh digunakan selama pelatihan apa yang akan menjadi alternatif ketika menjalankan model terhadap data baru, apakah mungkin untuk mendapatkan probabilitas dari ini satu.
SerialDev
2
@SerialDev, itu tidak mungkin untuk mendapatkan probabilitas dari tf.nn.sparse_softmax_cross_entropy_with_logits. Untuk mendapatkan probabilitas gunakan tf.nn.softmax.
Nandeesh
4

Jawaban di atas memiliki deskripsi yang cukup untuk pertanyaan yang diajukan.

Menambah itu, Tensorflow telah mengoptimalkan operasi penerapan fungsi aktivasi kemudian menghitung biaya menggunakan aktivasi sendiri diikuti oleh fungsi biaya. Karenanya ini adalah praktik yang baik untuk digunakan: tf.nn.softmax_cross_entropy()selesaitf.nn.softmax(); tf.nn.cross_entropy()

Anda dapat menemukan perbedaan mencolok di antara mereka dalam model intensif sumber daya.

Abish
sumber
1
jawaban di atas jelas belum membaca pertanyaan .. Mereka semua mengatakan hal yang sama, yang diketahui, tetapi jangan menjawab pertanyaan itu sendiri
Euler_Salter
@abhish Apakah maksud Anda, tf.nn.softmaxdiikuti oleh tf.losses.softmax_cross_entropy?
ankurrc
4

Apa yang pernah terjadi softmaxadalah logit, ini adalah apa yang J. Hinton ulangi dalam video coursera sepanjang waktu.

prosti
sumber
1

Tensorflow 2.0 Kompatibel Jawaban : Penjelasan dari dgadanstackoverflowuser2010 sangat rinci tentang Log dan Fungsi terkait.

Semua fungsi itu, ketika digunakan Tensorflow 1.xakan berfungsi dengan baik, tetapi jika Anda memigrasi kode Anda dari 1.x (1.14, 1.15, etc)ke2.x (2.0, 2.1, etc..) , menggunakan fungsi-fungsi tersebut menghasilkan kesalahan.

Karenanya, menentukan 2.0 Panggilan Kompatibel untuk semua fungsi, kami bahas di atas, jika kami bermigrasi dari 1.x to 2.x, untuk kepentingan komunitas.

Fungsi dalam 1.x :

  1. tf.nn.softmax
  2. tf.nn.softmax_cross_entropy_with_logits
  3. tf.nn.sparse_softmax_cross_entropy_with_logits

Fungsi Masing-masing saat Dimigrasikan dari 1.x ke 2.x :

  1. tf.compat.v2.nn.softmax
  2. tf.compat.v2.nn.softmax_cross_entropy_with_logits
  3. tf.compat.v2.nn.sparse_softmax_cross_entropy_with_logits

Untuk informasi lebih lanjut tentang migrasi dari 1.x ke 2.x, silakan merujuk Panduan Migrasi ini .

Dukungan Tensorflow
sumber
0

Satu hal lagi yang saya ingin sorot sebagai logit hanyalah output mentah, umumnya output dari lapisan terakhir. Ini bisa menjadi nilai negatif juga. Jika kami menggunakannya untuk evaluasi "cross entropy" seperti yang disebutkan di bawah ini:

-tf.reduce_sum(y_true * tf.log(logits))

maka itu tidak akan berhasil. Sebagai log of -ve tidak didefinisikan. Jadi menggunakan aktivasi softmax, akan mengatasi masalah ini.

Ini adalah pemahaman saya, tolong perbaiki saya jika saya salah.

vipin bansal
sumber