Hàm điều chỉnh độ căng cho dữ liệu mất cân bằng


12

Tôi có một vấn đề phân loại với dữ liệu rất mất cân bằng. Tôi đã đọc rằng hơn và dưới mẫu cũng như thay đổi chi phí cho đầu ra phân loại không đúng mức sẽ dẫn đến phù hợp tốt hơn. Trước khi điều này được thực hiện, tenorflow sẽ phân loại từng đầu vào là nhóm đa số (và đạt được độ chính xác hơn 90%, vô nghĩa như vậy).

Tôi đã nhận thấy rằng nhật ký tỷ lệ nghịch của mỗi nhóm đã tạo ra hệ số nhân tốt nhất mà tôi đã thử. Có một thao tác tiêu chuẩn hơn cho chức năng chi phí? Điều này có được thực hiện đúng không?

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)

Các bạn có bất kỳ tài liệu tham khảo khoa học cho cách bạn lý tưởng chọn trọng số cho chức năng mất? Không phải tôi không tin bạn, nhưng tôi nghĩ bạn rất lấy cảm hứng từ người khác?
Gerhard Hagerer

Và như davidparks21 đã hỏi, kết quả của phương pháp của bạn sẽ rất thú vị :).
Gerhard Hagerer

Câu trả lời:


4

Đây có vẻ là một giải pháp tốt cho chức năng mất. Gần đây tôi đã thành công với một cách tiếp cận tương tự, nhưng tôi nghĩ rằng bạn muốn sắp xếp lại nơi bạn nhân lên class_weight.

Suy nghĩ về nó một cách logic, class_weightsẽ là một đầu ra không đổi, do đó, nó sẽ được mang theo và áp dụng cho gradient theo cùng cách nó được áp dụng cho hàm chi phí. Dù vậy vẫn có một vấn đề.

Cách bạn có nó, class_weightsẽ ảnh hưởng đến giá trị dự đoán. Nhưng bạn muốn nó ảnh hưởng đến quy mô của gradient. Nếu tôi không sai tôi nghĩ bạn muốn đảo ngược thứ tự hoạt động:

# 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)

Tôi rất muốn biết làm thế nào điều này thực hiện so với việc đơn giản là vượt quá lớp học được trình bày, mà điển hình hơn. Vì vậy, nếu bạn đạt được một số cái nhìn sâu sắc có bài viết về nó! :)

Thật thú vị, tôi đã sử dụng thành công một kỹ thuật rất giống nhau trong một miền vấn đề khác chỉ gần đây (điều này đưa tôi đến bài đăng này):

Học đa tác vụ, tìm một hàm mất "bỏ qua" một số mẫu nhất định


2

Thanh toán tf.nn.weighted_cross_entropy_with_logits():

Tính toán một entropy chéo có trọng số.

Điều này giống như sigmoid_cross_entropy_with_logits () ngoại trừ pos_ weight, cho phép người ta đánh đổi sự thu hồi và độ chính xác bằng cách tăng hoặc giảm chi phí của một lỗi dương so với lỗi âm.

Điều này sẽ cho phép bạn làm những gì bạn muốn.


0

Tôi có 2 cách thực hiện khác nhau:

  1. với softmax 'thông thường' với các bản ghi: tf.nn.softmax_cross_entropy_with_logits

Trong đó class_ weight là một trình giữ chỗ tôi điền vào lặp đi lặp lại hàng loạt.

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. với tf.nn.softmax_cross_entropy_with_logits

Nơi tôi sử dụng hàm tenorflow đã triển khai nhưng tôi cần tính toán trọng số cho lô. Các tài liệu hơi khó hiểu về nó. Có 2 cách để làm điều đó với tf.gather hoặc như thế này:

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)

ở đây có một cuộc thảo luận tốt đẹp về nó

Và cuối cùng, vì tôi không muốn kết hôn với bất kỳ điều khoản nào, tôi đã thêm một tf.case và tôi chuyển qua thời gian đào tạo chiến lược tôi muốn sử dụng.

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.