1

TensorFlow를 사용하여 다중 레이블 분류를 구현하려고합니다 (즉, 각 출력 패턴에 많은 활성 단위가있을 수 있음). 이 문제는 클래스의 불균형을 낳습니다 (라벨 분포에있는 것보다 훨씬 많은 0으로 인해 라벨 패턴이 매우 희박합니다).Tensorflow와 Sigmoid 교차 엔트로피 손실의 차이

문제를 해결하는 가장 좋은 방법은 tf.nn.weighted_cross_entropy_with_logits 기능을 사용하는 것입니다. 그러나, 나는이 런타임 오류가 발생합니다 :

ValueError: Tensor conversion requested dtype uint8 for Tensor with dtype float32 

내가 여기에 어떤 문제가 있는지 이해할 수 없습니다. 이 문제를 해결하는 방법에 대한

positive_class_weight = 10 
loss = tf.nn.weighted_cross_entropy_with_logits(targets=labels, logits=logits, pos_weight=positive_class_weight) 

어떤 힌트 : 손실 함수에 입력, 나는 상수는이다, 라벨 텐서의 logits 텐서, 그리고 긍정적 인 클래스 무게를 통과? 방금 tf.losses.sigmoid_cross_entropy 손실 함수에 동일한 레이블과 로그 텐서를 전달하면 모든 것이 잘 작동합니다 (Tensorflow가 제대로 실행되지만 이후 훈련 예측은 항상 0 임).

관련 문제 here을 참조하십시오. tf.losses.sigmoid_cross_entropytf.nn.weighted_cross_entropy_with_logits 간의 유일한 유의 한 차이가 반환 텐서 형상이므로

답변

1

에러는 손실 함수 이후에 발생되기 쉽다.

logits = tf.linspace(-3., 5., 10) 
labels = tf.fill([10,], 1.) 

positive_class_weight = 10 
weighted_loss = tf.nn.weighted_cross_entropy_with_logits(targets=labels, logits=logits, pos_weight=positive_class_weight) 
print(weighted_loss.shape) 

sigmoid_loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=labels, logits=logits) 
print(sigmoid_loss.shape) 

텐서 logitslabels 종류의 인공하고 모두 모양 (10,) 있습니다

이 예에서 살펴 보자. 그러나 weighted_losssigmoid_loss이 다른 것이 중요합니다. 여기에서의 출력이다 :

(10,) 
() 

이 때문에 tf.losses.sigmoid_cross_entropy 수행 환원 (기본 합). 그래서 그것을 복제하기 위해서는 가중 손실을 tf.reduce_sum(...)으로 감싸 야합니다.

그래도 도움이되지 않으면 labels 텐서 형식이 float32인지 확인하십시오. 이 버그가 수 있도록하는 것은 매우 쉽습니다, 예를 들어, 다음과 같은 선언은 작동하지 않습니다

labels = tf.fill([10,], 1) # the type is not float! 

당신은 this question을 읽어도 관심이있을 수 있습니다.

+0

대단히 고맙습니다. 이로 인해 문제가 해결되었습니다. 나는 레이블을 명시 적으로'float32'로 캐스팅하고'tf.reduce_sum (...) '을 사용하여 손실 출력을 줄여야했습니다. – Alberto

관련 문제