Fungsi Penyesuaian Tensorflow untuk Data yang Tidak Seimbang


12

Saya memiliki masalah klasifikasi dengan data yang sangat tidak seimbang. Saya telah membaca bahwa over dan undersampling serta mengubah biaya untuk output kategoris yang kurang terwakili akan mengarah pada pemasangan yang lebih baik. Sebelum ini dilakukan, tensorflow akan mengategorikan setiap input sebagai kelompok mayoritas (dan mendapatkan akurasi lebih dari 90%, sama tidak berartinya).

Saya perhatikan bahwa log persentase terbalik dari setiap grup telah membuat pengganda terbaik yang saya coba. Apakah ada manipulasi yang lebih standar untuk fungsi biaya? Apakah ini diterapkan dengan benar?

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)

Apakah kalian punya referensi ilmiah tentang bagaimana Anda secara ideal memilih bobot untuk fungsi kerugian? Bukannya aku tidak percaya padamu, tapi kupikir kau sangat terinspirasi oleh orang lain?
Gerhard Hagerer

Dan seperti yang diminta davidparks21, hasil pendekatan Anda akan sangat menarik :).
Gerhard Hagerer

Jawaban:


4

Ini sepertinya solusi yang bagus untuk fungsi kerugian. Saya sudah sukses dengan pendekatan yang sama baru - baru ini, tetapi saya pikir Anda ingin memesan ulang tempat Anda berkembang biak di class_weight.

Memikirkannya secara logis, maka class_weightakan menjadi konstan wrt output, sehingga akan dibawa dan diterapkan pada gradien dengan cara yang sama itu diterapkan pada fungsi biaya. Namun ada satu masalah.

Cara Anda memilikinya, class_weightakan mempengaruhi nilai prediksi. Tetapi Anda ingin itu mempengaruhi skala gradien. Jika saya tidak salah, saya pikir Anda ingin membalik urutan operasi:

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

Saya akan sangat tertarik untuk mengetahui bagaimana kinerjanya dibandingkan dengan hanya terlalu banyak mengawasi kelas yang kurang terwakili, yang lebih khas. Jadi, jika Anda mendapatkan beberapa wawasan di sana, posting tentang itu! :)

Menariknya saya berhasil menggunakan teknik yang sangat mirip di domain masalah yang berbeda baru-baru ini (yang membawa saya ke posting ini):

Pembelajaran multi-tugas, menemukan fungsi kerugian yang "mengabaikan" sampel tertentu


2

Checkout tf.nn.weighted_cross_entropy_with_logits():

Menghitung entropi silang tertimbang.

Ini seperti sigmoid_cross_entropy_with_logits () kecuali pos_weight itu, memungkinkan seseorang untuk menukar ingatan dan presisi dengan menaikkan atau menurunkan bobot biaya kesalahan positif relatif terhadap kesalahan negatif.

Ini akan membuat Anda melakukan apa yang Anda inginkan.


0

Saya memiliki 2 implementasi yang berbeda:

  1. dengan softmax 'reguler' dengan log: tf.nn.softmax_cross_entropy_with_logits

Di mana class_weight adalah placeholder yang saya isi pada iterasi batch yang pernah ada.

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. dengan tf.nn.softmax_cross_entropy_with_logits

Di mana saya menggunakan fungsi tensorflow yang diimplementasikan tetapi saya harus menghitung bobot untuk bets. Dokumen agak membingungkan tentang hal itu. Ada 2 cara untuk melakukannya dengan tf.gather atau seperti ini:

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)

di sini ada diskusi yang bagus tentang itu

Dan akhirnya karena saya tidak ingin menikah dengan salah satu dari permen itu dengan baik, saya menambahkan sedikit. Saya dan saya meneruskan waktu pelatihan strategi yang ingin saya gunakan.

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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.