2017-11-08 8 views
1

sparse_softmax_cross_entropy을 사용하는 현재 코드가 정상적으로 작동합니다. 내가 사용하려고하지만Tensorflow - tf.losses.hinge_loss를 사용하여 도형을 만들 수 없음 호환되지 않는 오류

loss_normal = (
    tf.reduce_mean(tf.losses 
        .sparse_softmax_cross_entropy(labels=labels, 
               logits=logits, 
               weights=class_weights)) 
    ) 

hinge_loss :

ValueError: Shapes (1024, 2) and (1024,) are incompatible 

오류가 losses_impl.py 파일에이 기능에서 유래 것으로 보인다 : 그것은 말하는 오류를보고

loss_normal = (
    tf.reduce_mean(tf.losses 
        .hinge_loss(labels=labels, 
           logits=logits, 
           weights=class_weights)) 
    ) 

:

with ops.name_scope(scope, "hinge_loss", (logits, labels)) as scope: 
    ... 
    logits.get_shape().assert_is_compatible_with(labels.get_shape()) 
    ... 
단지 logits 텐서의 1 열을 추출하기 위해 다음과 같이

나는 내 코드를 수정 :

loss_normal = (
    tf.reduce_mean(tf.losses 
        .hinge_loss(labels=labels, 
           logits=logits[:,1:], 
           weights=class_weights 
           )) 
    ) 

을하지만 여전히 비슷한 오류보고 :

ValueError: Shapes (1024, 1) and (1024,) are incompatible. 

하는 사람이 왜 내 코드가 작동을 지적 도와주세요 수를 sparse_softmax_cross_entropy 손실이 있지만 hinge_loss이 아님으로 괜찮습니까?

답변

1

텐서 labels은 모양이 [1024]이고 텐서 logits[1024, 2] 모양입니다. 이 tf.nn.sparse_softmax_cross_entropy_with_logits을 위해 잘 작동 :

  • labels: Tensor of shape [d_0, d_1, ..., d_{r-1}] (where r is rank of labels and result) and dtype int32 or int64. Each entry in labels must be an index in [0, num_classes). Other values will raise an exception when this op is run on CPU, and return NaN for corresponding loss and gradient rows on GPU.
  • logits: Unscaled log probabilities of shape [d_0, d_1, ..., d_{r-1}, num_classes] and dtype float32 or float64.

그러나 tf.hinge_loss 요구 사항이 다릅니다 :

  • labels: The ground truth output tensor. Its shape should match the shape of logits. The values of the tensor are expected to be 0.0 or 1.0.
  • logits: The logits, a float tensor.

두 가지 방법으로이 문제를 해결할 수 있습니다

  • 그냥 하나를 [1024, 1]에 라벨 모양을 변경하고 사용 너 같은 행 logits 행 - logits[:,1:] :

    labels = tf.reshape(labels, [-1, 1]) 
    hinge_loss = (
        tf.reduce_mean(tf.losses.hinge_loss(labels=labels, 
                 logits=logits[:,1:], 
                 weights=class_weights)) 
        ) 
    

    나는 같은 방법으로 class_weights을 재 형성해야한다고 생각합니다. 플랫 (1024,) 텐서를 만들 것입니다 tf.reduce_sum를 통해

  • 사용 배운 logits의 모든 기능을 :

    logits = tf.reduce_sum(logits, axis=1) 
    hinge_loss = (
        tf.reduce_mean(tf.losses.hinge_loss(labels=labels, 
                 logits=logits, 
                 weights=class_weights)) 
        ) 
    

    labels 또는 class_weights을 바꿀 필요하지 않은이 방법.

+0

감사합니다. Maxim. 나는 축 1을 따라 논리를 합산함으로써 두 번째 접근법을 이해할 수 있을지 확신하지 못한다. 나는 내일 두 접근법을 시도하고 업데이트를 제공 할 것이다. 감사. – Allen

0

이유는 Maxim의 대답에서 잘 설명되어 있습니다. 나는 당신이 다른 클래스에 가중치를 추가하는 것을 목표로한다는 가정에 기초한 대안적인 솔루션을 제공하려고합니다.

무게가 배치 크기와 같은 것으로 보입니다.난 당신이 다른 클래스에 서로 다른 가중치를 추가하는 것을 목표로 추측하고, "무게"belowing 비슷한 몇 가지 코드에 의해 얻어진다 하나

이 코드는 클래스 가중치를 변환하는 것입니다

은 각 샘플에 추가 할

class_weights = [0.4, 0.6] # The weights for each class 
weights = tf.reduce_sum(class_weights * tf.labels, axis = 1) 
각 샘플을 가중치로 간접적으로 가중함으로써 클래스에 가중치를 부여 할 수 있습니다. 예를 들어 레이블이 [0, 1] 인 샘플의 경우 계산 된 샘플의 가중치는 0 * 0.4 + 1 * 0.6 = 0.6이며 실제로는 클래스 가중치입니다.

하지만 tf를 사용할 때. loss.hinge_loss,이 변환을 할 필요가 없습니다. 가중치 인수는 "0 또는 동일한 레이블 등급이어야하며 라벨에 브로드 캐스팅 할 수 있어야합니다 (즉, 모든 차원은 1이거나 해당 손실 차원과 동일해야합니다)."

등급 1 (2 차원)의 클래스 가중치를 생성해야하며 차원 0은 1 또는 일괄 처리 크기입니다. 다음 프로그램은 제대로 작동 할 수 있습니다.

질문에 대한 평판이 부족하기 때문에 더 많은 정보를 얻을 수 없습니다. 위의 모든 대답은 다른 클래스에 가중치를 추가해야한다는 가정에 기반합니다. 그래서 내가 틀렸다면,이 대답을 삭제하라고 알려주세요 :).