불균형 데이터에 대한 Tensorflow 조정 비용 기능


12

불균형이 심한 데이터에 분류 문제가 있습니다. 오버 샘플링과 언더 샘플링은 물론 불충분 한 범주 형 출력에 대한 비용을 변경하면 더 적합한 결과를 얻을 수 있습니다. 이 작업을 수행하기 전에 tensorflow는 각 입력을 다수 그룹으로 분류합니다 (그리고 의미가없는 것처럼 90 % 이상의 정확도를 얻습니다).

각 그룹의 역률 로그가 내가 시도한 최고의 승수를 만들었 음을 알았습니다. 비용 함수에 대한 표준 조작이 더 있습니까? 이것이 올바르게 구현 되었습니까?

from collections import Counter
counts = Counter(category_train)
weightsArray =[]
for i in range(n_classes):
    weightsArray.append(math.log(category_train.shape[0]/max(counts[i],1))+1)

class_weight = tf.constant(weightsArray)
weighted_logits = tf.mul(pred, class_weight)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(weighted_logits, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

손실 함수의 가중치를 이상적으로 선택하는 방법에 대한 과학적 참조가 있습니까? 나는 당신을 믿지 않지만 당신이 다른 누군가로부터 매우 영감을 받았다고 생각합니까?
Gerhard Hagerer

davidparks21이 이미 요청했듯이 접근 결과는 매우 흥미로울 것입니다.
Gerhard Hagerer

답변:


4

이것은 손실 함수에 대한 좋은 해결책처럼 보입니다. 최근 비슷한 접근 방식으로 성공했지만을 곱한 위치를 재정렬하고 싶습니다 class_weight.

논리적으로 생각 class_weight하면 결과는 일정하므로 비용 함수에 적용되는 것과 동일한 방식으로 그라디언트에 적용되고 적용됩니다. 그래도 한 가지 문제가 있습니다.

당신이 그것을 가진 방법 class_weight은 예측 값에 영향을 미칩니다. 그러나 그라디언트의 스케일에 영향을 미치기를 원합니다. 내가 틀리지 않으면 작업 순서를 바꾸고 싶다고 생각합니다.

# Take the cost like normal
error = tf.nn.softmax_cross_entropy_with_logits(pred, y)

# Scale the cost by the class weights
scaled_error = tf.mul(error, class_weight)

# Reduce
cost = tf.reduce_mean(scaled_error)

저 대표 클래스를 단순히 오버 샘플링하는 것과 비교하여 이것이 어떻게 수행되는지 알고 싶습니다. 그래서 당신이 통찰력을 얻는다면 그것에 대한 게시물이 있습니다! :)

흥미롭게도 나는 최근에 다른 문제 영역에서 매우 유사한 기술을 성공적으로 사용했습니다 (이 게시물로 나를 데려갔습니다).

특정 샘플을 "무시"하는 손실 함수를 찾는 다중 작업 학습


2

체크 아웃 tf.nn.weighted_cross_entropy_with_logits():

가중 교차 엔트로피를 계산합니다.

이것은 pos_weight를 제외하고 sigmoid_cross_entropy_with_logits ()와 비슷합니다. 음수 오류에 비해 양의 오류 비용을 가중 또는 가중하여 가중치를 재 호출함으로써 리콜 및 정밀도를 절충 할 수 있습니다.

이것은 당신이 원하는 것을 할 수 있도록해야합니다.


0

두 가지 구현이 있습니다.

  1. 로짓과 함께 '일반적인'softmax 사용 : tf.nn.softmax_cross_entropy_with_logits

class_weight가 플레이스 홀더 인 경우 에버리 배치 반복을 작성합니다.

self.class_weight  = tf.placeholder(tf.float32, shape=self.batch_size,self._num_classes], name='class_weight')    
self._final_output = tf.matmul(self._states,self._weights["linear_layer"]) + self._biases["linear_layer"] 
self.scaled_logits = tf.multiply(self._final_output, self.class_weight)
self.softmax = tf.nn.softmax_cross_entropy_with_logits(logits=self.scaled_logits,labels= self._labels)
  1. tf.nn.softmax_cross_entropy_with_logits

구현 된 tensorflow 함수를 사용하지만 배치의 가중치를 계산해야합니다. 문서는 약간 혼란 스럽습니다. tf.gather 또는 이와 같이하는 두 가지 방법이 있습니다.

self.scaled_class_weights=tf.reduce_sum(tf.multiply(self._labels,self.class_weight),1)
self.softmax = tf.losses.softmax_cross_entropy(logits=self._final_output,
                                                   onehot_labels=self._labels,weights=self.scaled_class_weights)

여기 에 좋은 토론이 있습니다

그리고 마지막으로 구현과 결혼하고 싶지 않았기 때문에 나는 약간의 tf.case를 추가했으며 훈련 시간에 내가 사용하고 싶은 전략을 전달합니다.

self.sensitive_learning_strategy = tf.placeholder(tf.int32 , name='sensitive_learning_strategy')
self.softmax =tf.case([
            (tf.equal(self.sensitive_learning_strategy, 0), lambda: self.softmax_0),
            (tf.equal(self.sensitive_learning_strategy, 1), lambda: self.softmax_1),
            (tf.equal(self.sensitive_learning_strategy, 2), lambda: self.softmax_2)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.