Nhật ký, softmax và softmax_cross_entropy_with_logits là gì?


350

Tôi đã trải qua các tài liệu API tenorflow ở đây . Trong tài liệu tenorflow, họ đã sử dụng một từ khóa được gọi là logits. Nó là gì? Trong rất nhiều phương thức trong tài liệu API, nó được viết như

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

Nếu những gì được viết là logitschỉ Tensors, tại sao giữ một tên khác như thế logitsnào?

Một điều nữa là có hai phương pháp tôi không thể phân biệt được. Họ đã

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

Sự khác biệt giữa chúng là gì? Các tài liệu không rõ ràng với tôi. Tôi biết những gì tf.nn.softmaxkhông. Nhưng không phải cái khác. Một ví dụ sẽ thực sự hữu ích.

Câu trả lời:


426

Các bản ghi đơn giản có nghĩa là hàm hoạt động trên đầu ra không được tính của các lớp trước đó và thang đo tương đối để hiểu các đơn vị là tuyến tính. Cụ thể, điều đó có nghĩa là tổng các đầu vào có thể không bằng 1, rằng các giá trị không phải là xác suất (bạn có thể có đầu vào là 5).

tf.nn.softmaxchỉ tạo ra kết quả của việc áp dụng hàm softmax cho một tenxơ đầu vào. Softmax "squishes" các đầu vào để sum(input) = 1: đó là một cách bình thường hóa. Hình dạng đầu ra của softmax giống như đầu vào: nó chỉ bình thường hóa các giá trị. Các đầu ra của softmax có thể được hiểu là xác suất.

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

Ngược lại, tf.nn.softmax_cross_entropy_with_logitstính toán entropy chéo của kết quả sau khi áp dụng hàm softmax (nhưng nó thực hiện tất cả cùng nhau theo một cách cẩn thận hơn về mặt toán học). Nó tương tự như kết quả của:

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

Entropy chéo là một số liệu tóm tắt: nó tính tổng các yếu tố. Đầu ra của tf.nn.softmax_cross_entropy_with_logitsmột [2,5]tenxơ hình dạng có hình dạng [2,1](kích thước đầu tiên được coi là lô).

Nếu bạn muốn thực hiện tối ưu hóa để giảm thiểu entropy chéo bạn đang mềm mại sau lớp cuối cùng của mình, bạn nên sử dụng tf.nn.softmax_cross_entropy_with_logitsthay vì tự làm, bởi vì nó bao gồm các trường hợp góc không ổn định về mặt số theo cách toán học. Nếu không, cuối cùng bạn sẽ hack nó bằng cách thêm ít epsilon ở đây và đó.

Đã chỉnh sửa 2016/02/07: Nếu bạn có nhãn một lớp, trong đó một đối tượng chỉ có thể thuộc về một lớp, bây giờ bạn có thể cân nhắc sử dụng tf.nn.sparse_softmax_cross_entropy_with_logitsđể bạn không phải chuyển đổi nhãn của mình thành một mảng dày đặc. Chức năng này đã được thêm vào sau khi phát hành 0.6.0.


1
Về softmax_cross_entropy_with_logits, tôi không biết liệu tôi có sử dụng đúng không. Kết quả là không ổn định trong mã của tôi. Cùng một mã chạy hai lần, tổng độ chính xác thay đổi từ 0,6 đến 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). Nhưng khi tôi sử dụng một cách khác, 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))kết quả ổn định và tốt hơn.
Rida

15
Bạn đang tăng gấp đôi trong dòng đầu tiên của bạn. softmax_cross_entropy_with_logits mong đợi các bản ghi không được tính toán, không phải là đầu ra của tf.nn.softmax. Bạn chỉ muốn tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W, b))trong trường hợp của bạn.
DGA

7
@dga Tôi nghĩ rằng bạn có một lỗi đánh máy trong mã của bạn, các bnhu cầu phải nằm ngoài khung,tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W), b)
jrieke

1
"thang đo tương đối để hiểu các đơn vị là gì". một phần của câu đầu tiên của bạn có nghĩa là gì?
Charlie Parker

5
Được nâng cấp - nhưng câu trả lời của bạn hơi không chính xác khi bạn nói rằng "[t] anh ấy hình dạng đầu ra của softmax giống như đầu vào - nó chỉ bình thường hóa các giá trị". Softmax không chỉ "ép" các giá trị sao cho tổng của chúng bằng 1. Nó cũng phân phối lại chúng, và đó có thể là lý do chính tại sao nó được sử dụng. Xem stackoverflow.com/questions/17187507/ khăn , đặc biệt là câu trả lời của Piotr Czapla.
Paolo Perrotta

282

Phiên bản ngắn:

Giả sử bạn có hai thang đo, trong đó y_hatcó các điểm được tính toán cho mỗi lớp (ví dụ: từ y = W * x + b) và y_truechứa các nhãn thực được mã hóa một lần nóng.

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

Nếu bạn giải thích các điểm trong y_hatkhi xác suất log unnormalized, sau đó họ logits .

Ngoài ra, tổng tổn thất entropy chéo được tính theo cách này:

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

về cơ bản là tương đương với tổng tổn thất entropy chéo được tính với hàm softmax_cross_entropy_with_logits():

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

Phiên bản dài:

Trong lớp đầu ra của mạng thần kinh của bạn, bạn có thể sẽ tính toán một mảng chứa điểm số lớp cho từng trường hợp đào tạo của bạn, chẳng hạn như từ một tính toán y_hat = W*x + b. Để làm ví dụ, bên dưới tôi đã tạo một y_hatmảng 2 x 3, trong đó các hàng tương ứng với các thể hiện đào tạo và các cột tương ứng với các lớp. Vì vậy, ở đây có 2 trường hợp đào tạo và 3 lớp.

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]])

Lưu ý rằng các giá trị không được chuẩn hóa (nghĩa là các hàng không thêm tối đa 1). Để bình thường hóa họ, chúng ta có thể áp dụng hàm softmax, mà giải thích đầu vào như xác suất unnormalized log (aka logits ) và đầu ra bình thường hóa tuyến tính xác suất.

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]])

Điều quan trọng là phải hiểu đầy đủ những gì đầu ra softmax đang nói. Dưới đây tôi đã hiển thị một bảng thể hiện rõ hơn đầu ra ở trên. Có thể thấy rằng, ví dụ, xác suất đào tạo ví dụ 1 là "Lớp 2" là 0,619. Xác suất lớp cho mỗi trường hợp đào tạo được chuẩn hóa, do đó tổng của mỗi hàng là 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

Vì vậy, bây giờ chúng ta có xác suất lớp cho từng trường hợp đào tạo, trong đó chúng ta có thể lấy argmax () của mỗi hàng để tạo phân loại cuối cùng. Từ trên, chúng ta có thể tạo ra trường hợp đào tạo 1 thuộc về "Lớp 2" và trường hợp đào tạo 2 thuộc về "Lớp 1".

Những phân loại này có đúng không? Chúng ta cần phải đo lường các nhãn thực sự từ tập huấn luyện. Bạn sẽ cần một y_truemảng được mã hóa một nóng , trong đó một lần nữa các hàng là các thể hiện đào tạo và các cột là các lớp. Dưới đây tôi đã tạo một ví dụ y_truemột mảng nóng trong đó nhãn thực sự cho trường hợp đào tạo 1 là "Lớp 2" và nhãn thực sự cho trường hợp đào tạo 2 là "Lớp 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.]])

Là phân phối xác suất y_hat_softmaxgần với phân phối xác suất trong y_true? Chúng ta có thể sử dụng tổn thất entropy chéo để đo lỗi.

Công thức cho mất entropy chéo

Chúng ta có thể tính toán tổn thất entropy chéo trên cơ sở hàng khôn ngoan và xem kết quả. Dưới đây chúng ta có thể thấy rằng trường hợp đào tạo 1 có tổn thất 0.479, trong khi trường hợp đào tạo 2 có tổn thất cao hơn 1.200. Kết quả này có ý nghĩa bởi vì trong ví dụ của chúng tôi ở trên, y_hat_softmaxcho thấy xác suất cao nhất của trường hợp đào tạo 1 là "Lớp 2", phù hợp với trường hợp đào tạo 1 trong y_true; tuy nhiên, dự đoán cho trường hợp đào tạo 2 cho thấy xác suất cao nhất đối với "Lớp 1", không phù hợp với lớp "Lớp 3" thực sự.

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])

Những gì chúng tôi thực sự muốn là tổng thiệt hại trên tất cả các trường hợp đào tạo. Vì vậy, chúng ta có thể tính toán:

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

Sử dụng softmax_cross_entropy_with_logits ()

Thay vào đó, chúng ta có thể tính tổng tổn thất entropy chéo bằng cách sử dụng tf.nn.softmax_cross_entropy_with_logits()hàm, như được hiển thị bên dưới.

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

Lưu ý rằng total_loss_1total_loss_2tạo ra kết quả cơ bản tương đương với một số khác biệt nhỏ trong các chữ số cuối cùng. Tuy nhiên, bạn cũng có thể sử dụng cách tiếp cận thứ hai: cần ít hơn một dòng mã và tích lũy ít lỗi số hơn vì softmax được thực hiện cho bạn bên trong softmax_cross_entropy_with_logits().


Tôi xác nhận tất cả những điều trên. Mã đơn giản: 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)trả về gần bằng 0 ở mọi nơi
Sami A. Haija

51

tf.nn.softmaxtính toán lan truyền về phía trước thông qua một lớp softmax. Bạn sử dụng nó trong quá trình đánh giá mô hình khi bạn tính toán xác suất mà mô hình đưa ra.

tf.nn.softmax_cross_entropy_with_logitstính toán chi phí cho một lớp softmax. Nó chỉ được sử dụng trong quá trình đào tạo .

Các bản ghi là xác suất nhật ký không chuẩn hóa xuất ra mô hình (đầu ra giá trị trước khi chuẩn hóa softmax được áp dụng cho chúng).


2
Tôi hiểu rồi. Tại sao không gọi hàm, tf.nn.softmax_cross_entropy_sans_n normalization?
auro

8
@auro vì nó bình thường hóa các giá trị (bên trong) trong quá trình tính toán entropy chéo. Điểm quan trọng tf.nn.softmax_cross_entropy_with_logitslà đánh giá mức độ mô hình lệch khỏi nhãn vàng, không cung cấp đầu ra chuẩn hóa.
erickrf

1
Trong trường hợp sử dụng tf.nn. một.
SerialDev

2
@SerialDev, không thể có xác suất từ ​​đó tf.nn.sparse_softmax_cross_entropy_with_logits. Để có được xác suất sử dụng tf.nn.softmax.
Nandeesh

4

Câu trả lời trên có đủ mô tả cho câu hỏi được hỏi.

Thêm vào đó, Tensorflow đã tối ưu hóa hoạt động áp dụng chức năng kích hoạt sau đó tính toán chi phí bằng cách sử dụng kích hoạt của chính nó theo sau là các hàm chi phí. Do đó, nó là một thực hành tốt để sử dụng: tf.nn.softmax_cross_entropy()hơntf.nn.softmax(); tf.nn.cross_entropy()

Bạn có thể tìm thấy sự khác biệt nổi bật giữa chúng trong một mô hình sử dụng nhiều tài nguyên.


1
câu trả lời ở trên rõ ràng không đọc câu hỏi .. Tất cả họ đều nói những điều tương tự, được biết, nhưng đừng trả lời chính câu hỏi
Euler_Salter

@abhish Ý của bạn là, tf.nn.softmaxtiếp theo tf.losses.softmax_cross_entropy?
ankurrc

4

Những gì đã từng đi softmaxlà logit, đây là những gì J. Hinton lặp đi lặp lại trong các video coursera mọi lúc.


1

Câu trả lời tương thích Tensorflow 2.0 : Các giải thích dgastackoverflowuser2010rất chi tiết về Nhật ký và các chức năng liên quan.

Tất cả các hàm đó, khi được sử dụng Tensorflow 1.xsẽ hoạt động tốt, nhưng nếu bạn di chuyển mã từ 1.x (1.14, 1.15, etc)sang 2.x (2.0, 2.1, etc..), sử dụng các hàm đó sẽ dẫn đến lỗi.

Do đó, chỉ định các cuộc gọi tương thích 2.0 cho tất cả các chức năng, chúng tôi đã thảo luận ở trên, nếu chúng tôi di chuyển từ 1.x to 2.x, vì lợi ích của cộng đồng.

Hàm trong 1.x :

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

Các chức năng tương ứng khi được di chuyển từ 1.x sang 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

Để biết thêm thông tin về việc di chuyển từ 1.x đến 2.x, vui lòng tham khảo điều này Hướng dẫn di chuyển .


0

Một điều nữa mà tôi chắc chắn muốn làm nổi bật là logit chỉ là một đầu ra thô, nói chung là đầu ra của lớp cuối cùng. Đây có thể là một giá trị tiêu cực là tốt. Nếu chúng ta sử dụng nó như là để đánh giá "entropy chéo" như được đề cập dưới đây:

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

sau đó nó sẽ không hoạt động. Như nhật ký của -ve không được xác định. Vì vậy, sử dụng kích hoạt o softmax, sẽ khắc phục vấn đề này.

Đây là sự hiểu biết của tôi, xin vui lòng sửa cho tôi nếu tôi sai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.