Phiên bản ngắn:
Giả sử bạn có hai thang đo, trong đó y_hat
có các điểm được tính toán cho mỗi lớp (ví dụ: từ y = W * x + b) và y_true
chứ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_hat
khi 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_hat
mả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_true
mả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_true
mộ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_softmax
gầ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.
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_softmax
cho 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_1
và total_loss_2
tạ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()
.
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.