나는 최근에 tf.nn.sparse_softmax_cross_entropy_with_logits 를 발견 했고 그 차이가 tf.nn.softmax_cross_entropy_with_logits 와 비교되는 것을 알 수 없습니다 .
y
를 사용할 때 훈련 벡터 가 원-핫 인코딩 되어야 한다는 유일한 차이점은 sparse_softmax_cross_entropy_with_logits
무엇입니까?
API를 읽으면서 .NET과 비교하여 다른 차이점을 찾을 수 없습니다 softmax_cross_entropy_with_logits
. 그런데 왜 추가 기능이 필요한가요?
원-핫 인코딩 된 학습 데이터 / 벡터와 함께 제공되는 경우 softmax_cross_entropy_with_logits
와 동일한 결과를 생성 하지 않아야 sparse_softmax_cross_entropy_with_logits
합니까?
답변
두 가지 다른 기능을 갖는 것은 동일한 결과를 생성하므로 편리합니다 .
차이점은 간단합니다.
- 의 경우
sparse_softmax_cross_entropy_with_logits
레이블의 모양은 [batch_size]이고 dtype은 int32 또는 int64 여야합니다. 각 레이블은 범위 내의 정수입니다[0, num_classes-1]
. - 의 경우
softmax_cross_entropy_with_logits
레이블은 [batch_size, num_classes] 및 dtype float32 또는 float64 모양이어야합니다.
에서 사용되는 라벨은 softmax_cross_entropy_with_logits
있습니다 핫 버전 에 사용 된 레이블 sparse_softmax_cross_entropy_with_logits
.
또 다른 작은 차이점은를 사용 sparse_softmax_cross_entropy_with_logits
하면 -1을 레이블로 제공 0
하여이 레이블에 손실 을 줄 수 있다는 것 입니다.
답변
TF 문서에서도 찾을 수있는 수락 된 답변에 두 가지를 추가하고 싶습니다.
먼저:
tf.nn.softmax_cross_entropy_with_logits
참고 : 클래스는 상호 배타적이지만 확률은 그럴 필요가 없습니다. 필요한 것은 레이블의 각 행이 유효한 확률 분포라는 것입니다. 그렇지 않은 경우 그래디언트 계산이 잘못됩니다.
둘째:
tf.nn.sparse_softmax_cross_entropy_with_logits
참고 :이 작업에서는 지정된 레이블의 확률이 배타적 인 것으로 간주됩니다. 즉, 소프트 클래스는 허용되지 않으며 레이블 벡터는 각 로짓 행 (각 미니 배치 항목)의 실제 클래스에 대한 단일 특정 인덱스를 제공해야합니다.
답변
두 함수 모두 동일한 결과를 계산 하고 sparse_softmax_cross_entropy_with_logits 는 원-핫 인코딩 으로 변환하는 대신 희소 레이블에서 직접 교차 엔트로피를 계산합니다 .
다음 프로그램을 실행하여이를 확인할 수 있습니다.
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
여기서 logits
길이 의 임의의 벡터를 만들고 dims
원-핫 인코딩 된 레이블을 생성합니다 (여기서 요소 pos
는 1이고 다른 요소 는 0).
그 후 소프트 맥스와 스파 스 소프트 맥스를 계산하고 출력을 비교합니다. 항상 동일한 출력을 생성하도록 몇 번 다시 실행 해보십시오.